Janomeを使った形態素解析④
※使用したデータ:カップヌードルミュージアムの口コミ500件
(じゃらんの口コミをスクレイピングで取得したもの。 )
■Jaccard係数を計算する
まずはレビューごとのtermリストのリスト(つまり二次元リスト)を作る
terms_list= [] from janome.tokenizer import Tokenizer t = Tokenizer() for i in range(500): text = DF['本文'][i] terms = [] token_list = t.tokenize(text) for token in token_list: if token.part_of_speech.split(',')[0] in ['名詞']: #品詞は名詞に限定 terms.append(token.base_form) terms_list.append(terms)
次に頻出termのみ抽出してtermの組み合わせリストを作る
from collections import defaultdict term_freq = defaultdict(lambda: 0) for term in sum(terms_list, []): term_freq[term] += 1 term_freq_sort = sorted(term_freq.items(), key=lambda x:x[1], reverse=True) term_freq_20 = term_freq_sort[:20] #ここで頻出単語Top20にした term_uni = [tupple[0] for tupple in term_freq_20] term_combis = list(itertools.combinations(term_uni, 2))
Jaccard係数を計算する
def Jaccard(x,y,terms_list): #x,y=2つのterm seki = sum(((x in terms) & (y in terms)) for terms in terms_list) wa = sum(((x in terms) or (y in terms)) for terms in terms_list) return seki/wa Jaccard_list = [] for term_combi in term_combis: data = dict(term1=term_combi[0], term2=term_combi[1], Jaccard=Jaccard(term_combi[0], term_combi[1], terms_list)) Jaccard_list.append(data)
termの組み合わせとJaccard係数をまとめたデータフレームを作る
import pandas as pd DF_Jaccard = pd.DataFrame(Jaccard_list) DF_Jaccard = DF_Jaccard.sort_values(by='Jaccard', ascending=False).reset_index()[:30] #Jaccard係数が大きい順に並べ替えてTop30を抽出
■ NetworkXで描画する
import networkx as nx import matplotlib import matplotlib.pyplot as plt %matplotlib inline DF = DF_Jaccard term_combi = [(DF['term1'][i], DF['term2'][i]) for i in range(len(DF))] G = nx.Graph() G.add_edges_from(term_combi) G.remove_nodes_from(['ラーメン', '体験', '大人', 'チキン']) #適宜ノードやエッジを削除して見た目をよくする width = DF['Jaccard']*10 node_size = [term_freq[term]*7 for term in G.nodes] pos = nx.spring_layout(G, k=0.5) #エッジの大きさによる吸引力でノードの位置を決定する(kの値が大きいと全体的に丸くなる) nx.draw(G, pos, with_labels=True, font_family='IPAexGothic', width=width, node_size=node_size,\ node_color='skyblue',alpha=0.6, edge_color='gray')
■おまけ:pyfpgrowthを使った組み合わせパターンの抽出
import pyfpgrowth kyoki = pyfpgrowth.find_frequent_patterns(wakati_list1, 30) #頻度の高い組み合わせを抽出。「30回以上」と指定。 pair = [] for kyoki_set in kyoki.items(): if len(kyoki_set[0]) == 2: #2つの単語の組み合わせのみ抽出し、単語3つ以上の組み合わせは除く。 pair.append(kyoki_set) sorted_pair = sorted(pair, key=lambda x:x[1], reverse=True) #出現頻度で並び替え sorted_pair_30 = sorted_pair[:30] #Top30を抽出 sorted_pair_30
[(('カップ', 'ヌードル'), 636),
(('する', 'カップ'), 274),
(('できる', 'カップ'), 244),
(('オリジナル', 'ヌードル'), 228),
(('こと', 'できる'), 228),
(('いる', 'する'), 193),
(('カップ', '作る'), 180),
(('ある', 'カップ'), 177),
(('カップ', '自分'), 161),
(('カップ', '楽しい'), 140),
(('カップ', '作れる'), 132),
(('ヌードル', '歴史'), 131),
(('ヌードル', 'ヌードル'), 127),
(('カップ', 'カップ'), 127),
(('する', 'ラーメン'), 125),
(('する', 'の'), 118),
(('カップ', '楽しめる'), 117),
(('の', 'カップ'), 110),
(('する', '体験'), 98),
(('なる', 'カップ'), 94),
(('する', 'れる'), 89),
(('カップ', '子供'), 84),
(('ヌードル', '子供'), 80),
(('する', 'カップラーメン'), 79),
(('カップ', '具'), 76),
(('カップ', '食べる'), 76),
(('ヌードル', '食べる'), 73),
(('する', '行く'), 73),
(('カップ', 'ラーメン'), 73),
(('する', 'チキン'), 71)]