自然言語研修 (3)反対語
■ GoogleDriveのマウントコマンド:
from google.colab import drive
drive.mount('/content/drive')
Mounted at /content/drive
■ モデルファイルのダウンロード:
# GoogleDriveフォルダに作成する
!mkdir -p /content/drive/MyDrive/KITERETU
# Word2Vecの学習済みモデルをダウンロード
!curl -o /content/drive/MyDrive/KITERETU/gw2v160.model https://storage.googleapis.com/nlp_youwht/w2v/gw2v160.model
!curl -o /content/drive/MyDrive/KITERETU/gw2v160.model.trainables.syn1neg.npy https://storage.googleapis.com/nlp_youwht/w2v/gw2v160.model.trainables.syn1neg.npy
!curl -o /content/drive/MyDrive/KITERETU/gw2v160.model.wv.vectors.npy https://storage.googleapis.com/nlp_youwht/w2v/gw2v160.model.wv.vectors.npy
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 19.1M 100 19.1M 0 0 16.2M 0 0:00:01 0:00:01 --:--:-- 16.2M % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 179M 100 179M 0 0 28.4M 0 0:00:06 0:00:06 --:--:-- 43.5M % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 179M 100 179M 0 0 31.4M 0 0:00:05 0:00:05 --:--:-- 31.4M
■ コアラの反対側の単語の確認:
from gensim.models.word2vec import Word2Vec
# 学習済みモデルのロード
model_file_path = '/content/drive/MyDrive/KITERETU/gw2v160.model'
model = Word2Vec.load(model_file_path)
# 「似ている」の場合はpositiveであったことを思い出す
# out = model.wv.most_similar(positive=[u'群馬'], topn=7)
# 「反対の意味」としてnegativeだけを入れてみる
out = model.wv.most_similar(negative=[u"コアラ"], topn=7)
print(out)
[('勘文', 0.4315894544124603), ('要諦', 0.3936310410499573), ('徳政', 0.37152087688446045), ('綱紀', 0.36845099925994873), ('権威者', 0.35816508531570435), ('請文', 0.3445848822593689), ('理非', 0.34137365221977234)]
■ コアラの賛成の反対?反対の賛成?:
out = model.wv.most_similar(positive=[u"コアラ", u"反対"], negative=[u"賛成"], topn=5)
print(out)
out = model.wv.most_similar(positive=[u"コアラ", u"賛成"], negative=[u"反対"], topn=5)
print(out)
[('カンガルー', 0.5650547742843628), ('ウォンバット', 0.5431149005889893), ('ライオン', 0.5078734159469604), ('タロンガ', 0.5016540288925171), ('ゴリラ', 0.49797317385673523)] [('ウォンバット', 0.5293771028518677), ('ワラビー', 0.519114077091217), ('洗い熊', 0.5170611143112183), ('背黄青', 0.48218613862991333), ('レッサーパンダ', 0.4773913025856018)]
■ 対義語リストのダウンロード:
# 対義語リストファイルのダウンロード:
!curl -o /content/drive/MyDrive/KITERETU/taigigolist.csv https://storage.googleapis.com/nlp_youwht/taigigo/taigigolist.csv
# 冒頭部分を眺めてみる
!head "/content/drive/MyDrive/KITERETU/taigigolist.csv"
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 8554 100 8554 0 0 22160 0 --:--:-- --:--:-- --:--:-- 22160 アウト,セーフ アクセル,ブレーキ おしゃべり,無口 セーフ,アウト ふもと,頂上 ブレーキ,アクセル 悪,善 悪い,良い 悪意,善意 悪質,良質
■ 対義語一覧ファイルの読み込み:
import csv
# 対義語一覧ファイルの読み込み
csv_file = open("/content/drive/MyDrive/KITERETU/taigigolist.csv", "r", encoding="utf8")
# CSVファイルをリスト形式で読み出す
csv_reader = csv.reader(csv_file, delimiter=",")
# csv_readerで1行ずつ読みこまれたデータをリスト形式にする処理
TAIGIGO_LIST = [ e for e in csv_reader ]
# 読み終わったCSVファイルを閉じる
csv_file.close()
# 読み込んだリストの長さを表示
print(len(TAIGIGO_LIST))
# 最初の数例を表示
print(TAIGIGO_LIST[0:5])
568 [['アウト', 'セーフ'], ['アクセル', 'ブレーキ'], ['おしゃべり', '無口'], ['セーフ', 'アウト'], ['ふもと', '頂上']]
■ コアラとの類似度を求める例:
print(model.wv.similarity("コアラ", "賛成"))
print(model.wv.similarity("コアラ", "セーフ"))
print(model.wv.similarity("コアラ", "コアラ"))
-0.11382347 0.044115696 1.0
■ 注意したい例=存在しない単語での演算:
model.wv.similarity("コアラ", "ぱんだ")
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-8-cfe0cc5793e8> in <module>() ----> 1 model.wv.similarity("コアラ", "ぱんだ") /usr/local/lib/python3.7/dist-packages/gensim/models/keyedvectors.py in similarity(self, w1, w2) 990 991 """ --> 992 return dot(matutils.unitvec(self[w1]), matutils.unitvec(self[w2])) 993 994 def n_similarity(self, ws1, ws2): /usr/local/lib/python3.7/dist-packages/gensim/models/keyedvectors.py in __getitem__(self, entities) 335 if isinstance(entities, string_types): 336 # allow calls like trained_model['office'], as a shorthand for trained_model[['office']] --> 337 return self.get_vector(entities) 338 339 return vstack([self.get_vector(entity) for entity in entities]) /usr/local/lib/python3.7/dist-packages/gensim/models/keyedvectors.py in get_vector(self, word) 453 454 def get_vector(self, word): --> 455 return self.word_vec(word) 456 457 def words_closer_than(self, w1, w2): /usr/local/lib/python3.7/dist-packages/gensim/models/keyedvectors.py in word_vec(self, word, use_norm) 450 return result 451 else: --> 452 raise KeyError("word '%s' not in vocabulary" % word) 453 454 def get_vector(self, word): KeyError: "word 'ぱんだ' not in vocabulary"
■ 「ぱんだ」と「パンダ」のいるいないを確認する:
if "ぱんだ" in model.wv.vocab.keys():
print("YES!「ぱんだ」はいますよ")
else:
print("NO!「ぱんだ」はいません")
if "パンダ" in model.wv.vocab.keys():
print("YES!「パンダ」はいますよ")
else:
print("NO!「パンダ」はいません")
NO!「ぱんだ」はいません YES!「パンダ」はいますよ
■ 対義語リストと、対象の単語との類似度を出す関数:
def add_similarity_to_taigigo_list(target_word, taigigo_list):
result_list = []
# taigigo_list の各要素は、["賛成","反対"]などの形式であり、
# リストの各要素がリストである二重リスト
for taigigo_pair in taigigo_list:
try:
# 「賛成」と「コアラ」、「反対」と「コアラ」などそれぞれの類似度を得る
sim0 = model.wv.similarity(taigigo_pair[0], target_word)
sim1 = model.wv.similarity(taigigo_pair[1], target_word)
# 結果格納用のリストに、元の各単語、各類似度、を格納する
result_list.append( [taigigo_pair[0], taigigo_pair[1], sim0, sim1] )
except KeyError:
# ある対義語ペアの、どちらかの単語がKeyErrorの場合、何もしないでスキップ
# または、元の入力単語がKeyErrorの場合も、何もしないでスキップ
pass
# 生成された二重リストを返却する。各要素は以下のような形式
# ["賛成", "反対", "賛成とコアラの類似度", "反対とコアラの類似度"]
return result_list
# コアラと、対義語リストの全単語の類似度を求める。
KOARA_TAIGIGO_SIM_LIST = add_similarity_to_taigigo_list(u"コアラ",TAIGIGO_LIST)
# 最初の5つを表示する
print( KOARA_TAIGIGO_SIM_LIST[0:5])
[['アウト', 'セーフ', 0.090600915, 0.044115696], ['アクセル', 'ブレーキ', -0.033691376, -0.11518881], ['セーフ', 'アウト', 0.044115696, 0.090600915], ['ブレーキ', 'アクセル', -0.11518881, -0.033691376], ['悪', '善', 0.03668707, -0.086812906]]
■ 結局誰が一番「コアラ」に似ているのか?並び替え:
KOARA_TAIGIGO_SIM_LIST.sort(key = lambda x : -x[2])
# 最初の5つを表示する
print( KOARA_TAIGIGO_SIM_LIST[0:5])
[['満腹', '空腹', 0.2346971, 0.19706017], ['本物', '偽物', 0.22309045, 0.1399938], ['男性', '女性', 0.2089082, 0.19897342], ['販売', '購入', 0.20580953, 0.1399232], ['売る', '買う', 0.20547116, 0.057075344]]
■ コアラと似ている「満腹」との対義語演算:
out = model.wv.most_similar(positive=[u"コアラ", u"満腹"], negative=[u"空腹"], topn=5)
print(out)
out = model.wv.most_similar(positive=[u"コアラ", u"空腹"], negative=[u"満腹"], topn=5)
print(out)
[('ミッフィー', 0.5394263863563538), ('ウォンバット', 0.5337938666343689), ('パンダ', 0.5278213620185852), ('ウーパールーパー', 0.5196086168289185), ('白熊', 0.4782952070236206)] [('プレーリードッグ', 0.5548356771469116), ('縞馬', 0.5465219616889954), ('アメリカグマ', 0.5432994961738586), ('カンガルー', 0.5380684733390808), ('園側', 0.5326305031776428)]
■ 単語を対義語にする関数:
def make_taigigo_kouho_list(target_word, taigigo_list):
taigigo_sim_list = add_similarity_to_taigigo_list(target_word, taigigo_list)
# 3番目の要素をキーにして、元のリストの順番を「降順」に並び替える
taigigo_sim_list.sort(key = lambda x : -x[2])
# 結果出力用のリストを初期化
result_list = []
# 並び替えた一位のペア([0])の、対義語ペアの各単語を使用する
word0 = taigigo_sim_list[0][0]
word1 = taigigo_sim_list[0][1]
# 対義語の候補リストを生成し、出力結果に書き加える
result_list.extend(model.wv.most_similar(positive=[target_word, word0], negative=[word1], topn=5))
result_list.extend(model.wv.most_similar(positive=[target_word, word1], negative=[word0], topn=5))
return result_list
make_taigigo_kouho_list(u"コアラ", TAIGIGO_LIST)
[('ミッフィー', 0.5394263863563538), ('ウォンバット', 0.5337938666343689), ('パンダ', 0.5278213620185852), ('ウーパールーパー', 0.5196086168289185), ('白熊', 0.4782952070236206), ('プレーリードッグ', 0.5548356771469116), ('縞馬', 0.5465219616889954), ('アメリカグマ', 0.5432994961738586), ('カンガルー', 0.5380684733390808), ('園側', 0.5326305031776428)]
■ パンダの対義語をランダムに出力:
import random
def word2taigigo(input_word):
# Word2Vecのmodelにその単語が含まれているか確認して含まれていれば処理を行う
if input_word in model.wv.vocab.keys():
taigigo_kouho_list = make_taigigo_kouho_list(input_word, TAIGIGO_LIST)
if len(taigigo_kouho_list) > 0 :
# 対義語の候補が複数出ている場合、その中からランダムで選択。
taigigo_kouho = random.choice(taigigo_kouho_list)
# taigigo_kouhoは、('プレーリードッグ', 0.5548356771469116) の形なので
# その最初の要素、[0]に単語自体が含まれており、それを返す
return taigigo_kouho[0]
# 単語が含まれていなかったり、生成できない場合は元の単語を返す
return input_word
# 乱数によって結果が変わるため、数回繰り返してみる
for n in range(5):
print(word2taigigo("パンダ"))
ジャイアントパンダ くま にゃん 縫い包み にゃん
■ Janomeのインストール:
!pip install janome
Collecting janome Downloading Janome-0.4.2-py2.py3-none-any.whl (19.7 MB) |████████████████████████████████| 19.7 MB 1.4 MB/s Installing collected packages: janome Successfully installed janome-0.4.2
■ 文章対義語化関数:
# Janomeのロード
from janome.tokenizer import Tokenizer
# Tokenizerインスタンスの生成
tokenizer = Tokenizer()
# 日本語を対義語にする関数
def taigi_str_henkan(input_str):
# 形態素解析の実施
tokens = tokenizer.tokenize(input_str)
# 各tokenを、対義語変換関数にかけて、その出力を順番につなげる
result_str = ""
for token in tokens:
# 名詞か形容詞の場合のみ、変換処理を行うことにする
if token.part_of_speech.split(',')[0] in ['名詞', '形容詞']:
# 入力された単語を対義語に変換
taigigo = word2taigigo(token.surface)
result_str += taigigo
else:
# 変換対象ではない品詞の場合、そのままつなげる
result_str += token.surface
return result_str
# ランダム要素が大きいので、5回出力させてみる
for n in range(5):
print(taigi_str_henkan("赤の他人"))
青の自分 赤いの他者 黄色の自分 青の自分 butaの他者