KH Coderでツイートを分類するでツイートをKH Coderを使ってクラスタリングしてみたが、今度はPython3でやってみる。KH Coderでツイートを分類するで「スイーツ シュークリーム」「スイーツ ジェラート」「スイーツ バームクーヘン」「スイーツ どら焼き」「スイーツ たい焼き」「スイーツ 羊羹」を検索ワードとして収集したツイートを使う。mecab-ipadic-NEologdで形態素解析を新語に対応させるでインストールしたMeCabとmecab-ipadic-NEologdで形態素解析を行い、各スイーツのツイートをTF-IDFでベクトル化する。そして、ベクトル化した文章間の距離をもとにクラスタリングし、最後にデンドログラムを作成する。
Raspberry PiをJupyter Notebookサーバにするの手順でBash on Ubuntu on Windowsに構築したJupyter Notebookサーバ。
必要なPythonライブラリをインストールする。
続いて、PythonでMeCabとmecab-ipadic-NEologdを使える環境にしておく(mecab-ipadic-NEologdで形態素解析を新語に対応させるを参照)。
さらに、matplotlibで日本語を使えるようにしておく(Raspberry PiとPython3でグラフを作成する参照)。
KH Coderでツイートを分類するで収集したツイートのテキストsweets.txt(スイーツ名がH1タグで囲まれている)から、スイーツ名をインデックスとするPnadasのデータフレームを作成する。
作成したデータフレームは以下の通り。
MeCabでツイートを分かち書きして、scikit-learnのTfidfVectorizerでTF-IDFを計算する。今回は「名詞」「動詞」「形容詞」「副詞」「感動詞」のみを使う。さらに、ツイート収集時の検索ワードは使用しない。
以下のようなTF-IDFが得られる。行は各スイーツのツイート、列は語。
最後にscipyのlinkageとdendrogramでデンドログラムを作成する。ここではコサイン距離を使ってクラスタリングする。
以下のようなデンドログラムが作成された。「たい焼き」「どら焼き」と「シュークリーム」「バームクーヘン」がそれぞれ近くにあって、直感に近い分類になった。
KH Coderでツイートを分類するで作成したKH Coderによるデンドログラムとは違う結果になったけれど、クラスタリングの方法や距離が違うので単純な比較はできない。
環境
Raspberry PiをJupyter Notebookサーバにするの手順でBash on Ubuntu on Windowsに構築したJupyter Notebookサーバ。
Pythonライブラリ等のインストール
必要なPythonライブラリをインストールする。
続いて、PythonでMeCabとmecab-ipadic-NEologdを使える環境にしておく(mecab-ipadic-NEologdで形態素解析を新語に対応させるを参照)。
さらに、matplotlibで日本語を使えるようにしておく(Raspberry PiとPython3でグラフを作成する参照)。
ツイートテキストの読み込み
KH Coderでツイートを分類するで収集したツイートのテキストsweets.txt(スイーツ名がH1タグで囲まれている)から、スイーツ名をインデックスとするPnadasのデータフレームを作成する。
import codecs import re import pandas as pd def get_sweets(): with codecs.open('sweets2.txt', 'r', 'shift_jis', 'ignore') as f: lines = f.readlines() pat = re.compile('(.+)
') cat = '' sweets = {} for line in lines: match = pat.match(line) if match: cat = match.group(1) sweets[cat] = '' else: sweets[cat] += line # スイーツ名をインデックスにしてDataframe作成 return pd.DataFrame.from_dict(sweets, orient='index') def main(): df = get_sweets() df.index.name = 'スイーツ名' df.columns = ['ツイート'] if __name__ == '__main__': main()
作成したデータフレームは以下の通り。
TF-IDFでベクトル化する
MeCabでツイートを分かち書きして、scikit-learnのTfidfVectorizerでTF-IDFを計算する。今回は「名詞」「動詞」「形容詞」「副詞」「感動詞」のみを使う。さらに、ツイート収集時の検索ワードは使用しない。
import codecs import re import pandas as pd import MeCab from sklearn.feature_extraction.text import TfidfVectorizer def wakati(text): """ 対象とする品詞のみでわかち書き """ # 取り込む品詞 cat_list = ['名詞', '動詞', '形容詞', '副詞', '感動詞'] # ストップワード stop_list = ['スイーツ', '羊羹', 'ジェラート', 'どら焼き', 'シュークリーム', 'バームクーヘン', 'たい焼き'] # 辞書としてmecab-ipadic-neologdを使う m = MeCab.Tagger('-Ochasen -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd') m.parse('') node = m.parseToNode(text) wd_list = [] while node: cat = node.feature.split(',')[0] if cat in cat_list and node.surface not in stop_list: wd_list.append(node.surface) node = node.next return ' '.join(wd_list) def calc_tfidf(wakati_list): """ TF-IDFでベクトル化 """ # token_pattern=u'(?u)\\b\\w+\\b : 文字列長が 1 の単語を処理対象に含める vectorizer = TfidfVectorizer(token_pattern='(?u)\\b\\w+\\b') vecs = vectorizer.fit_transform(wakati_list) print('TF-IDF=',) print(vecs.toarray().shape) print(vecs.toarray()) return vecs def main(): df = get_sweets() df.index.name = 'スイーツ名' df.columns = ['ツイート'] # ツイートをわかち書きにする df['wakati'] = df['ツイート'].apply(wakati) # TF-IDF計算 vecs = calc_tfidf(df['wakati'].tolist()) if __name__ == '__main__': main()
以下のようなTF-IDFが得られる。行は各スイーツのツイート、列は語。
デンドログラムの作成
最後にscipyのlinkageとdendrogramでデンドログラムを作成する。ここではコサイン距離を使ってクラスタリングする。
import codecs import re import pandas as pd import MeCab from sklearn.feature_extraction.text import TfidfVectorizer from scipy.cluster.hierarchy import dendrogram, linkage import matplotlib %matplotlib inline import matplotlib.pyplot as plt # matplotlibの日本語フォント指定 font = {'family' : 'IPAexGothic'} matplotlib.rc('font', **font) def gen_cluster(X, labels): # コサイン距離を使ってクラスタリングする Z = linkage(X, metric='cosine') # デンドログラムの作成 plt.figure(figsize=(10, 5)) plt.ylabel('距離') dendrogram( Z, leaf_rotation=90., leaf_font_size=12., labels=labels ) plt.show() def main(): df = get_sweets() df.index.name = 'スイーツ名' df.columns = ['ツイート'] # ツイートをわかち書きにする df['wakati'] = df['ツイート'].apply(wakati) # TF-IDF計算 vecs = calc_tfidf(df['wakati'].tolist()) # デンドログラムの作成 gen_cluster(vecs.toarray(), df.index.values) if __name__ == '__main__': main()
結果
以下のようなデンドログラムが作成された。「たい焼き」「どら焼き」と「シュークリーム」「バームクーヘン」がそれぞれ近くにあって、直感に近い分類になった。
KH Coderでツイートを分類するで作成したKH Coderによるデンドログラムとは違う結果になったけれど、クラスタリングの方法や距離が違うので単純な比較はできない。
0 件のコメント:
コメントを投稿