nikkie-ftnextの日記

イベントレポートや読書メモを発信

イベントレポート | #pyhack にて旦那と彼氏の間に何があるのかをword2vecに聞いてみました

はじめに

いつも心は虹色に! nikkieです。
4/6開催 (第98回)Python mini Hack-a-thon のイベントレポートをお送りします。

注:書かれている感想や考えは4月時点のものです。

勉強会の概要

(第98回)Python mini Hack-a-thon - connpass

基本的に毎月開催です。スプリントのゆるい版みたいな感じで各自自分でやりたいことを持ってきて、勝手に開発を進めています。参加費は無料です。 初めての方も常連さんもぜひご参加ください。

2月回以来の参加となりました。
(3月はstapy長野とブッキング)

取り組んだこと

word2vec入門!

今年はじめに どうしたら「彼女」から「奥さん」になれるかを『Word2Vec』に聞いてみた | 人工知能ニュースメディア AINOW を見て以来、ずっと気になっていたword2vecを触ってみました。

知りたいこと:旦那と彼氏の間に何があるのか?(旦那 - 彼氏)

以下を使って答えを求めてみます:

notebookはこちら:
word2vecで彼氏と旦那の間に何があるのか聞いてみる ライブドアニュースコーパス編 #pyhack 20190406 · GitHub

word2vecとは

単語がベクトルとして表現されるので、単語の足し引きができるようになると理解しています。

f:id:nikkie-ftnext:20190406163345p:plain

よくある例

  • 王様 - 男 + 女 → 女王1
  • 日本 - 東京 + ソウル → 韓国2

詳しくは勉強中です。

コーパス

以下のリンクからダウンロードした「livedoor ニュースコーパス」を使いました。3
https://www.rondhuit.com/download.html

ダウンロードしたtar.gzの解凍:tar -zxvf ldcc-20140209.tar.gz
-vもつけると、解凍したフォルダ・ファイル名がコマンドラインに表示されます)

.
├── ldcc-20140209.tar.gz
└── text
    ├── CHANGES.txt
    ├── README.txt
    ├── dokujo-tsushin
    ├── it-life-hack
    ├── kaden-channel
    ├── livedoor-homme
    ├── movie-enter
    ├── peachy
    ├── smax
    ├── sports-watch
    └── topic-news

形態素解析

Keras MLPの文章カテゴリー分類を日本語のデータセットでやってみる | cedro-blog と同様にjanomeで実施しました。

from janome.tokenizer import Tokenizer
ja_tokenizer=Tokenizer()
line = 'すもももももももものうち'
words = ja_tokenizer.tokenize(line)
for word in words:
    print(word)
すもも 名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も 助詞,係助詞,*,*,*,*,も,モ,モ
もも  名詞,一般,*,*,*,*,もも,モモ,モモ
も 助詞,係助詞,*,*,*,*,も,モ,モ
もも  名詞,一般,*,*,*,*,もも,モモ,モモ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
うち  名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ

今回は名詞だけを取り出すことにします。

res = []
malist=ja_tokenizer.tokenize(line)
for tok in malist:
    ps=tok.part_of_speech.split(",")[0]
    if not ps in ['名詞']: continue
    w=tok.base_form
    if w=="*" or w=="": w=tok.surface
    if w=="" or w=="\n": continue
    res.append(w)
res.append("\n")
print(res)
# ['すもも', 'もも', 'もも', 'うち', '\n']

取り出した名詞は半角スペースで区切って並べ、テキストファイルに書き出します。
ライブドアニュースのテキストファイルと同じだけ、名詞を取り出したファイルができます。)
名詞で構成されたテキストファイルはtextと同じ階層にwakatiフォルダを作って配置します。

.
├── ldcc-20140209.tar.gz
├── text
│   ├── CHANGES.txt
│   ├── README.txt
│   ├── dokujo-tsushin
│   ├── it-life-hack
│   ├── kaden-channel
│   ├── livedoor-homme
│   ├── movie-enter
│   ├── peachy
│   ├── smax
│   ├── sports-watch
│   └── topic-news
└── wakati
    ├── dokujo-tsushin
    ├── it-life-hack
    ├── kaden-channel
    ├── livedoor-homme
    ├── movie-enter
    ├── peachy
    ├── smax
    ├── sports-watch
    └── topic-news

名詞を取り出す処理は10分くらいかかりました(1万には満たないファイル数です)。4

モデル作成

word2vecのモデルを作る上で、ライブドアニュースから取り出した名詞を1つのファイルに集約する必要がありました。 (gensim.models.word2vec.Text8Corpusに渡すファイルを作る)
以下の記事のシェルスクリプトを利用させていただきました🙏: 【Python】Word2Vecの使い方 - Qiita

find wakati \
| grep -e movie-enter -e it-life-hack -e kaden-channel \
    -e topic-news -e livedoor-homme -e peachy -e sports-watch \
    -e dokujo-tsushin -e smax \
| awk '{system("cat "$0" >> livedoor_wakati.txt")}'

複数のフォルダから集約する必要があったので、grep-eオプション5を使い、「または」検索しました。

彼氏 - 旦那 = ?

足し引きのやり方は、以下の記事を参考にしました:
【Python】🍜ラーメンガチ勢によるガチ勢のためのWord2vec(食べログ口コミコーパスの威力を検証してみた)🍜 - Qiita
引き算はnagetiveに指定すると理解しました(ドキュメントの確認は宿題事項)。

旦那と彼氏の間にあるものは、「農家、土地、畑」か〜😳

他の方の取り組みから

感想

気になっていた記事の内容を試せたので満足です。
複数カテゴリの記事を渡していたり、名詞だけに限定していたりと工夫できそうなポイントがあるので、今後確認したいと思います。

  • janomeは初期設定がMeCabより少なく6、使いやすいですね(MeCabの経験と比較して)
  • ファイルの集約に使ったシェルスクリプト便利ですね。「awkでやっていることって何?」って感じなので早々に調べます
  • ファイルパスの扱いでos.pathの代わりにpathlibを使ったところ、なかなかいい感じです