自然言語処理ハンズオン【MeCab, word2vec】動かしてみよう!

自然言語処理でよく使われるライブラリ、
MeCab(めかぶ)とWord2vec(わーどつーべっく)について
とりあえず動かせるようになれる記事です。

今回のゴール

・ゴール1
この文章からフルーツらしい単語を検出します。
"私はオレンジとバナナを作っている農家です。"
・ゴール2
長文での実践として、wikipediaのカレーの説明文から食材を抽出します。

進め方

Google colabratoryにてハンズオンで体験していきましょう!

再生ボタンをポチポチすると動きます。

MeCabとは?

文章を単語に分けるライブラリです。
たとえば、、
"私はオレンジとバナナを作っている農家です。"
という文章を単語に分けることができます。分かち書きと呼びます。

 #Wikipediaの文章をMeCabで分かち書きする 
tagger = MeCab.Tagger()  
tagger = MeCab.Tagger("-Owakati")
sample_txt = "私はオレンジとバナナを作っている農家です。"
words_list=list(tagger.parse(sample_txt).split())
words_list

['私', 'は', 'オレンジ', 'と', 'バナナ', 'を', '作っ', 'て', 'いる', '農家', 'です', '。']

さらに詳しく解析もできます。形態素解析と呼んだりします。

 #詳しい分析もできます
tagger1 = MeCab.Tagger()  
sample_txt = "私はオレンジとバナナを作っている農家です。"
tagger1.parse(sample_txt).split()

['私','代名詞,,,,,,ワタクシ,私-代名詞,私,ワタクシ,私,ワタクシ,和,"","","","","","",体,ワタクシ,ワタクシ,ワタクシ,ワタクシ,"0","","",11345327978324480,41274',

'は', '助詞,係助詞,,,,,ハ,は,は,ワ,は,ワ,和,"","","","","","",係助,ハ,ハ,ハ,ハ,"","動詞%F2@0,名詞%F1,形容詞%F2@-1","",8059703733133824,29321',

'オレンジ','名詞,普通名詞,一般,,,,オレンジ,オレンジ-orange,オレンジ,オレンジ,オレンジ,オレンジ,外,"","","","","","",体,オレンジ,オレンジ,オレンジ,オレンジ,"2","C1","",1477202495545856,5374',

word2vecとは?

単語同士の類似度を算出できるライブラリです。
「ワードtoベクトル」の略で、単語をベクトル化する技術です。

先ほど作成した単語リスト
['私', 'は', 'オレンジ', 'と', 'バナナ', 'を', '作っ', 'て', 'いる', '農家', 'です', '。']
からフルーツを抽出するために、それぞれの単語と「フルーツ」との類似度を計算します。

 #分かち書きした文章から 、word2vecでフルーツを抽出
for word in words_list:
  try:
    sim = word2vec_model.similarity("フルーツ", word)
    print(word,":",round(sim*100,2),"%")
  except (KeyError) :
    pass

私 : 29.79 %
は : 27.44 %
オレンジ : 51.46 %
と : 29.47 %
バナナ : 69.16 %
を : 23.89 %
て : 28.42 %
いる : 17.57 %
農家 : 26.12 %
です : 30.46 %
。 : 22.53 %

オレンジとバナナの数値が高く、いい感じに計算されています。

MeCabとWord2vecが使えるようになったところで、2つ目のゴールの、カレーの説明文からの食材抽出を行いましょう!

カレーの食材抽出

まずはMeCabで分かち書きをします。

 #Wikipediaの文章をMeCabで分かち書きする 
tagger = MeCab.Tagger()  
tagger = MeCab.Tagger("-Owakati")
sample_txt1 = "日本にカレーが伝えられたのは1868年で、イギリスの商船が既成のカレー粉を持ち込んだのが始まりとされている[15]。その後1872年には仮名垣魯文によって編纂された『西洋料理通』が出版され、カレーレシピが紹介されることで広く浸透した[15]。定着の理由としては時代背景として肉食の奨励とともに西洋文化の取り込み・吸収に貪欲であったことに加え、野菜、肉、米をまとめて摂取可能な上に安上がりで食べ応えがあったことが挙げられている[16]。イギリスから伝わったものに小麦粉を加えたとろみのあるカレーを米飯(ライス)の上に掛けて食する「カレーライス」が普及しており、それぞれの地域や家庭、店舗等によって様々にアレンジされたカレーが存在する。スープ状のカレーや、カレー味のスープはスープカレーと呼ばれ、ハウス食品のレシピの例では、使用される具材は固形カレーの素、タマネギ、ロースハム、キャベツ、サラダ油、水、塩、胡椒である。グリーンカレーの名で販売する店舗もあり、インドの地方やタイのカレーは同様のカレーと呼ぶがスープ状の物であり、スープ状である事からカレースープと呼ぶ人もいる[17]。「カレー」と称しているがスープの店もある[18]。日清食品からカップのグリーンカレーのスープも販売されている。地元産素材を使う地域の町おこしとして売り出される例もみられる[19][20]。そのほかにも、日本独自のカレー料理(食品)は多く、カレー南蛮(カレー味の汁をかけたかけそば)などの麺類、ドライカレー、カレーまん、カレーパン、カレーコロッケなどがある。カレー味に調味したスナック菓子も多い。"
words_list1 = list(tagger.parse(sample_txt1).split()) #10単語だけ出力 
words_list1[:10]

['日本', 'に', 'カレー', 'が', '伝え', 'られ', 'た', 'の', 'は', '1868' ……………..]

ここからWord2vecで「食材」に似ている単語を算出しましょう。
類似度が40%を超える単語に絞り込みます。

 #word2vecで分かち書きした文章から 、食材っぽいものを抽出
dump=[]
for word in words_list1:
  try:
    sim = word2vec_model.similarity("食材", word) #40 %以上似ている単語に絞り込み
    if sim>0.4 and word not in dump:
      print(word,":",round(sim*100,2),"%")
    dump.append(word)
  except (KeyError) :
    pass

カレー : 46.41 %
料理 : 70.61 %
レシピ : 50.2 %
野菜 : 71.45 %
肉 : 56.63 %
米飯 : 50.51 %
食する : 56.85 %
スープ : 47.82 %
味 : 43.54 %
食品 : 64.6 %
具材 : 63.38 %
キャベツ : 45.0 %
サラダ : 49.03 %
麺類 : 56.03 %
パン : 43.74 %
コロッケ : 41.91 %
調味 : 58.45 %
菓子 : 45.06 %

まずまず絞り込めてますが、微妙なものも入ってますね。
さらに「炭水化物」に似ているものに絞り込みましょう。

#「食材」に加えて「炭水化物」でも絞り込んでみる
dump,dump2=[],[]
for word in words_list1:
  try:
    sim = word2vec_model.similarity("食材", word) #40 %以上似ている単語に絞り込み
    if sim>0.4 and word not in dump:
      dump2.append(word)
    dump.append(word)
  except (KeyError) :
    pass
dump=[]
for word in dump2:
  try:
    sim = word2vec_model.similarity("炭水化物", word) #30 %以上似ている単語に絞り込み
    if sim>0.3 and word not in dump:
      print(word,":",round(sim*100,2),"%")
    dump.append(word)
  except (KeyError) :
    pass

カレー : 31.18 %
野菜 : 44.94 %
肉 : 41.86 %
米飯 : 47.58 %
食する : 41.55 %
スープ : 37.43 %
食品 : 45.93 %
具材 : 35.5 %
キャベツ : 42.3 %
サラダ : 36.51 %
麺類 : 57.34 %
パン : 36.41 %
コロッケ : 30.61 %
調味 : 32.49 %
菓子 : 32.42 %

「料理、レシピ、味」が消されて少し、理想に近づきました。
まだ改善の余地はありますが、今回はここまでにしようと思います。
お時間あれば色々と試して精度を上げてみてください。


参考記事:
今回のword2vecのモデルはここから引用させていただきました。
モデルはたくさん公開されているので、別モデルを使うと結果も変わります。(word2vecはSudachiのモデルなんかい)


この記事が気に入ったらサポートをしてみませんか?