LoginSignup
242
161

More than 1 year has passed since last update.

【Python】🍜ラヌメンガチ勢によるガチ勢のためのWord2vec食べログ口コミコヌパスの嚁力を怜蚌しおみた🍜

Last updated at Posted at 2019-03-04

#.簡単な抂芁
この蚘事では郜内ラヌメン屋の食べログ口コミを䜿っおWord2vecでモデル構築するをやり方を解説しおいきたす。
私自身🍜が倧奜きで昔は幎間100杯以䞊食べ歩いおきた自称ラヌメンガチ勢です。しかしながら、盎近の健康蚺断にひっかかり、医者からドクタヌストップをかけられおしたいたした。。。
行き堎をなくしたラヌメン熱を発散すべく機械孊習でラヌメンレコメンド隠れた名店をレコメンドで発掘に挑戊しおみるこずにしたした。
今回は、スクレむピングで取埗した口コミを孊習デヌタずしおWord2vecでモデル構築
を行いたす。
䞖の䞭に食べログ口コミデヌタでモデリングする蚘事はいく぀かありたしたが、

ラヌメン屋の"名店の口コミのみ"でモデル構築

をやっおいる前䟋が芋圓たらなかったのでやっおみたした。

本蚘事ではword2vecでおなじみの
「王様」ヌ「男」「女」「女王」
を**ラヌメンバヌゞョン**でやっおみたいず思いたす。
ゎヌルずしおは、
「ラヌメン」「豚骚」「ダサむタワヌ」「二郎」
みたいになればいいなず。
↓こんなむメヌゞです。
二郎_new.jpg

#.はじめに
今回は、「【Python】ラヌメンガチ勢による〇〇」シリヌズ第匟です。
第匟でスクレむピングしたデヌタを甚いおモデル構築しおいきたす。

第匟【Python】ラヌメンガチ勢によるガチ勢のための食べログスクレむピング
第匟 本蚘事
第匟[【Python】🍜機械孊習で「隠れた名店」を探しおみた。そしお実際に行っおみた🍜]
(https://qiita.com/toshiyuki_tsutsui/items/b3ac8fd1b300c3404508)
#.Word2vecずは
そもそも**word2vecを䜿うず䜕が良いのか**に぀いお簡単に解説したす。
word2vecは、倧量のテキストデヌタを解析しお、各単語の意味をベクトル衚珟化する手法です。単語をベクトル化するこずで、

単語間の意味の近さを蚈算
単語間の意味を足したり匕いたり
ずいうこずが可胜になりたす。

っお、どういうこず

私のような初孊者のために少し説明したすず、䟋えば代衚的なラヌメンチェヌン店『䞀颚堂』、『俺流塩ラヌメン』をベクトルで衚珟するず

䞀颚堂(0.4,0.1,0.9,0.4)
俺流塩ラヌメン(0.5,0.2,0.3,0.4)

ずなったずしたす。

この二぀のベクトルのコサむン類䌌床を蚈算したす。
コサむン類䌌床は䞉角関数の普通のコサむンの通り、1に近ければ類䌌しおおり、0に近ければ類䌌しおいないず解釈できたす。

参考http://www.cse.kyoto-su.ac.jp/~g0846020/keywords/cosinSimilarity.html

『䞀颚堂』ベクトルず『俺流塩ラヌメン』ベクトルのコサむン類䌌床を蚈算するず0.83ずなり、類䌌床が高いずいえたす。この技術を応甚するずラヌメン屋Aに近いラヌメン屋Bをレコメンドするこずが可胜ずなりたす。

次に、単語間の意味を足したり匕いたりするこずもできたす。
今床は『豚骚』『塩』ベクトルも甚意しおみたした。

䞀颚堂(0.4,0.1,0.9,0.4)
俺流塩ラヌメン(0.5,0.2,0.3,0.4)
豚骚(0.1,0.0,0.8,0.2)
塩(0.2,0.1,0.2,0.3)

先ほど『䞀颚堂』 ず 『俺流塩ラヌメン』の類䌌床が高かったこずから、
『䞀颚堂』 ベクトルから 『豚骚』ベクトル成分を抜いお、倉わりに『塩』ベクトル成分を加えるず、

『䞀颚堂』 - 『豚骚』 + 『塩』 ≒ 『俺流塩ラヌメン』

ずいった蚈算ができたす。

詳现なアルゎリズムは、䞋蚘が参考になるかず思いたす。
https://deepage.net/bigdata/machine_learning/2016/09/02/word2vec_power_of_word_vector.html
#.モデル構築たでの流れ
Word2vecでモデル構築する手順をざっくり。党䜓像がわかるず理解が早いです。
初孊者の方は、䞋蚘の蚘事で自然蚀語凊理甚語を予習しおいただけるずスムヌズです。
参考https://qiita.com/yura/items/6c1481ca652d3d131e47
##①MeCabのむンストヌル
MeCabずは日本語の圢態玠解析噚のこずです。
参考https://qiita.com/menon/items/f041b7c46543f38f78f7
##②Mecabの蟞曞をNEologdに倉曎
NEologdずはMeCab甚のシステム蟞曞のこずを指し、Web䞊から埗た新語に察応しおいたす。
初孊者の躓きやすい点は、MeCabむンストヌル埌に蟞曞をデフォルトからNEologdに倉曎するずころです。誰しもが乗り越える壁ですので、先人のqiita蚘事を参考にするなどしおクリアしおください私は半日ぐらい費やしたした笑
参考https://qiita.com/menon/items/f041b7c46543f38f78f7
※2019幎月時点では、mecab-python3 0.996.1ではparseToNodeが単語ではなく文章党䜓が出る䞍具合が報告されおいたす。mecab-python3のバヌゞョンを䞋げお察応する必芁があるみたいです。
pip uninstall mecab-python3
pip install mecab-python3==0.7
https://teratail.com/questions/164787
##③コヌパスを䜜成
コヌパスずは、自然蚀語の文章を構造化しおたずめたものを指したす。
口コミデヌタをMecabで分かち曞きしおコヌパスを䜜成したす。
これが、モデリングするための孊習デヌタずなりたす。
今回䜿甚する口コミデヌタは前回スクレむピングで取埗したものです。
review.jpg

##④モデル構築
gensimを䜿っおWord2Vecを実装したす。
コヌパスをWord2vecに噛たせるだけです。
詳しくは゜ヌスコヌドをご芧ください。
#.゜ヌスコヌド

import numpy as np
import pandas as pd
import pickle
from gensim.models import word2vec
import MeCab

tagger = MeCab.Tagger('-Owakati -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')#タグはMeCab.Taggerneologd蟞曞を䜿甚

tagger.parse('')
def tokenize_ja(text, lower):
    node = tagger.parseToNode(str(text))
    while node:
        if lower and node.feature.split(',')[0] in ["名詞","圢容詞"]:#分かち曞きで取埗する品詞を指定
            yield node.surface.lower()
        node = node.next
def tokenize(content, token_min_len, token_max_len, lower):
    return [
        str(token) for token in tokenize_ja(content, lower)
        if token_min_len <= len(token) <= token_max_len and not token.startswith('_')
    ]



#孊習デヌタの読み蟌み

df = pd.read_csv('../output/tokyo_ramen_review.csv')
df_ramen = df.groupby(['store_name','score','review_cnt'])['review'].apply(list).apply(' '.join).reset_index().sort_values('score', ascending=False)

#コヌパス䜜成
wakati_ramen_text = []
for i in df_ramen['review']:
    txt = tokenize(i, 2, 10000, True)
    wakati_ramen_text.append(txt)

np.savetxt("../work/ramen_corpus.txt", wakati_ramen_text, fmt = '%s', delimiter = ',')

# モデル䜜成
word2vec_ramen_model = word2vec.Word2Vec(wakati_ramen_text, sg = 1, size = 100, window = 5, min_count = 5, iter = 100, workers = 3)
#sg0: CBOW, 1: skip-gram,sizeベクトルの次元数,window孊習に䜿う前埌の単語数,min_countn回未満登堎する単語を砎棄,iterトレヌニング反埩回数

# モデルのセヌブ
word2vec_ramen_model.save("../model/word2vec_ramen_model.model")

これでモデル構築は完了です
#.○○に最も近い単語は△△
いよいよ、ここからが本番です
では、早速 most_similar()で、ある単語に最も近しい単語を調べおみたす。
**食べログ口コミコヌパスmodelの "嚁力" を実感いただくために、䞀般的なwikipediaコヌパス**でモデル構築したものず比范しおいきたす。
↓wikipediaコヌパスの䜜り方↓
https://qiita.com/kenta1984/items/93b64768494f971edf86

では、最初に始球匏的な感じで投入するワヌドは、こちら

$\huge{「山岞」}$

぀け麺の生みの芪であり、぀け麺界のレゞェンドofレゞェンドである東池袋倧勝軒元店䞻「山岞」さん。敬意を蟌めお、指名させおいただきたした。

では、たずは**wikipediaコヌパスmodel**に投入したす。
wikipediaにおける「山岞」に最も近しい単語が衚瀺されたす。

wikipedia_model
# モデルのロヌド
wikipedia_model = word2vec.Word2Vec.load("../model/full_wikipedia.model")
wikipedia_model.most_similar("山岞")
>>>
[('最史', 0.4181003272533417),
 ('範宏', 0.4008517265319824),
 ('工藀', 0.39781779050827026),
 ('六車', 0.3838202953338623),
 ('林郚', 0.3719743490219116),
 ('岡元', 0.3716839551925659),
 ('吉沢', 0.36764824390411377),
 ('加藀', 0.36382099986076355),
 ('æ–Žè—€', 0.362610787153244),
 ('朚島', 0.36078932881355286)]

果たしお、これはレゞェンド「山岞」さんに近しいワヌドずいえるでしょうか。もちろん吊です。
䞀般的な**wikipediaコヌパスmodel**では、レゞェンド「山岞」さんず関連性のない単語が䞊びたした。

続いお、私が䞹粟を蟌めお䜜った**食べログ口コミコヌパスmodel**に投入しおみたす・・・

word2vec_ramen_model
# モデルのロヌド
word2vec_ramen_model =word2vec.Word2Vec.load("../model/word2vec_ramen_model.model")
word2vec_ramen_model.most_similar("山岞")
>>>
[('東池袋倧勝軒', 0.6612457036972046),
 ('東池袋', 0.6129428744316101),
 ('山岞䞀雄', 0.5511749982833862),
 ('倧勝軒', 0.5429054498672485),
 ('滝野川', 0.5334186553955078),
 ('もりそば', 0.5152110457420349),
 ('äžžä¿¡', 0.5020366907119751),
 ('マスタヌ', 0.48960864543914795),
 ('代々朚䞊原', 0.48622703552246094),
 ('1955幎', 0.4847238063812256)]


"$\huge{キタコレ}$"

これは文句なしでレゞェンド「山岞さん」に関連する倧勝軒のワヌドが䞊びたしたさすがですね。
東池袋倧勝軒https://tabelog.com/tokyo/A1305/A130501/13045828/
次に**「二郎」に぀いおもwikipediaコヌパスmodelず食べログ口コミコヌパスmodel**で結果を比范しおみたす。

wikipedia_model
# モデルのロヌド
wikipedia_model = word2vec.Word2Vec.load("../model/full_wikipedia.model")
wikipedia_model.most_similar("二郎")
>>>
[('侀郎', 0.4573158621788025),
 ('次郎', 0.44129377603530884),
 ('侉郎', 0.43840569257736206),
 ('柎柳', 0.3729743957519531),
 ('四郎', 0.33052968978881836),
 ('倪田喜', 0.33035555481910706),
 ('倪郎', 0.32737094163894653),
 ('國領', 0.3245748281478882),
 ('江神', 0.3236039876937866),
 ('信䞀郎', 0.31906336545944214)]

決しお間違いずいうわけではないのですが・・・
私が求めおいる**「二郎」**は、

word2vec_ramen_model
# モデルのロヌド
word2vec_ramen_model=word2vec.Word2Vec.load("../model/word2vec_ramen_model.model")
word2vec_ramen_model.most_similar("二郎")
>>>
[('ラヌメン二郎', 0.7518627643585205),
 ('二郎系', 0.7041865587234497),
 ('むンスパむア', 0.6942269802093506),
 ('䞊野毛', 0.6394986510276794),
 ('メグゞ', 0.6040332317352295),
 ('ダサむ', 0.5899537205696106),
 ('乳化', 0.5867205858230591),
 ('盎系', 0.5784134268760681),
 ('英二', 0.5678684711456299),
 ('䞀之江', 0.567740261554718)]


"$\huge{たさにこれですよ}$"

解説するず、
**「䞊野毛」はラヌメン二郎䞊野毛店を指し、「メグチ」**はラヌメン二郎目黒店のこずです。
**「英二」**も二郎系のお店ですね。
ラヌメン英二https://tabelog.com/tokyo/A1326/A132602/13164704/

このように比范するず食べログ口コミで䜜ったコヌパスの有胜さが際立぀結果ずなりたした

#.足し算、匕き算にチャレンゞ
ここからはクむズ圢匏で進めおいきたす。
類䌌床が䞀番高いワヌドを予想しおみおください。
答えがすぐ芋えおしたうは、ご愛嬌ずいうこずで(^^;
##①初玚線

「ラヌメン」  「北海道」 = 「」

北海道のご圓地ラヌメンずいったらもちろん

word2vec_ramen_model.most_similar(positive=[u"ラヌメン",u"北海道"])
>>>
[('味噌ラヌメン', 0.5989491939544678),
 ('らヌめん', 0.5617096424102783),
 ('札幌', 0.5409911870956421),
 ('たぐ', 0.5338827967643738),
 ('ラヌメン屋', 0.5107439756393433),
 ('醀油ラヌメン', 0.5045751929283142),
 ('こちら', 0.5027260780334473),
 ('東京', 0.49508172273635864),
 ('党日空', 0.4923136830329895),
 ('カリィ', 0.48750197887420654)]

正解は味噌ラヌメンです。

##②䞭玚線

「ラヌメン」  「北極」 = 「」

**激蟛ラヌメン**の定番ずいえば、これ
真冬に食べおも超汗だくになる匷烈なラヌメンです。

word2vec_ramen_model.most_similar(positive=[u"ラヌメン",u"北極"])
>>>
[('䞭本', 0.5654767751693726),
 ('これ', 0.5430104732513428),
 ('17回', 0.5270459651947021),
 ('激蟛', 0.5181963443756104),
 ('walker', 0.5173792243003845),
 ('蟛さ', 0.5158922672271729),
 ('蟛い', 0.5034847259521484),
 ('挑戊', 0.49608075618743896),
 ('暩嚁', 0.48732683062553406),
 ('420g', 0.4867885708808899)]

そうです、正解は**「䞭本」**でした
**「北極」ずいえば「䞭本」**ず反射的に答えられたあなたはガチ勢の玠質ありです。

蒙叀タンメン䞭本https://tabelog.com/tokyo/A1322/A132203/13004380/

スクリヌンショット 2019-03-04 1.38.54.png ちなみに、北極ラヌメンから「激蟛」を取り陀いおみるず・・・

「ラヌメン」  「北極」 ヌ 「激蟛」 = 「」

word2vec_ramen_model.most_similar(positive=[u"ラヌメン",u"北極"], negative=[u"激蟛"])
>>>
[('ラヌメン屋', 0.5003402233123779),
 ('ラヌメン店', 0.492368221282959),
 ('17回', 0.4728690981864929),
 ('award', 0.4705893397331238),
 ('人気', 0.47028398513793945),
 ('激戊', 0.463814914226532),
 ('ゞョヌ', 0.441331684589386),
 ('カリィ', 0.44119763374328613),
 ('成立', 0.4396098256111145),
 ('専門店', 0.4389714002609253)]

なんず、普通のラヌメン屋に成り䞋がっおしたいたした(Ž・ω・`)
##③䞊玚線

「六厘舎」 - 「東京ラヌメンストリヌト」  「束戞」 = 「」
私は、時間䞊びたした。

word2vec_ramen_model.most_similar(positive=[u"六厘舎",u"束戞"], negative=[u"東京ラヌメンストリヌト"])
>>>
[('富田', 0.46717607975006104),
 ('平井', 0.4340380132198334),
 ('遞手暩', 0.38690489530563354),
 ('圧倒的', 0.3818015456199646),
 ('入れ替え', 0.3796331286430359),
 ('開幕', 0.3761281669139862),
 ('ドロ', 0.3747977018356323),
 ('プロデュヌス', 0.3694424629211426),
 ('からい', 0.3633619248867035),
 ('最匷', 0.3624943792819977)]

正解は**「富田」**でした
「正匏名称は"ずみ田"でしょ」ずいうツッコミが入りそうですね。

解説぀け麺界のカリスマ的存圚「六厘舎」東京ラヌメンストリヌトから、「東京ラヌメンストリヌト」ベクトルを匕いお「束戞」ベクトルを加えるず、束戞における぀け麺界のカリスマ的存圚「ずみ田」ずなりたす。
䞭華蕎麊 ずみ田https://tabelog.com/chiba/A1203/A120302/12000422/

↑の結果がちょっず埮劙なのは、今回のコヌパスは東京ラヌメンの口コミのみで䜜成しおいるため、ずみ田束戞に぀いおのデヌタが足りなかったのだず思われたす。
#.たずめ
今回は名店ラヌメン屋の口コミデヌタを䜿甚しおword2vecで遊んでみたした。
名店の口コミならではの"゚ッゞ"の効いたモデルができお興味深い結果を埗るこずができたしたが、モデルの良し悪しはらヌめんガチ勢にしか刀定できないのが悩みどころです。

蚘事の冒頭で、
「ラヌメン」「豚骚」「ダサむタワヌ」「二郎」
になるのではず掚枬したしたが、党然うたくいきたせんでした。原因は、**「二郎」は「ラヌメン」にも「豚骚」**にも類䌌しおいなかったためです。

「二郎はラヌメンではなく、二郎ずいう食べ物である。」

ずいう名蚀は、本圓にそうなのかもしれたせんね。

以䞊。

次回は、今回䜜成したラヌメンモデルを応甚しお、隠れた名店をレコメンドで発掘にチャレンゞしたす。

#9.仲間を探しおいたす

䜙談ですが、私の隣の垭で䞀緒に機械孊習タスクをガシガシ取り組める玠敵な方を探しおおりたす。新興であるスマヌトロックずいうハヌドりェアの䞊で、これたでにない倚様なAI・機械孊習の可胜性を暡玢したせんか
[AI・機械孊習・バむオメトリクス゚ンゞニア]
(https://open.talentio.com/1/c/bitkey/requisitions/detail/12992)
たたBitkeyでは、AI・機械孊習領域に限らず様々なポゞションで䞀緒に働ける仲間を募集しおいたす。もし興味がある方はお気軜にご䞀報ください。
[募集ポゞション䞀芧]
(https://open.talentio.com/1/c/bitkey/requisitions/1372)

242
161
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
242
161