CreateField Blog

オープンソースを使って個人でWebサービスを開発・運営していたブログ

日米特許のデータを使ってword2vecを試してみた

はじめに

去年あたりから流行っているらしいword2vecが面白そうだったので日本特許の要約データと米国特許の要約データを使って試してみました。

word2vecは、類語やアナロジー(類推)等を取得することができます。

word2vecの使い方は非常に簡単で、空白区切りのテキストデータをword2vecの学習プログラムに渡すだけです。

アナロジーというのは、ベクトル同士を演算し、A → Bの関係に対し、C→Xに当てはまるXというのを探すことができるようです。

(引用)https://plus.google.com/107334123935896432800/posts/JvXrjzmLVW4
面白いのは、2つのベクトルの差が、2つの単語の関係をよく近似してくれること。 (中略) A B C → X (A → Bの関係に対し、 C → X に当てはまるXを探す)

グーグル ヤフー トヨタ → 日産
渋谷 新宿 札幌 → 旭川
警察 泥棒 正義 → くそ
平和 戦争 左 → 右
社員 会社 生徒 → 小学校
空 海 天井 → 床板
生きる 死ぬ 動く → 止まる

実装例

兎にも角にも、まずは、実際に試してみた例を示します。特許の全文検索サービスにword2vecを使った類語、類推語検索機能を組み込んで見ました。

以下のページで試すことができます。上部フォーム横にある検索ボタンの左の+ボタンで類義語、類推語を検索することができます。

PatentField | 無料特許検索

類語取得例

以下は類語取得例です。

筆記具 ボールペン 筆記 万年筆 消しゴム 水性ボールペン 水性インキ 筆記具用インキ 筆記用具 サインペン
自動車 乗用車 オートバイ 車両 車輌 車輛 二輪車 乗り物 乗物
スマートフォン PDA 携帯情報端末 パソコン pda カーナビ 携帯型コンピュータ
ラーメン うどん 味噌汁 スープ 麺類 麺 玉子
情報処理装置 情報処理システム データ処理装置 コンピュータ装置 多機能周辺装置 情報処理プログラム
煩雑 繁雑 面倒 煩わしい 煩瑣 手間
円滑 スムーズ スムース 確実 容易 迅速 速やか

割と類語らしきものがとれていますね。結構いい感じです。ちなみに日本特許の要約データには、ほぼ商標が入っていないはずなので、商品名とかはとれません。

また、学習させたコーパスには、行頭に出願人(会社名)をつけているので、今度は会社名で類語を取得してみます。

任天堂株式会社 株式会社コナミデジタルエンタテインメント 株式会社ソニー・コンピュータエンタテインメント 株式会社バンダイナムコゲームス 株式会社国際電気通信基礎技術研究所 株式会社タイトー 株式会社セガ 株式会社スクウェア・エニックス
ヤフー株式会社 楽天株式会社 株式会社日立ソリューションズ 株式会社野村総合研究所 NECフィールディング株式会社 株式会社日立システムズ 富士通モバイルコミュニケーションズ株式会社 ソフトバンクモバイル株式会社
グーグル・インコーポレーテッド ヤフー!インコーポレイテッド ▲ホア▼▲ウェイ▼技術有限公司 アマゾンテクノロジーズインコーポレイテッド グーグルインコーポレイテッド アリババ・グループ・ホールディング・リミテッド
パナソニック株式会社 シャープ株式会社 ソニー株式会社 パナソニック電工株式会社 松下電器産業株式会社 三星電子株式会社 三菱電機株式会社
トヨタ自動車株式会社 日産自動車株式会社 本田技研工業株式会社 マツダ株式会社 株式会社デンソー 富士重工業株式会社 ダイハツ工業株式会社 日野自動車株式会社 アイシン精機株式会社

ほぼ同じ業界の会社名が現れていますね。

なお、特許情報の書誌データに出現する会社名を追加した形態素解析辞書を使っているので株式会社まで入った正式名称で類語検索する必要があります。出願人名はこちらで検索することができます。

米国特許の要約データから英語のモデルも作成しました。

フレーズ処理で変なくっつきかたしているのもありますが、英語の方もうまくいく例が結構ありました。しかし、うまく前処理ができていないせいか日本語よりは精度が落ちる感じです。

smartphone smart_phone smartphones cellular_telephone pda pda_laptop assistant_pda
ipad iphone ipod iphone_xae
browser web_browser web_page browse webpage applet html
car vehicle automobile passenger railway
twitter facebook facebook_xae stock_quote yahoo facebook_twitter myspace blogging newsfeeds blogger
google ebay yahoo yahoo! stock_quote twitter facebook

類推語取得例

以下は、類推語取得例です。

印刷→プリンタ 通信→(通信制御装置 LAN データ通信 無線通信回線 無線通信網 ゲートウェイ装置 通信機器)

動詞V→主語S 動詞Vとすることで、動詞Vに対応する主語Sが取得されています。この例では、通信する物が取得されていますね。

プリンタ→印刷 カメラ→(撮影 撮像 被写体 撮像カメラ ステレオ撮影 テレビカメラ)

逆に、主語S→動詞V 主語Sとすることで、主語Sに対応する動詞Vが取得されています。この例では、カメラに対応する動詞として、撮影、撮像が取得されていますね。

日本語は、主語と動詞のベクトル差が同じぐらいなのかもしれません。

king - man +woman = queenのような属性的な演算がうまくできるものは、見つかりませんでした(思いつきませんでした)。何かおもしろそうなものがあったら、教えてください。

ここからは、実際にやった作業メモです。

C言語版word2vecをダウンロード、コンパイル

https://code.google.com/p/word2vec/

CentOS6.4では、makefileのCFLAGSの-Ofastオプションがうまく使えなかったのでfastオプションを除去して-O2を追加してmakeしました。

4/23追記
以下を参考にすると、速度差が結構あるらしく、GCCのバージョンを見直したほうがいいのかもしれません。

http://www.pc-koubou.jp/blog/word2vec.php

前処理

sedを使って、コーパスに対してアルファベット大文字を小文字に統一、HTML/XMLタグ、特殊文字の除去等の前処理をします。

% sed -i -e "s/[\t&#12345678901234567890,.\"'()();:^/-]/ /g" jpa_abst.csv
% sed -i -e 's/<[^>]*>/ /g' jpa_abst.csv
% tr A-Z a-z < jpa_abst.csv > jpa_abst2.csv

英語コーパスの基本形戻し

英語の場合、ingや複数形、過去形などの活用形をWordNetを使って基本形に戻します。

以下は、WordNetライブラリを使った作業用プログラムです。
https://gist.github.com/naoa/9997134

% yum install glib2 glib2-devel wordnet wordnet-devel
% gcc -I/usr/include/glib-2.0 -lglib-2.0 -lWN wn_morph.c -o wn_morph
% ./wn_morph us_abst2.csv

英語コーパスのフレーズ処理

word2vecにはフレーズを抽出するプログラムが含まれているようなので、これを使ってフレーズ抽出します。

% time ./word2phrase -train us_abst2.csv -output us_abst_phrase.csv -threshold 500 -debug 2
Starting training using file us_abst2.csv

Words processed: 400900K     Vocab size: 18319K
Vocab size (unigrams + bigrams): 11162427
Words in train file: 400962342
Words written: 400900K
real    6m40.781s
user    6m34.243s
sys     0m6.251s

日本語コーパスの分かち書き

日本語の文書は、単語ごとに空白区切りとなっていないため、MeCabを使って分かち書きをします。 辞書データは、専門用語が含まれている方が望ましいです。今回は、特許の機械翻訳辞書や特許文書から機械的に専門用語を抽出して、naist-jdicに専門用語を追加した辞書を使って分かち書きをしています。(あまり洗練されていなく、名詞以外も含まれちゃっています。)

% mecab -d /usr/lib64/mecab/dic/naist-jdic/ -Owakati jpa_abst.csv > jpa_abst2.csv 2>&1 &

トレーニング

オプションは、demo-word.shとdemo-phrases.shを参考に以下のようにしました。

  • 日本
% time ./word2vec -train jpa_abst4.csv -output jpa_abst5.bin -size 200 -window 5 -negative 0 -hs 1 -sample 1e-3 -threads 12 -binary 1
Starting training using file jpa_abst4.csv
Vocab size: 667502
Words in train file: 1049391660
Alpha: 0.000025  Progress: 99.90%  Words/thread/sec: 18.22k
real    123m17.701s
user    961m9.457s
sys     0m13.122s
コーパスサイズ 6.4G
モデルサイズ 523M
  • 米国
% time ./word2vec -train us_abst_pharase5.csv -output us_abst_pharase5.bin -cbow 0 -size 300 -window 10 -negative 0 -hs 1 -sample 1e-3 -threads 12 -binary 1
Starting training using file us_abst_pharase5.csv
Vocab size: 552645
Words in train file: 392879338
Alpha: 0.000007  Progress: 99.98%  Words/thread/sec: 6.76k
real    122m56.767s
user    968m55.401s
sys     0m5.715s
コーパスサイズ 2.2G
モデルサイズ 640M

類似演算とアナロジー演算するWebサーバの作成

Webアプリから使うためにサーバが欲しかったので、Qiitaにあったpythonを使ったWebサーバにword2vecのpythonインターフェースのcosineとanalogyの機能を付け加えました(Qiitaの著者様に感謝です。)。なお、pythonをはじめて触ったこともあって割りと適当です。

https://gist.github.com/naoa/10005117

pythonのパッケージ管理ソフトとword2vecのpythonインターフェースをインストールして、サーバ実行

% yum install python-pip python-setuptools numpy
% pip install word2vec
% python word2vec_server.py jpa_abst4.bin 8000

これで以下のようにGETアクセスをすると、JSONが得られるようになります。

curl "127.0.0.1:8000?c=test&n=10"
curl "127.0.0.1:8000?pos=king%20woman&neg=man&n=10"

おわりに

自然言語処理の知識はほとんどありませんでしたが、上記のようにword2vecを簡単に利用することができました。非常に簡単に学習できるにも関わらず、類義語はなかなかの精度で得られています。類推は、使いどころが難しいなぁと思いました。そのうち、もう少し分野を絞ったら、どうなるか試してみたいと思います。

本来の動きかどうかはわかりませんが、訳語が抽出できるようなパターンもあるようです。

http://naoyat.hatenablog.jp/entry/2013/09/11/002941

特許の文献では日英対訳を取得することも容易なので、日英対訳コーパスでword2vecをうまく利用できないかなぁとぼんやりと思っています。

また、アナロジーとは異なるベクトル演算ができないかとかも気になっています。

全文検索エンジンGroongaを使って、特許の全文検索システムを作るときにも思ったのですが、自然言語処理は非常に面白いなぁと思います。

惜しむらくは、大学時代に自然言語処理が面白いことに気づきたかったなぁ。。

おまけ

あまり出現しないワードだと、へんてこな答えが返ってくることがあります。

サラリーマン 山奥 お年 貧困 出掛ける いただける

特許情報的には、サラリーマンは山奥でお年をめしていて貧困なようです。

記事を追加しました。

word2vecをDockerでプレーンテキストから簡単に使えるようにしました

複合語などの専門用語を自動抽出するTermExtractをDockerで簡単に使えるようにしました。word2vecで解析する前にこれを使って、形態素解析辞書に用語を追加してみてはいかがでしょうか。

専門用語を自動抽出するTermExtractをDockerで簡単に使えるようにしました

全文検索エンジンGroongaからword2vecを簡単に使えるプラグイン - CreateField Blog

Groongaからword2vecを使って類似文書を取得してみる - CreateField Blog

参考

https://plus.google.com/107334123935896432800/posts/JvXrjzmLVW4
http://naoyat.hatenablog.jp/entry/2013/09/05/230947
http://naoyat.hatenablog.jp/entry/2013/09/11/002941
http://antibayesian.hateblo.jp/entry/2014/03/10/001532
http://saiyu.cocolog-nifty.com/zug/2014/02/word2vec-1867.html
http://kensuke-mi.hatenablog.com/entry/2014/01/25/072210

Mroongaを使って全文検索Webサービスを作ったときにはまったこと(第1回)

前回のエントリに書いたように、1年半ほどをかけて、独学で特許の全文検索サービスを開発しました。

PatentField | 無料特許検索

最初は、MySQLを使ったこともない状態だったこともあり、かなり紆余曲折しました。Groonga開発チームの懇切な対応もあって、専用サーバ1台で最大で1千万レコード超、400GiB以上のサイズのテキストデータを高速に検索できるようになりました。

今後、何回かにわけて、Mroonga(Groonga)を使って全文検索Webサービスを作ったときにはまったこと、学んだことを全て書き出したいと思います。

全文検索エンジンMroongaとは?

Mroongaは全文検索エンジンであるGroongaをベースとしたMySQL用のストレージエンジンです。Mroongaは、MySQLが使える人であれば、簡単に高速な全文検索機能が使えます。MariaDB10.0系にもバンドルされる予定のようです。

MyISAMラッパーモードでのデータベース構築

最初、データベースをMyISAMで構築したこともあり、ドキュメント(ストレージモード/ラッパーモード)を比較したところ、Groongaのコマンドの実行とカウントの高速化がないぐらいだったため、ラッパーモードでいけるかなぁと思い、ラッパーモードで全文検索を試してみました。

インデックス構築に失敗(mmap編)

数百GiBぐらいのテーブルを10分割し、数十GiBぐらいのテーブルを作成し、インデックス構築をしてみました。しかしながら、以下のようなメッセージがでて、インデックス構築できませんでした。

mmap(4194304,551,432017408)=Cannot allocate memory

これについては、groonga-devのメーリングリストで相談しつつ、vm.max_map_countのカーネルパラメータを見直すことで、このメッセージの発生を抑制することができました。今は、このドキュメントに対応方法の詳細が記載されています。

4/15 追記

このドキュメントに記載のように、データベースがメモリサイズを超える場合、vm.overcommit_memoryの設定をしておくことが推奨されています。

vm.overcommit_memory = 1

インデックス構築に失敗(long token編)

Mroongaでは、転置インデックスを作成するためのパーサ(Groongaでは、トークナイザと呼ばれる)として、デフォルトでTokenBigramが用いられます。

通常、Bigramと言えば、2文字ごとにトークンが作成されると思われますが、Mroongaでは、このドキュメントに記載の通り、連続したアルファベット、記号については、1つのトークンとして扱われます。

また、Mroonga(Groonga)では、1つのキーの最大サイズが4096Byteという制限があります。

このため、当時は、アルファベット、記号が4096個以上連続する場合、この制限にひっかかり、インデックス構築できませんでした(今は、4096個以上連続したとしても警告扱いでインデックス構築には失敗しません。)。

これについて、groonga-devのメーリングリストで相談すると、すぐにTokenBigramSplitSymbolAlphaDigit使えばいいよ!という回答が得られました。

非常に親切だなぁと思ったのを覚えております。

TokenBigramSplitSymbolAlphaDigitは、記号、アルファベットについても、2文字で切り出すトークナイザです。これにより、4096Byte以上となるトークンが発生せずに、インデックス構築ができるようになりました。

TokenBigramSplitSymbolAlphaDigitとTokenBigramの検索性能差

アルファベットは、日本語よりも種類が少ないため、アルファベットのBigramでの異なり語数は、たったの26*26種類です。このため、数十GiBクラスの英文のテキストデータをTokenBigramSplitSymbolAlphaDigitでトークナイズすると、TokenBigramに比べて、検索性能が顕著に劣化することが判りました。

TokenBigramSplitSymbolAlphaDigitは、トークンを短く切って一致率を上げるかわりに、検索性能の劣化が生じます。これは、トレードオフの関係となるため、仕方がありません。

しかしながら、上述のように、4096個以上連続するアルファベットが含まれる場合は、インデックス構築することができませんでした。

groonga-devのメーリングリストで相談すると、too long tokenを警告メッセージにして、4096Byte以上の長いトークンについては無視するように改修してくれました。

これもものすごい速い対応で感動した覚えがあります。

これにより、数十GiBのデータベースについては、インデックス構築に失敗せず、MyISAMのラッパーモードで高速に全文検索できるようになりました。

その後、「ストレージモードの検討」、「複数条件の絞り込み」、「Spiderストレージエンジンを使ったデータベースシャーディングの検討」、「ドリルダウン検索の検討」、「テーブルの統合」、「テーブルの統合によるカラムサイズ制限」、「テーブルの統合によるインデックス構築失敗再び」、「トークナイザのカスタマイズ」、「ノーマライザのカスタマイズ」、「スニペットがうまく取得できない場合がある」、等、様々な問題にぶちあたります。

それは、またの機会に書き連ねたいと思います。

おわりに

Groonga、Mroongaは日本で活発に開発が行われており、毎月29日にバージョンアップされています。

最近、全文検索エンジンとしては、Elasticsearchなどが流行ってきているようですが、Mroongaには、MySQLのストレージエンジンで簡単に全文検索が使えるというメリットもあり、Groongaも、他の全文検索エンジンに負けないほど高速なはずです(Lucene系の全文検索エンジンと比較したことがないからわかりませんが速いはず。)。

また、先月には、Droongaと呼ばれる分散型の全文検索システムもメジャーリリースされています。

困ったことがあれば、groonga-devのメーリングリストで相談すると、ものすごく親切に対応してくれるはずです。(Twitterでつぶやくだけでも、どこからともなく、親切な方がやってきて助け舟が入る可能性も。。私が知っている範囲なら、私に聞いてもらっても大丈夫です。)

全文検索システムを使いたい場合は、Groonga、Mroongaがおすすめです。

足りない部分があるなら、どんどん提案したり、改修していけたらいいなぁと思います。日本製のGroongaがもっと普及して欲しいと思っています。

全文検索システムを使いたい場合は、Groonga、Mroongaがかなりおすすめです。

4/13 記事を追加しました。
ストレージモードとGroongaの利点について説明しています。
Mroongaのラッパーモードからストレージモードに変えた理由 - CreateField Blog

4/15 記事を追加しました。
ストレージモードにしてはまったことについて説明しています。
数百GiBの全文検索用データベースをMroongaのストレージモードにしてはまったこと - CreateField Blog

6/26 記事を追加しました。
Groongaがあまり得意でない類似文書検索に連想検索エンジンGETAssocを使った話

2014-11-29(土)13:30 - 17:30
年に1度のGroongaに関するイベントがあります。Groongaを使っている人、興味がある人は参加してみてはいかがでしょうか。

全文検索エンジンGroongaを囲む夕べ5 - Groonga | Doorkeeper

独学で特許の全文検索サービスを開発しました

はてなブログ初投稿です。

 大学の授業でC言語をかじった程度のサラリーマンですが、1年半ほどをかけて、独学で特許の全文検索サービスを開発しました。

 PatentField | 無料特許検索

 1年半前は、データベースもサーバサイドの言語もJavaScriptもまったく触ったことがなく、Ajaxって何?ってぐらいの技術レベルでしたが、ようやく先月公開することができました。

 まだまだ未完成ですが、最大で1千万レコード以上、400GiB以上のサイズのテキストデータを高速に全文検索することができます。

 

このサービスでは、ただ公報データを全文検索するだけではなく、整理標準化データと呼ばれる権利の死活情報等を含む数十種類の項目を組み合わせて検索することができます。これにより、一般の利用者が特許を侵害していないかどうかを確認し易く、また、特許期限切れのフリ―な技術情報を簡単に参照できるようにしています。

また、特許の世界では、日本で出願した特許出願が翻訳され、同じ発明の内容が様々な国で外国特許出願されます。この同じ発明の内容の特許出願をパテントファミリーといいます。このサービスでは、日本出願のパテントファミリー情報を独自に蓄積しており、パテントファミリーの有無に応じた絞り込みも可能となっています。

たとえば、米国に特許出願されている日本特許出願を検索し、日本特許出願と、対応する米国特許出願を比較すれば、技術用語の対訳表現を抽出することができます。これにより、特許明細書の技術者や翻訳者が技術用語を簡単に調べることができるようにしています。

このサービスでは、サーバサイドの言語にPHP、データベースにMySQL、全文検索エンジンにMroonga(Groonga)、連想検索エンジンにGETAssocを使用しています。

今後について

このブログでは、主に、独学でWebサービス開発、運営するにあたり、つまったこと、調べたこと、感じたこと、等を記録していきたいと思います。

なお、単純な技術メモについては、MediaWikiをつかった以下のWikiでまとめています。

CreateField

今後は、上記サービスの運営、改善をしつつ、Droonga、Ruby、Rails、Bootstrapあたりを勉強しつつ、新しく全文検索を使ったサービスを作りたいなぁと思っています。