彼氏から旦那になる方法をWord2Vecに聞いてみた
■背景
研究で自然言語処理で有名なAttentionの技術を使おうと思い,名著であるゼロから作るDeep Learning 2を勉強していました.そこで,Word2Vecという言葉をベクトルとして扱い,それをニューラルネット(以下NN)を使って推論する技術に出会いました.なんか活用方法が面白そうだったのでggっていたら,"どうしたら「彼女」から「奥さん」になれるかを『Word2Vec』に聞いてみた"というとてもおもしろそうな記事と出会いました.ちょうど偶々実家に返った際デキ婚で結婚し,2歳の子供と幸せに暮らす友人に出会ったのも相まり,実装したくなりました.
■流れ
流れは前述した記事を参考にしました.
①まずは文章データをweb上からスクレイピングで集め,
②コンピューターが扱えるように,形態要素解析を行い,
③最後にword2vecで学習を書けるといった流れです.
細かい理論は名著を読んでいただければ分かるので割愛します(書くのがめんどくさい)
1.文章データのスクレイピング
恋愛関係のことは発言小町というサイトに聞けば良いらしいので,このサイトからスクレイピングしてきました.PythonのHTMLやXMLからデータを取得することのできるライブラリ「Beautiful Soup4」を使いました.正直,自分はpythonしかできないのでhtmlなどがよく分からずここで一番苦労しました.参考にコードを挙げておきます.
大きな流れとしては,発言小町の恋愛のページに全部で50個の記事があるので,そのタイトルとurlを取得し,各記事に飛んで,そのテキストをすべてスクレイピングしてくる流れです.
BeautifulSoupの使い方は以下の2つの記事が分かりやすかったです.
#①発言小町からwebスクレイピング
import requests
from bs4 import BeautifulSoup
basic_url = "https://komachi.yomiuri.co.jp"
survey_text = ""
url = "https://komachi.yomiuri.co.jp/topics/genre/love/ranking/"
res = requests.get(url)
content = res.content #HTMLの中身が文字列で
#HTMLをBeautifulSoupにわたす
soup = BeautifulSoup(content, "html.parser")
titles = soup.find_all("a", class_ = "p-topiList__itemLink")
#各タイトルに飛んで,文章データを得る
for title in titles:
url = title.get("href")
res = requests.get(basic_url+url)
#print(basic_url+url)
content = res.content
soup = BeautifulSoup(content, "html.parser")
for el in soup.find_all("div", class_ = "topicsId__articleContentText"):
#print(el.text+"\n")
survey_text += el.text
survey_text += "\n"
for el in soup.find_all("div", class_ = "p-resList__itemContent"):
#print(el.text+"\n")
survey_text += el.text
survey_text += "\n"
#print("------------------\n")
survey_text += "------------------\n"
2.Mecabを使って,分かち書きをする
Mecabの使い方・セットアップの仕方については色々な方々が記事を書いているのでそれを参考にしました.
以下のコードで文章を分かち書きでき,コンピューターが使えるようにできます.
import sys
import MeCab
mecab = MeCab.Tagger ("-Owakati")
text = mecab.parse(survey_text)
file_name = "survey.txt"
with open(file_name,"w") as f:
f.write(text)
3.Word2Vecを使って学習+推論を行う
記事に習い,gensimというライブラリを使って,word2vecを実装しました.使い方は以下のサイトを参考にさせていただきました.
from gensim.models import word2vec
import logging
#logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = word2vec.Text8Corpus('survey.txt')
model = word2vec.Word2Vec(sentences, vector_size=200, min_count=20, window=15)
model.wv.save_word2vec_format("survey.vec.pt", binary=True)
#print(model.wv.most_similar("奥さん", topn=5))
print("--------------------\n")
print("「旦那」ー「彼氏」 = ")
result = model.wv.most_similar(positive=["旦那"], negative=["彼氏"], topn=10)
for i in range(len(result)):
print(i+1, result[i])
print(model.wv.vectors)
たったこれだけで,言葉のベクトル表現を学習でき,言葉の関連について推論できます.果たして推論結果は・・・・
一位が「迷惑」,2位が「お金」といった大変ネガティブな結果となりましたwwwww
これは学習データが夫の不満を言う記事が多かったからでしょうね....
学習データに偏りがあると,こんな結果になるよといったいい記事になりそうです.
ちなみに,「奥さん」ー「彼女」の一位は指輪でした.結婚したくなったら指輪を用意しましょう.