前回は、学習済みのw2vを扱いました。ただしそれですと、自分の目的にあった使い方ができない場合があります。そのためここでは、一からモデルを作ってみる、ということを学びます。
from gensim.models import Word2Vec
import numpy as np
import MeCab
今回、中心に使用するgensimは以下にドキュメントがあります。 https://radimrehurek.com/gensim/models/word2vec.html
今回は、口コミ文章内に登場する用語の類似を算出するためのw2vを開発してみます。 このため、あるエアコンの口コミを適当に用意しました。
なお、今回は練習用の例ですので、少数データで行います。でも、本来は莫大な量のテキストが必要であることを忘れないでください。
mail_text =[
"すぐに温度が下がり、部屋が冷たくなります。この商品はとても良いと思います。",
"良い商品で嬉しいです。冷たい風が素早く発生し、部屋の温度が下がりました。",
"エアコンのボタンを押すと、すごい勢いで動作しました。嬉しいです。",
"リモコンのボタンを入れても、動きませんでした。ダメな製品で、良くないです。",
"部屋が寒くなりすぎて、困りました。ダメな製品だと思います。",
"たまに電源がつかないので、困る。部屋も寒くなりすぎるし、返品したいくらいダメな商品だ。"
]
続きて、mecabを活用し、形態素解析にかけ、品詞ごとに分解します。word2vectorを使用するには、分かち書きに分解しておくことが必要です。
def wakachi(txt):
Dic = MeCab.Tagger("-Ochasen")
node = Dic.parseToNode(txt)
Info01, Info02, Word = [], [], []
while node:
Info01.append(node.feature.split(",")[0]) # 品詞情報1
Info02.append(node.feature.split(",")[1]) # 品詞情報2
Word.append(node.surface.split(",")[0]) # 単語
node=node.next
return Word
TrainingDat = []
for i in range(len(mail_text)):
temp = wakachi(mail_text[i])
temp.pop(0) # 最初の空白文字を削除
temp.pop(-1) # 最後の空白文字を削除
TrainingDat.append(temp)
print("TrainingDat[", i, "]: \n", TrainingDat[i])
print("")
続いて、分かち書きに変換されたデータを用い、w2vを学習させてみます。
mod = Word2Vec(
TrainingDat,
sg=1, #skip-gram
min_count=1, # 登場回数がこれ未満の単語は、除去
window = 5, # 前後いくつまでの単語を対象とするか
iter = 3000, # 学習回数
alpha = 0.1, # 学習係数(0.1, 0.01あたりを推奨)
seed = 0 # 乱数シード(自然数を指定、結果の再現性を保証)
)
これで学習が終わりました。このモデルは、どんな単語の入力を受け付けているか、表示してみます。
mod.wv.vocab.keys()
ここに表示されているワード以外は使用できないので、注意が必要です。学習済みのw2vを使用して何か単語を入力したときにエラーが出る場合は、ここにない単語を入力している場合がほとんどです。
続いて、学習済みモデルを活用して、2単語間の類似度を算出してみます。
w1 = "返品"
w2 = "ダメ"
dist12 = mod.wv.similarity(w1, w2)
print("[", w1, "] と [", w2, "] の類似度: ", np.round(dist12, 3))
w3 = "嬉しい"
w4 = "ダメ"
dist34 = mod.wv.similarity(w3, w4)
print("[", w3, "] と [", w4, "] の類似度: ", np.round(dist34, 3))
w5 = "嬉しい"
w6 = "良い"
dist56 = mod.wv.similarity(w5, w6)
print("[", w5, "] と [", w6, "] の類似度: ", np.round(dist56, 3))
同時に発生しそうな用語は類似度が高く、対象的な用語は類似度が低く出ました。他にもいくつか試してもて、類似度をきちんと測れてそうならばokです。もしダメそうなら、
を検討してください。
ある口コミが入力されたとき、それがポジティブなものか、ネガティブなものか、当てるシステムを開発してみましょう。アルゴリズムの簡単流れは以下の通りです。
# 処理 (A)
input_text = "部屋が寒くなりすぎるし、動かないときもあるし、困ります。"
#input_text = "このエアコンはすぐに部屋が冷える!"
#input_text = "このエアコンは、部屋がよく冷えるけど、たまに動かないから困るよ。"
print("\n *** 解析対象テキスト ****")
print(input_text)
# 処理(B)
wakachi_text = wakachi(input_text)
print("\n *** 形態素解析(分かち書き) ****")
print(wakachi_text)
# 処理(C)
NegativeScore = 0
PositiveScore = 0
# 処理 (C-1)
print("\n *** NegativeScore 算出ログ ****")
NegWord1 = "ダメ"
NegWord2 = "返品"
for i in range(len(wakachi_text)):
try: # 類似度算出にトライ
temp_dist1 = mod.wv.similarity(wakachi_text[i], NegWord1)
temp_dist2 = mod.wv.similarity(wakachi_text[i], NegWord2)
except Exception as e: # エラーが出る場合
print("「", wakachi_text[i], "」を扱えないので、スキップします。")
else: # エラーが出ない場合
print("「", wakachi_text[i], "」のNegativeScore加算値:", temp_dist1+temp_dist2)
NegativeScore = NegativeScore + temp_dist1 + temp_dist2
# 処理 (C-2)
print("\n *** PositiveScore 算出ログ ****")
PosWord1 = "良い"
PosWord2 = "嬉しい"
for i in range(len(wakachi_text)):
try: # 類似度算出にトライ
temp_dist1 = mod.wv.similarity(wakachi_text[i], PosWord1)
temp_dist2 = mod.wv.similarity(wakachi_text[i], PosWord2)
except Exception as e: # エラーが出る場合
print("「", wakachi_text[i], "」を扱えないので、スキップします。")
else: # エラーが出ない場合
print("「", wakachi_text[i], "」のPositiveScore加算値:", temp_dist1+temp_dist2)
PositiveScore = PositiveScore + temp_dist1 + temp_dist2
# 処理 (D)
print("\n *** スコア表示 ***")
print(" NegativeScore = ", np.round(NegativeScore, 3))
print(" PositiveScore = ", np.round(PositiveScore, 3))
# 処理 (E)
print("\n *** 推定結果 ***")
if PositiveScore - NegativeScore >= 0.5: # ポジが0.5以上高いなら
print("この口コミは、ポジティブだと判定されました。")
elif NegativeScore - PositiveScore >= 0.5: # ネガが0.5以上高いなら
print("この口コミは、ネガティブだと判定されました。")
else:
print("この口コミは、中立だと判定されました。")
こんな感じで、ポジティブ/ネガティブをうまく判定できました。 このモデルは、
を利用しています。でも、入力した口コミを見ても、この用語は直接利用されていません。これがw2vの利点で、直接指定した単語が入っていなくても、それらの単語との類似度が高ければ、判定に使うことができるのです。
なお、これはアプリケーションの一例でしかないので、随時、好きなように工夫してください。他、今回は口コミのデータ数が少ないので、限定的な判定しかできませんが、もっとたくさんの口コミを入れてw2vを学習させることで、もっと色々なことができるようになるでしょうね。興味のある方は、ぜひ取り組んでください。