ラベル Glosbe の投稿を表示しています。 すべての投稿を表示
ラベル Glosbe の投稿を表示しています。 すべての投稿を表示

2017年7月31日月曜日

続・ソースコード中の単語からの略語/スペルミス検出に挑戦

ブログズミ: ソースコード中の単語からの略語/スペルミス検出に挑戦」で紹介した略語チェッカーを大幅に更新したので、続報です。
ついでなので、Glosbe でリクエスト制限にかかってしまった場合の対処方法も紹介しておきます。

変更点
usage: abbreviation.py [-h] [-v] [-g FILE] [-w FILE] [-e EXCLUDE]
                       [-a ABBREVIATION] [--glosbe] [--dejizo] [--cache]
                       [--load-cache NAME] [--cache-dir DIR]
                       [--disable-keywords] [-x {c++,c#,objc,diff}]
                       [--list-all] [--progress] [--safe-mode]
                       [--encoding ENCODING] [--extension EXTENSION]
                       [--ignore-noexists] [--relpath] [--word WORD] [-]
                       [FILE/DIR [FILE/DIR ...]]

positional arguments:
  FILE/DIR              source code file/dir

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  -g FILE, --gene FILE  exlude word
  -w FILE, --whitelist FILE
                        whitelist file
  -e EXCLUDE, --exclude EXCLUDE
                        exlude word
  -a ABBREVIATION, --abbreviation ABBREVIATION
                        abbreviation word
  --glosbe              use online translation service (glosbe)
  --dejizo              use online service (dejizo)
  --cache               online translation cache enable
  --load-cache NAME     load translation cache
  --cache-dir DIR       translation cache directory
  --disable-keywords    disable general and language keywords
  -x {c++,c#,objc,diff}, --language {c++,c#,objc,diff}
                        select language
  --list-all            list up all location
  --progress            print percent progress
  --safe-mode           api request limit safe mode(glosbe)
  --encoding ENCODING   set file encoding
  --extension EXTENSION
                        file extension matcher
  --ignore-noexists     ignore option file not exists
  --relpath             print relative path
  --word WORD           dircet check words
  -                     source code from stdin

diff ファイルに対応
便利になった機能の1つがこれだと思います。
diff ファイルから差分があったところだけをチェックするので、コードレビューのときに重宝します。
対応しているフォーマットは Unified format になります。

略語判定ロジックの大幅更新
「~の略語」だけでなく、「~の過去形」「~の複数形」なども検出して、辞書判定するように改善しました。主に、boost のヘッダーファイルをチェッカーに入力して、その結果を見ながら、期待に沿わないものに対応していった感じです。

ただ、ソースコード中で出てきた場合の一般的な意味と、辞書に載っている意味で剥離している場合もあります。
例えば、「apis」とあったら、「APIs」のことだとプログラマーは思うと思うのですが、辞書的には「蜂」です。
こういったものを機械的に振り分けるのは(今の自分の力量では)難しかったので、100% プログラマーが期待する結果になるわけではありませんので、ご注意!
ディープラーニングさせたらいいのかな?

ともあれ、boost を解析して自分なりに納得のいくところまで対応できたかなーと思ってます。

Glosbe でリクエスト制限にかかってしまった場合の対処方法
('Http error:', u'429 Client Error:  for url: https://glosbe.com/gapi/translate?dest=ja&phrase=opendir&from=en&pretty=true&format=json')
('request count: ', 802)
Please access the glosbe, click the search button and check reCAPTCHA.
Glosbe でリクエスト制限にかかると上記ログが出力されます。
これが出た場合、以下の方法で回復が可能です。

まずは、https://ja.glosbe.com/ にアクセスして、普通に辞書検索します。


以下のような画面になるので、チェックをクリアすると制限が解除されます。
(何回も制限かけられましたが、今のところこの方法ですぐに解除できています。)


最後に
このツールを実際に使ってみて、当初の目的の略語検出よりも typo 検出の方が役に立ちました。
実際にヒドイ typo が見つかりました…
https://github.com/srz-zumix/iutest/commit/c063225f5abfeb157f671e3fc55b779f32e12193

ただ、typo チェックであれば、「Pull Requestに潜むタイポを自動的に検出し、修正を代行するBot - Qiita」の方がよさそうだなーと思ったのと、PyEnchant ってのがあるほを初めて知ったので機会があれば使ってみようと思いました。

最後ですが、今回のアップデートで自己満足できるところまで作れたので、これで開発を一旦終了しようと思います。
(要望いただければ対応します)
ではでは。

2016年11月22日火曜日

ソースコード中の単語からの略語/スペルミス検出に挑戦

2018/2/22 追記:続編書いた「続・ソースコード中の単語からの略語/スペルミス検出に挑戦」。Glosbe の制限の解決策も書いてあります。

ブログズミ: TreeTagger を使ってソースコード中の単語をリストアップしてみた」の続きです。
今回は抽出した単語が略語、もしくはスペルミスなどがないかチェックします。

なぜ、こんなものを作ったのか?それは


ということです。

今回作成したものはそのうちの一つで、「許可された略語以外は禁止」という規約に対して、その発見を"補助"するものです。
(あくまで補助でこれをかけて何も検出されなかったら OK というわけではありません。でも、人間が一語一語確認するものでもないので、これでも十分かなぁーっと思ってます。)

できたもの
最初に出来上がったものを紹介したいと思います。
ソースコードはこちらで公開しています。

usage: abbreviation.py [-h] [-v] [-g FILE] [-w FILE] [-e EXCLUDE]
                       [-a ABBREVIATION] [--glosbe] [--dejizo] [--cache]
                       [--load-cache NAME] [--cache-dir DIR] [--list-all]
                       FILE/DIR [FILE/DIR ...]

positional arguments:
  FILE/DIR              source code file/dir

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  -g FILE, --gene FILE  exlude word
  -w FILE, --whitelist FILE
                        whitelist file
  -e EXCLUDE, --exclude EXCLUDE
                        exlude word
  -a ABBREVIATION, --abbreviation ABBREVIATION
                        abbreviation word
  --glosbe              use online translation service (glosbe)
  --dejizo              use online service (dejizo)
  --cache               online translation cache enable
  --load-cache NAME     load translation cache
  --cache-dir DIR       translation cache directory
  --list-all            list up all location

試しに iutest のソースコードを調べてみました。


設計としては、抽出した単語を辞書(オンライン/オフライン)から検索して、辞書にあれば問題なし(辞書に略語として登録されている場合は×)、辞書になかった場合に疑わしい単語として警告する設計です。

以下で詳しく説明していきます。

単語の抽出
「ソースコード中の単語」の抽出は libclang などを利用してやるほうが正しいとは思うのですが、
ブログズミ: TreeTagger を使ってソースコード中の単語をリストアップしてみた」でやったように形態素解析ツールの TreeTagger を使ってやりました。


オンライン辞書サービスを利用する
Glosbe
Glosbe Api
英単語の日本語訳をプログラム内やターミナル内で取得する - roombaの日記

いいね~いいね~とコーディングしていたら、いつの間にかエラーに…
Too many queries, your IP has been blocked

    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 429 Client Error:  for url: https://glosbe.com/gapi/translate?dest=ja&phrase=incg&from=en&pretty=true&format=json
というわけで、制限を超えてしまったようです…

ドキュメントによれば、「ブロックするリクエスト数は明確には決まってないけど、人間じゃなくてロボットだと判断したらブロックするよ」と書いてあります。

ロボットなのでしょうがないですね…
開発者でブロックされたら連絡してねとありますが、別のサービスを探すことにしました。
(一応、1日経つとブロック解除されています。今のところ)

WORDS API
WORDS API
無料プランでも 2,500 Requests/Day でよさそうだったんですが、クレジットの登録が必要だったので今回は保留としました。
(V-プリカとか使えば良いんですけど、めんどくさいので…)
(制限オーバーしたら請求が発生する感じに見えたのも保留した理由の1つ…)

デ辞蔵
デ辞蔵 オンラインでもオフラインでも使える電子辞書
続いて目をつけたのがこちら。
(SOAP ってなんだろ?って思ったんですが、そういうのがあったんですね)

こちらは特に制限がないのですが、注意事項として
・短時間にアクセスが集中するような呼び方(1秒間に20回以上の呼び出しなど)
・定常的に一定のアクセスが続くような呼び方(数秒ごとに自動的に呼び出すなど)
とありました。→「BizPal - デ辞蔵Tech よくある質問と回答
あと無償版は動作保証なし。

英和辞書で使えるのは、EDICT和英辞典(EJdict) と 三省堂 デイリーコンサイス英和辞典 試用版(DailyEJL)の2つあったので、両方を検索するようにしてます。ただし、 Glosbe よりも辞書の単語数は少ない印象
秒間20リクエストは場合によっては超えてるかもしれないので、ゴメンナサイm(__)m

その他
この記事も早く公開したいし、組み込みはこの辺で一旦終わりにしておきます。
その他の辞書サービスがあれば使ってみたいと思います。
あとは、翻訳サービス使う方法もありなのかも。

オンライン辞書のヒット結果をキャッシュする
さて、オンライン辞書から単語を引いてくることができるようになりましたが、リクエスト制限のことを考えなければいけません。というわけで、なるべくリクエストを投げないようにするために、一度検索ヒットした単語をローカルにキャッシュする仕組みを入れました。

今回 iutest を解析したときのキャッシュがリポジトリに入ってます。
このキャッシュはサービスごとに記録し、どんどん追記していく仕組みです。

また、キャッシュは2種類あります。
辞書には「略語」として単語登録されているものもありますので、ヒットしたけど略語だった場合はブラックリストに登録しています。
(※この略語判定が大変だった。特に EDICT は統一性がないのでかなり妥協…)

オフライン辞書を利用する
ソースコード中の単語で、外部に出したくないものもあると思います。(コードネームとか製品名とか?)
そこで、オフラインの辞書にも対応しています。

辞書は3つのタイプが利用可能です。

--whitelist FILE
単純な形式で単語を1行ずつ読み込みます。

--gene FILE
オープンしたファイルから、 '^[a-zA-Z][a-z]+$' にマッチするものを単語として読み込みます。
(これは GENE95 を想定して用意しているので、それ以外には使わないかもしれませんが…)

--cache-load XXX
オンライン辞書でキャッシュしたファイルを読み込みます。
XXX の部分にはオンライン辞書のオプション名を入れます。(現状、glosbe と dejizo のみ対応)
形式はホワイトリスト+ブラックリストになっています。

オンライン辞書では、場合によって "ver" などが "version" の略語として単語登録されている場合がありますので、
そのような単語はブラックリストとしてキャッシュしています。
(ホワイトリストの形式 --whitelist で読み込めるファイルと同じですので、これだけを --whitelist で読み込むことも可能です。)


使ってみた結果
当初は略語の検出を目的に作成しましたが、どちらかと言うと typo 、誤字脱字の方がよく検出される結果となりました。
(恥ずかしいのでちゃんと直しました。 > https://github.com/srz-zumix/iutest/commit/6c767630c810ef27b92bfca856a657209945433c

使ってみたい方、github で公開してますのでご自由にお使いください。