【Python】自然言語処理でグルメ大国福岡の人気店を発掘してみた

#概要
__Fukuokaの「食」__と言えば、ラーメン・もつ鍋・ごまさばですよね。福岡グルメとは裏腹に私はこよなく__うなぎを愛しており__、15年間行きつけの鰻屋さんに通っています。鰻屋の新規開拓をしたいところですが、金銭的に余裕のない私にはちょっと、、、なので今回は福岡の鰻屋さんの食べログ口コミを使って、__行きつけのうなぎ屋さんに類似したお店を発掘してみました。__そして、実際に行ってみた感想を最後に述べたいと思います。

#行きつけの鰻屋のご紹介
・福岡県久留米市にある
・__「富松うなぎ屋」__という__約80年続く老舗__
・席に着くとまずは「うなぎの骨」を堪能
・ほどよい塩加減とやみつきになるサクサクな食感が堪らない
・オススメメニューは__セイロむし(2400円)と鯉のアライ(550円)__
・ふっくらもちもちの肉厚うなぎに80年継ぎ足された秘伝のタレはまさに鬼に金棒
・鰻に甘いタレがたっぷり染み込んでおり、口に入れると香りが一層引き立ち最高の味わいです。

![S__254541826.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474739/a7eb4302-04e5-cfbd-09f4-04456dfb77c4.jpeg)
![eel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474739/49424bf8-5dbd-0f55-86bd-cedea666db50.png)

空腹で気が狂いそうなので、気を紛らわすために作業開始w

#環境
・Python 3.7.4
・windows10

#参考資料
[【Python】🍜機械学習で「隠れた名店」を探してみた。(そして実際に行ってみた)🍜](https://qiita.com/toshiyuki_tsutsui/items/b3ac8fd1b300c3404508)

#大まかな流れ
1. 食べログ口コミを取得(スクレイピング)
2. 口コミを単語にする(形態素解析)
3. レコメンド(Word2vec)
4. そして、実際に行ってみた！

#1. 食べログ口コミを取得(スクレイピング)

[食べログサイト](https://tabelog.com/)から福岡県のうなぎ屋さん全ページを取得しました。

スクレイピングの流れは以下の通り。
1. 店舗一覧ページ
2. 店舗詳細ページ
3. 口コミ一覧ページ
4. 口コミ詳細ページ
詳しいことは[こちら](https://qiita.com/toshiyuki_tsutsui/items/b3ac8fd1b300c3404508)を参照。

また、[前回の記事](https://qiita.com/yuuuusuke1997/items/122ca7597c909e73aad5)でご指摘頂いたので、サーバーに負荷をかけないよう1秒待機するようにしました。

```python:scraping_eel.py
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time

list_df = pd.DataFrame(columns=['店舗名', '口コミ'])

name_list = []
link_list = []

# 店舗一覧ページ
for page in range(1, 30):
    url = 'https://tabelog.com/fukuoka/rstLst/unagi/' + str(page) + '/?svd=20191026&svt=1900&svps=2'
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'lxml')
    # 店舗一覧ページから店舗名一覧と店舗詳細ページのリンクを取得
    store_tags = soup.find_all('a', class_='list-rst__rst-name-target cpy-rst-name')
    for store_tag in store_tags:
        # 店舗詳細ページのリンクが格納されたリスト作成
        link_list.append(store_tag.get('href'))
        # 店舗名一覧が格納されたリスト作成
        store_name = store_tag.text
        store_name = store_name.replace('　', '')
        store_name = store_name.replace(' ', '')
        name_list.append(store_name)

    for store_name, link in zip(name_list, link_list):
        # 店舗詳細ページ
        response = requests.get(link)
        soup = BeautifulSoup(response.text, 'lxml')
        # 店舗詳細ページから口コミ一覧ページへのリンクを取得
        review_tag_id = soup.find('li', id='rdnavi-review')
        review_tag_href = review_tag_id.a.get('href')

        # 口コミ一覧ページ
        response = requests.get(review_tag_href)
        soup = BeautifulSoup(response.text, 'lxml')
        # 口コミ一覧ページから口コミ詳細ページへのリンク取得
        review_comments = soup.find_all('a', class_='rvw-item__title-target')
        for review_comment in review_comments:

            # 口コミ詳細ページ
            response = requests.get('https://tabelog.com' + review_comment.get('href'))
            soup = BeautifulSoup(response.text, 'lxml')
            # 口コミ取得
            review_tags = soup.find_all('div', class_='rvw-item__rvw-comment')
            review = review_tags[0].p.text.encode('cp932', 'ignore')
            review = review.decode('cp932')
            review = review.replace('\n','')
            review = review.replace(' ','')
            review = review.replace('　','')

            # サーバーに負荷を与えないため1秒待機
            time.sleep(1)

            # 取得した項目
            # store_name=店舗名
            # review=口コミ
            tmp_se = pd.DataFrame([store_name, review], index=list_df.columns).T
            list_df = list_df.append(tmp_se)

print(list_df)

# CSV保存
list_df.to_csv('list_eel.csv', mode = 'a', encoding='cp932')
```

#2. 口コミを単語にする(形態素解析)

```python:morphological_analysis_eel.py
from janome.tokenizer import Tokenizer
from gensim.models import word2vec
import pandas as pd

#pandasで作成したCSVファイルを読み込み
df_file = pd.read_csv('list_eel.csv', encoding='cp932')

store_names = df_file['店舗名'].tolist()
reviews = df_file['口コミ'].tolist()

t = Tokenizer()

result = []

#解析開始
for i, review in enumerate(reviews):
	s = review
	tokens = t.tokenize(s)

	r = []

	for tok in tokens:
		#単語ごとに分かち書き
		#活用形がない(名詞)のとき実行
		if tok.base_form == '*':
			word = tok.surface
		#活用形がある(動詞・形容詞)のとき実行
		else:
			word = tok.base_form

		ps = tok.part_of_speech

		#品詞の種類を取得
		hinshi = ps.split(',')[0]

		#[]内の品詞のみを処理して追加
		if hinshi in ['名詞', '形容詞', '動詞']:
			r.append(word)

	rl = (' '.join(r)).strip()
	result.append(store_names[i])
	result.append(rl)
	#余計な文字コードを排除
	result = [i.replace('\u3000','') for i in result]
	
print(result)

#書き込み先テキストファイルを開く
text_file = 'wakati_list_eel.txt'
with open(text_file, 'w', encoding='utf-8') as fp:
	fp.write("\n".join(result))

#テキストファイルを読み込み、model作成
data = word2vec.LineSentence(text_file)
model = word2vec.Word2Vec(data, size=200, window=1, hs=1, min_count=1, sg=1)
model.save('./wakati_list_eel.model')
```

#3. レコメンド(Word2vec)

```python:word2vec_eel.py
from gensim.models import word2vec
import pandas as pd

model = word2vec.Word2Vec.load('./wakati_list_eel.model')

df_file = pd.read_csv('list_eel.csv', encoding='cp932')
store_names = df_file['店舗名'].tolist()

#任意の店舗名
keyword = '富松うなぎ屋黒田本店'

dic = {}

for store_name in store_names:
	result = model.wv.similarity(store_name, keyword)

	#出力結果を[店名: 類似度]にしたい
	dic[store_name] = result

#類似度が高い順で上位5番目まで取得
result = sorted(dic.items(), key=lambda x: -x[1])[1:6]
print(result)
>>>
[('福泉操', 0.16873132),
('博多銀丁', 0.14888753),
('うなぎ処安', 0.13577707),
('魚国', 0.12946151),
('うなぎ処柳川屋博多駅前店', 0.12561372)]
```
結果発表！
__1位：福泉操__
__2位：博多銀丁__
__3位：うなぎ処安__
__4位：魚国__
__5位：うなぎ処柳川屋博多駅前店__

ということで、堂々たる1位に輝いた__「福泉操」__に行ってみました。

#4. そして、実際に行ってみた！
・__柳川駅から徒歩1分__という好立地に店を構える__「福泉操」__
・__うなぎの看板が際立ち__、迷うことはまずない
・店内に入ると店中に香ばしい香りが充満し食欲そそられるぅ
・安定の__うなぎのセイロむし(2800円)__を注文
・我慢できないので早速一口いただきます
・__口全体に鰻の風味が広がり幸せパンチ__
・__ふっくら香ばしくて旨い__
・さすが駅前の老舗。大満足です！
・自宅から車で2時間かけて行った甲斐がありました
・みなさんも柳川に来た際はぜひ、ご堪能ください！

福泉操: https://fukusensou.com/
![S__254795831.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474739/627e4c80-4eee-3da9-9117-97ceabb86337.jpeg)
![S__254795829.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474739/d6ef035f-4def-3ca2-2e8e-3f35348ad83c.jpeg)

#私からのオススメ店 in Fukuoka
・__ちんぷんかんぷん(焼き鳥)__
・__京風もつ鍋越後屋__
・__味一(ラーメン)__
・__らーめん雷蔵__
・__安全食堂(ラーメン)__
・__博多もつ鍋前田屋のもつラーメン__

ラーメンばっかになっちゃった笑
福岡に来た際には是非、訪れてみてください。一人で不安な方はご連絡下さい。お供します！！

#おわりに
今回はうなぎ屋の新規開拓を目的にスクレイピング、形態素解析、word2vecを学びました。新規開拓に戸惑ったらこれを使うといいかもしれませんね。今後は類似度の精度向上を図るため、ワードの絞り込みやTF-IDFを加え実装してみたいと思います。長くなりましたが、ここまで読んでくださりありがとうございます。誤っている箇所がございましたら、コメントでご指摘頂けると大変嬉しいです。