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のデータフレームを作成する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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 ( '<h1>(.+)</h1>' ) 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を計算する。今回は「名詞」「動詞」「形容詞」「副詞」「感動詞」のみを使う。さらに、ツイート収集時の検索ワードは使用しない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | 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でデンドログラムを作成する。ここではコサイン距離を使ってクラスタリングする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | 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 件のコメント:
コメントを投稿