山本昌投手と各球団の関係をjanomeとTF-IDF Cosine Similarityで類似度ソートする

PyCon2015で紹介されたjanome便利ですね。今年引退した名投手山本昌選手と各球団との関係をwikipediaの文章で類似度ソートしていきたいと思います。

# 今回やること
wikipediaの文章から形態素解析器janome使って日本語の名詞を抽出し、TF-IDFで特徴ベクトルを抽出。各記事の特徴ベクトルで内積してcosθを取れば、0〜1の範囲でのエントリの類似度が取得できます。文章の類似度で記事をソートすれば完了です。

# janomeが便利なところ
mecabのインストールはpythonのバージョンへの依存性や辞書追加インストールが必要で、構築がとにかく手間です。pipでインストールできるjanomeは便利。形態素解析が必要になったとき手軽に挑戦できます。

# janomeを使ってみる

```py
pip install janome
from janome.tokenizer import Tokenizer
t = Tokenizer()
text = """
広島時代入団後の2年間は芽が出ず、年下の前田智徳や江藤智らに追い抜かれ
打撃は当時のコーチから「転がして足を活かせ」と言われるほど非力で
外野守備も送球を地面に向かって投げてしまう悪癖から「モグラ殺し」のあだ名を付けられるなど...
"""
for token in t.tokenize(text):
     print(token)

------------------
広島	名詞,固有名詞,地域,一般,*,*,広島,ヒロシマ,ヒロシマ
時代	名詞,一般,*,*,*,*,時代,ジダイ,ジダイ
入団	名詞,サ変接続,*,*,*,*,入団,ニュウダン,ニューダン
後	名詞,接尾,副詞可能,*,*,*,後,ゴ,ゴ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
2	名詞,数,*,*,*,*,*,*,*
年間	名詞,接尾,助数詞,*,*,*,年間,ネンカン,ネンカン
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
芽	名詞,一般,*,*,*,*,芽,メ,メ
が	助詞,格助詞,一般,*,*,*,が,ガ,ガ
出	動詞,自立,*,*,一段,未然形,出る,デ,デ
ず	助動詞,*,*,*,特殊・ヌ,連用ニ接続,ぬ,ズ,ズ
、	記号,読点,*,*,*,*,、,、,、
年下	名詞,一般,*,*,*,*,年下,トシシタ,トシシタ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
前田	名詞,固有名詞,人名,姓,*,*,前田,マエダ,マエダ
智徳	名詞,固有名詞,人名,名,*,*,智徳,トモノリ,トモノリ
や	助詞,並立助詞,*,*,*,*,や,ヤ,ヤ
江藤	名詞,固有名詞,人名,姓,*,*,江藤,エトウ,エトー
智	名詞,固有名詞,人名,名,*,*,智,サトシ,サトシ
ら	名詞,接尾,一般,*,*,*,ら,ラ,ラ
に	助詞,格助詞,一般,*,*,*,に,ニ,ニ
追い抜か	動詞,自立,*,*,五段・カ行イ音便,未然形,追い抜く,オイヌカ,オイヌカ
...

```

# TF-IDF とは
文章中の名詞の数をカウントしたら、文章の特徴ベクトルが取得できるよねって考え方です。日本語は英語と違い区切りにwhite spaceがありませんから、形態素解析が必要です。つまり形態素解析器のjanomeの出番な訳です。

TF-IDF = 文章中の特定名詞の数 / 文章中の全ての名詞の数


# 実際にやってみよう
```py:例文
肉フェスNIIGATAで肉三昧の夜ごはん❤︎ステーキハウスあづまさんの雪室熟成新潟県産牛ステーキおいしい*\(^o^)/*お塩でもワサビでもぴったり！
```

```py:結果
from simple_tfidf_japanese.tfidf import TFIDF
text = "肉フェスNIIGATAで肉三昧の夜ごはん❤︎ステーキハウスあづまさんの雪室熟成新潟県産牛ステーキおいしい*\(^o^)/*お塩でもワサビでもぴったり！"
result = TFIDF.gen(text, enable_one_char=1)
for key, value in result:
     print key, value

肉 0.0952380952381
ステーキ 0.0952380952381
お 0.047619047619
ごはん 0.047619047619
雪 0.047619047619
新潟 0.047619047619
熟成 0.047619047619
塩 0.047619047619
フェス 0.047619047619
あづま 0.047619047619
ワサビ 0.047619047619
牛 0.047619047619
ハウス 0.047619047619
夜 0.047619047619
三昧 0.047619047619
```
お肉いいですね〜!こちらの文章は肉、ステーキ、ご飯が一番の特徴みたいです。



# 山本昌投手と各球団の類似度を抽出してみよう
作ったツールをPyPiに登録しておきました。

```py
pip install simple_tfidf_japanese
```

wikipediaのページをベースとして昌と各球団との関係性を比較してみます。試験用として全く関係ないサッカーの記事も混ぜておきます。

```py
from simple_tfidf_japanese.tfidf import TFIDF

# 山本昌
_base_url = "https://ja.wikipedia.org/wiki/%E5%B1%B1%E6%9C%AC%E6%98%8C"

# 比較対象
data = [
     ['ヤクルト', 'https://ja.wikipedia.org/wiki/%E6%9D%B1%E4%BA%AC%E3%83%A4%E3%82%AF%E3%83%AB%E3%83%88%E3%82%B9%E3%83%AF%E3%83%AD%E3%83%BC%E3%82%BA'],
     ['巨人', 'https://ja.wikipedia.org/wiki/%E8%AA%AD%E5%A3%B2%E3%82%B8%E3%83%A3%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%84'],
     ['阪神', 'https://ja.wikipedia.org/wiki/%E9%98%AA%E7%A5%9E%E3%82%BF%E3%82%A4%E3%82%AC%E3%83%BC%E3%82%B9'],
     ['広島', 'https://ja.wikipedia.org/wiki/%E5%BA%83%E5%B3%B6%E6%9D%B1%E6%B4%8B%E3%82%AB%E3%83%BC%E3%83%97'],
     ['中日', 'https://ja.wikipedia.org/wiki/%E4%B8%AD%E6%97%A5%E3%83%89%E3%83%A9%E3%82%B4%E3%83%B3%E3%82%BA'],
     ['横浜', 'https://ja.wikipedia.org/wiki/%E6%A8%AA%E6%B5%9CDeNA%E3%83%99%E3%82%A4%E3%82%B9%E3%82%BF%E3%83%BC%E3%82%BA'],
     ['ソフバン', 'https://ja.wikipedia.org/wiki/%E7%A6%8F%E5%B2%A1%E3%82%BD%E3%83%95%E3%83%88%E3%83%90%E3%83%B3%E3%82%AF%E3%83%9B%E3%83%BC%E3%82%AF%E3%82%B9'],
     ['日ハム', 'https://ja.wikipedia.org/wiki/%E5%8C%97%E6%B5%B7%E9%81%93%E6%97%A5%E6%9C%AC%E3%83%8F%E3%83%A0%E3%83%95%E3%82%A1%E3%82%A4%E3%82%BF%E3%83%BC%E3%82%BA'],
     ['ロッテ', 'https://ja.wikipedia.org/wiki/%E5%8D%83%E8%91%89%E3%83%AD%E3%83%83%E3%83%86%E3%83%9E%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%BA'],
     ['西武', 'https://ja.wikipedia.org/wiki/%E5%9F%BC%E7%8E%89%E8%A5%BF%E6%AD%A6%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%B3%E3%82%BA'],
     ['オリックス', 'https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%AA%E3%83%83%E3%82%AF%E3%82%B9%E3%83%BB%E3%83%90%E3%83%95%E3%82%A1%E3%83%AD%E3%83%BC%E3%82%BA'],
     ['楽天', 'https://ja.wikipedia.org/wiki/%E6%9D%B1%E5%8C%97%E6%A5%BD%E5%A4%A9%E3%82%B4%E3%83%BC%E3%83%AB%E3%83%87%E3%83%B3%E3%82%A4%E3%83%BC%E3%82%B0%E3%83%AB%E3%82%B9'],
     ['サッカー日本代表', 'https://ja.wikipedia.org/wiki/%E3%82%B5%E3%83%83%E3%82%AB%E3%83%BC%E6%97%A5%E6%9C%AC%E4%BB%A3%E8%A1%A8'],
]

# 計算
result = TFIDF.some_similarity(_base_url, data)

# 結果表示
result.sord(key=lambda x: x[2], reverse=True)
for title, url, value in result:
     print title, value

"""
巨人 0.437053886215
ヤクルト 0.399745780763
阪神 0.383247816027
広島 0.356147904333
ロッテ 0.351312791912
中日 0.344772305253
横浜 0.334360056622
日ハム 0.326226324436
オリックス 0.317250711462
ソフバン 0.285703674673
西武 0.283181229507
楽天 0.275111280558
サッカー日本代表 0.177026402257
"""

```
全体で俯瞰するとセが類似度上位、パが下位、まったく関係ないサッカーは最低の類似度となっています。
30年以上中日ドラゴンズ一筋の山本投手ですが、意外にも中日ではなく巨人との関連が一位となっています。
WikiPediaにも巨人との対戦の話が多く、巨人との類似度が上昇したものと思われます。

また広島が中日より上位にきているのはミスター赤ヘルの山本浩二監督に関する記述が多いため
山本繋がりで上位になったものと推察できます。中日よりヤクルト、阪神、ロッテが上位に来ている理由は、『記録, 勝利, 野球, プロ, 選手』のワードの出現数によって変動してしまった模様です。

# simple_tfidf_japaneseの使い方
simple_tfidf_japaneseはアルファベットは全てノイズとして排除する日本語専用のTFIDF計算モジュールです。

```py
# 文章からtfidfを出力(Get TF-IDF from text)
from simple_tfidf_japanese.tfidf import TFIDF
text = "肉フェスNIIGATAで肉三昧の夜ごはん❤︎ステーキハウスあづまさんの雪室熟成新潟県産牛ステーキおいしい*\(^o^)/*お塩でもワサビでもぴったり！"
tfidf1 = TFIDF.gen(text, enable_one_char=1)
for key, value in tfidf1:
     print key, value

>>> 肉 0.0952380952381
>>> ステーキ 0.0952380952381
>>> お 0.047619047619
>>> ごはん 0.047619047619
>>> 雪 0.047619047619
>>> 新潟 0.047619047619
>>> 熟成 0.047619047619
...

# Webからtfidfを出力(Get TF-IDF from Web)
url = "https://ja.wikipedia.org/wiki/%E6%B7%A1%E8%B7%AF%E3%83%93%E3%83%BC%E3%83%95"
tfidf2 = TFIDF.gen_web(url)
for key, value in tfidf2:
     print key, value

>>> 淡路 0.0453257790368
>>> ビーフ 0.0396600566572
>>> 但馬 0.0198300283286
>>> 淡路島 0.0169971671388
>>> ページ 0.0169971671388
>>> 表示 0.014164305949

# TF-IDF Cosine Similarityで類似度を計算(calc TF-IDF Cosine Similarity)
tfidf1 = [['Apple', 1], ['Orange', 2], ['Banana', 1], ['Kiwi', 0]]
tfidf2 = [['Apple', 1], ['Orange', 0], ['Banana', 2], ['Kiwi', 1]]
print TFIDF.similarity(tfidf1, tfidf2)
>>> 0.5

```


# janomeについてもっと知りたい
作った人がPyCon2015で発表したスライドを読みましょう！
[Python で作って学ぶ形態素解析のスライド](https://techstars.jp/blog/pycon15-1/#202)

# TF-IDF Cosine Similarityについて詳しく知りたい
Qiita: [TF-IDF Cos類似度推定法](http://qiita.com/nmbakfm/items/6bb91b89571dd68fcea6)