特許データで自然言語処理(4)

前回のキーワードの頻度分析に引き続いてword2vecです。word2vecはある程度のボリュームのテキストから、ある単語の近辺に存在する他の単語の分布確率を低次元の特徴量のベクトルで表すことができるように学習するツールです。周囲に出現する他の単語の分布確率が似た単語は同じような意味合いを有する言葉と言うこともできますので、特許的に言うと、特許検索の際の類義語探索に用いることが期待されます。また、意味的な足し算・引き算が有効に機能するように見える場合もあるようです。例えば、東京から日本を引いてフランスを足した特徴量ベクトルに近い単語はパリになるというような事例があります。

word2vecの説明はこれくらいで、前回のZITの1件の特許データをword2vecで処理してみましょう。本来はこのような少量のテキストよりもある程度のボリュームで処理するものではありますが、操作のお試しとしてはこれくらいから始めるのがよいでしょう。また、国内ではまとまった量の特許のテキストデータを無料でスムーズに入手することは難しいという事情もあります。

まず、最初にword2vecで処理が可能なテキストデータを準備します。Jupyter上で処理してもよいのですが、楽なのでコマンドライン上でMecabのコマンドで処理を行います。

mecab -Owakati samplepatent.txt -o sampledata.txt

まず、最初にword2vecで処理が可能なテキストデータを準備します。Jupyter上で処理してもよいのですが、楽なのでコマンドライン上でMecabのコマンドで処理を行います。

samplepaten.txtは前回の1件の特許の詳細な説明のテキストデータで、上記のMecabのコマンドで処理した結果は、形態素解析で切り出したキーワードをスペースで区切った以下のようなデータになります。前回は品詞等の情報が付いていましたが、このコマンドでの処理ではこのような形態素解析処理になります。

【 発明 の 詳細 な 説明 】
【 技術 分野 】
【 0 0 0 1 】
本 発明 は 、 例えば 、 スマートフォン や 携帯電話 や タブレット 等 の 主 に 無線 により ネットワーク に 接続 可能 な 携帯 クライアント ( 携帯端末 ) に 、 肌 測定機 装置 を 接続 し 、 ネットワーク を 介し て データ を 送受 する こと により 、 肌 の 状態 の 測定 と 測定 結果 の 分析 と を 行う とともに 、 測定 結果 や 分析 結果 の データ ( 測定 データ 、 分析 結果 データ ) を 管理 する 肌 状態 測定 分析 情報管理 システム および 肌 状態 測定 分析 情報管理 方法 に関する 。

作成したこのテキストデータをword2vecで処理していきます。まずはgensimからword2vecをimport。

from gensim.models import word2vec
word2vecの処理用のテキストデータとして先ほど作成したsampledata.txtを設定します。
data = word2vec.Text8Corpus('sampledata.txt')
設定したdataに対してword2vecのモデル作成を実行させます。
model = word2vec.Word2Vec(data, size=200)
1件の特許データ全文程度なら、モデル作成は一瞬で終わります。モデル作成が終われば、特定のキーワードに対して、そのキーワードとよく似たワードベクトルを有するキーワード、すなわち周辺に出現するキーワードに分布が類似したキーワードを探索できます。
out=model.most_similar(positive=[u'データ'])
out
これらのコマンドで、「データ」に類似したキーワードは以下のようになります。
[('前記', 0.9969677925109863),
 ('た', 0.991806149482727),
 ('れ', 0.9905794858932495),
 ('結果', 0.9895579218864441),
 ('さ', 0.9857822060585022),
 ('特定', 0.9777529239654541),
 ('化粧品', 0.9774397611618042),
 ('分析', 0.9741998314857483),
 ('測定', 0.9731069803237915),
 ('ID', 0.9713792204856873)]
同様に「登録」に類似したキーワードは以下のようになります。
out=model.most_similar(positive=[u'登録'])
out
[('p', 0.9984594583511353),
 ('関連付け', 0.9982966780662537),
 ('とともに', 0.9981814622879028),
 ('手段', 0.9980460405349731),
 ('項目', 0.9977996349334717),
 ('ユーザー', 0.9976646900177002),
 ('認証', 0.9976398944854736),
 ('使用', 0.9972869157791138),
 ('られ', 0.9969701766967773),
 ('検索', 0.9967353343963623)]
同様に「化粧品」に類似したキーワードは以下のようになります。
out=model.most_similar(positive=[u'化粧品'])
out
[('特定', 0.999102771282196),
 ('情報', 0.9974192976951599),
 ('入力', 0.9970183968544006),
 ('記憶', 0.9962270259857178),
 ('さ', 0.9947283864021301),
 ('ID', 0.9940637350082397),
 ('使用', 0.9934926629066467),
 ('た', 0.992370069026947),
 ('顧客', 0.9923679232597351),
 ('当該', 0.9917648434638977)]
同様に「肌」に類似したキーワードは以下のようになります。
out=model.most_similar(positive=[u'肌'])
out
[('状態', 0.9966976642608643),
 ('情報管理', 0.9924602508544922),
 ('システム', 0.9908404350280762),
 ('装置', 0.989385724067688),
 ('診断', 0.9883158206939697),
 ('簡易', 0.9857101440429688),
 ('や', 0.9848286509513855),
 ('詳細', 0.9844359159469604),
 ('および', 0.9841267466545105),
 ('による', 0.9835302233695984)]
同様に「表示」に類似したキーワードは以下のようになります。
out=model.most_similar(positive=[u'表示'])
out
[('すなわち', 0.9993413090705872),
 ('コンバージョンレンズ', 0.9993192553520203),
 ('メニュー', 0.9993120431900024),
 ('機能', 0.9992128014564514),
 ('ユーザー登録', 0.9992063641548157),
 ('高く', 0.9989919662475586),
 ('行わ', 0.9989498853683472),
 ('行う', 0.9989293813705444),
 ('特', 0.9988886117935181),
 (',', 0.9988185167312622)]
単一の特許公報のテキストデータでword2vecの分析を行ったため、類似するキーワードというよりは、単に特許公報中で近くに登場することが多いキーワードを摘出したような結果になりました。
次回はもう少しボリュームのあるデータでword2vecの分析を行っていきたいと思います。
かなりのボリュームのあるデータで作成済みのword2vecのモデルというのも公開されているものがあります。例えば、こちらのサイト「word2vecの学習済み日本語モデルを公開します」には日本語wikipediaのデータから作成済みのword2vecモデルが公開されています。このような作成済みモデルを試してみることで、ある程度のボリュームがあるデータでのword2vecの挙動を実感できると思います。

特許データで自然言語処理(3)

さて、前回までは環境設定とツールの説明まででした。今回からは少しづつ各ツールを使った分析を行っていきます。

お題目の自然言語処理ですが、例えば、「本発明はエネルギーを消費することなく自律走行が可能な移動体に関わる。」というようなテキストを分析する場合に、自然言語処理はこれをこのまま処理するのではありません。ざっくりいうと、元のテキストからひらがなを抜いて切り分けたようなキーワードの集まり、(「本発明」、「エネルギー」、「消費」、「自律走行」、「可能」、「移動体」・・・)のような形式に変換する必要があります。自然言語処理では、このような変換処理の後で、これらのキーワードが幾つあるか(頻度)、どのような並びで出現しているか(位置関係)等に基づいて分析を行っていきます。

前述の切り分け処理を形態素解析等と呼びます。前回までの環境設定で導入したMeCabもその一つですが、他にもJanomeやJuman等があります。

まずは、MeCabを使った形態素解析について、Jupyter Notebook上での処理の具体例を説明していきます。

Jupyter NoteBookを起動して、新規でPython3のNoteBookを作成したら、Mecabが使えるようにMecabのTaggerを呼び出します。

from MeCab import Tagger

分析対象となるテキストとして上述した例のテキストを設定します。

target_text = u"本発明はエネルギーを消費することなく自律走行が可能な移動体に関わる。"

MecabのTaggerオブジェクトをmとして生成し、mに上記のテキスト例の形態素分析を行わせた上で結果を出力させます。

m = Tagger() 
print(m.parse(target_text))
 で、これが出力結果です。
本	接頭詞,名詞接続,*,*,*,*,本,ホン,ホン
発明	名詞,サ変接続,*,*,*,*,発明,ハツメイ,ハツメイ
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
エネルギー	名詞,一般,*,*,*,*,エネルギー,エネルギー,エネルギー
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
消費	名詞,サ変接続,*,*,*,*,消費,ショウヒ,ショーヒ
する	動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
こと	名詞,非自立,一般,*,*,*,こと,コト,コト
なく	形容詞,自立,*,*,形容詞・アウオ段,連用テ接続,ない,ナク,ナク
自律走行	名詞,固有名詞,一般,*,*,*,自律走行,ジリツソウコウ,ジリツソウコー
が	助詞,格助詞,一般,*,*,*,が,ガ,ガ
可能	名詞,形容動詞語幹,*,*,*,*,可能,カノウ,カノー
な	助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
移動	名詞,サ変接続,*,*,*,*,移動,イドウ,イドー
体	名詞,接尾,一般,*,*,*,体,タイ,タイ
に	助詞,格助詞,一般,*,*,*,に,ニ,ニ
関わる	動詞,自立,*,*,五段・ラ行,基本形,関わる,カカワル,カカワル
。	記号,句点,*,*,*,*,。,。,。
EOS

 基本的なJupyter NoteBook上での形態素分析について説明しました。

次は実践編として、特許公報の発明の詳細な説明全体を取り込んで、Mecabで形態素解析を行った上で、形態素解析で切り分けたキーワードの頻度を分析する手法について説明していきます。特許公報のデータは、本日時点でJ-PlatPatの分類検索でIoT系の特許分類ZITでヒットする特許公報の内で最初の案件、特開2017-139005「肌状態測定分析情報管理システムおよび肌状態測定分析情報管理方法」の発明の詳細な説明全体をコピーして、メモ帳にテキストを張り付けて、文字コードをUTF-8にして(ここ大事)、ファイル名samplepatent.txtとして保存しました。

Jupyter NoteBookを起動して、新規でPython3のNoteBookを作成したら、初期設定として、Mecabとキーワードカウント用にCounterを呼び出すとともに、分析元の特許公報データのテキスト名をfname、形態素解析を行った後のテキストデータの保管先のファイル名をfname_parsedに設定します。

import MeCab
from collections import Counter
fname = 'samplepatent.txt'
fname_parsed = 'samplepatent.txt.mecab'
元ファイルを形態素処理して、形態素解析後のファイルをfname_parsedで設定したファイル名で保存します。
with open(fname) as data_file, open(fname_parsed, mode='w') as out_file:
    mecab = MeCab.Tagger()
    out_file.write(mecab.parse(data_file.read()))

出来上がる形態素分析済みのファイルの中身は次のようになります。

【     記号,括弧開,*,*,*,*,【,【,【
発明    名詞,サ変接続,*,*,*,*,発明,ハツメイ,ハツメイ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
詳細    名詞,形容動詞語幹,*,*,*,*,詳細,ショウサイ,ショーサイ
な      助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
説明    名詞,サ変接続,*,*,*,*,説明,セツメイ,セツメイ
】      記号,括弧閉,*,*,*,*,】,】,】 ….

 

形態素解析後のファイルを呼び出して、上から順に処理してmorphemesに辞書のリストとして保存していきます。分析結果の分かりやすさのために名詞の形態素のみをリストに追加するようにしています。

with open(fname_parsed) as file_parsed:
    morphemes = []
    for line in file_parsed:
        # 表層形はtab区切り、それ以外は','区切りでバラす
        cols = line.split('\t')
        if(len(cols) < 2):
            continue
        
        res_cols = cols[1].split(',')
        
        # 辞書作成、リストに追加(名詞のみ)
        if res_cols[0] == '名詞':
            morpheme = {
                'surface': cols[0],
                'base': res_cols[6],
                'pos': res_cols[0],
                'pos1': res_cols[1]
                }
        
        morphemes.append(morpheme)
morphemesの中身は次のようになります。
[{‘base’: ‘)’, ‘pos’: ‘記号’, ‘pos1’: ‘括弧閉’, ‘surface’: ‘)’},
{‘base’: ‘発明’, ‘pos’: ‘名詞’, ‘pos1’: ‘サ変接続’, ‘surface’: ‘発明’},
{‘base’: ‘発明’, ‘pos’: ‘名詞’, ‘pos1’: ‘サ変接続’, ‘surface’: ‘発明’},
{‘base’: ‘詳細’, ‘pos’: ‘名詞’, ‘pos1’: ‘形容動詞語幹’, ‘surface’: ‘詳細’},
{‘base’: ‘詳細’, ‘pos’: ‘名詞’, ‘pos1’: ‘形容動詞語幹’, ‘surface’: ‘詳細’},
{‘base’: ‘説明’, ‘pos’: ‘名詞’, ‘pos1’: ‘サ変接続’, ‘surface’: ‘説明’},
{‘base’: ‘説明’, ‘pos’: ‘名詞’, ‘pos1’: ‘サ変接続’, ‘surface’: ‘説明’},
{‘base’: ‘説明’, ‘pos’: ‘名詞’, ‘pos1’: ‘サ変接続’, ‘surface’: ‘説明’}, ….]
Counterオブジェクトword_counterを生成して、単語カウントのためにmorphemesから単語をセットしていきます。
word_counter = Counter()
for morpheme in morphemes:
    word_counter.update([morpheme['surface']])
word_counterにセットされた単語を大きいものから順に出力する処理を行います。
for word, cnt in word_counter.most_common():
    print (word, cnt)
 結果はこのようになります。
データ 2401
こと 1690
5 1320
登録 1145
場合 1122
化粧品 1063
よう 1031
3 1021
可能 897
肌 842
1 806
表示 781
0 769
入力 745
2 728
もの 727
状態 719
前記 704
ユーザー 636
測定 619
使用 566
手段 554
送信 495
装置 488
サーバ 473
ID 471
結果 456
データベース 447
分析 417
等 415
情報 414
診断結果 407
いかがでしょうか、上位頻度のキーワードとして「データ」、「登録」、「場合」、「化粧品」、「肌」等があることが分かりました。
次は、同じ公報データについてword2vecを用いた処理を行っていきます。