プログラミング超初心者です。
現在、アンケート結果の大量の単文書(例:これがかっこいいと思います。/私はこれが好きです。等)の文書間類似度を計算するために以下のような、システムをネットなどの情報からpythonで作りました。現状、Excelデータ(.csv)から形態素解析、名詞の取り出しおよびTF-IDF法による重みづけ、文書ベクトルの作成、それらのcos類似度の計算まで、なんとか出力されるようになりました。
Python
1import pandas as pd 2import MeCab as mc 3from time import sleep 4import numpy as np 5from sklearn.feature_extraction.text import TfidfVectorizer 6import itertools 7import openpyxl 8 9##関数定義 10#step1:テキストデータをデータフレームとして読み込む 11def get_text(): 12 text_list="" 13 csv_input=pd.read_csv(filepath_or_buffer="C:\Users\lklng\OneDrive\デスクトップ\test2.csv", 14 encoding="utf_8",sep=',',engine="python") 15 text_list=csv_input["発話内容"].values 16 # 指定したカラムだけ抽出したDataFrameオブジェクトを返却します。#値を二次元配列形式?で返却します。 17 #返却される型は、numpy.ndarray #行インデックス、カラムインデックスの順番で指定して項目の値を取得できます。 18 return text_list 19 20# Step2:それらをMeCabで形態素解析。名詞だけ抽出。 21def mplg(text_list): 22 word_list="" 23 m=mc.Tagger("-Ochasen") 24 m1=m.parse(text) 25 for row in m1.split("\n"): 26 word=row.split("\t")[0]#タブ区切りになっている1つ目を取り出す。ここには形態素が格納されている 27 if word=="EOS":#EOS は end of sentence で文末 28 break 29 else: 30 pos=row.split("\t")[3]#タブ区切りになっている4つ目を取り出す。ここには品詞が格納されている 31 slice=pos[:2] 32 if slice=="名詞": 33 word_list=word_list+" "+word 34 return word_list 35 36#step3:文書ベクトル化関数 37def tfidf(word_list): 38 docs=np.array(word_list)#Numpyの配列に変換 39 #単語をベクトル化して、TF-IDFを計算する 40 vectorizer=TfidfVectorizer( 41 token_pattern=u'(?u)\b\w+\b'#文字列長が 1 の単語を処理対象に含めることを意味します。 42 ).fit_transform(docs) #fit_transform:BagofWords(単語の出現回数)へ:fit(変換式の計算)とtransform(データの変換)を同時に 43 vecs=vectorizer.toarray() 44 return vecs 45 46#step4:類似度行列作成 47def cossim(v1,v2): 48 #二つのベクトルの内積をそれぞれのL2ノルムで割る 49 return np.dot(v1,v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)) 50 51#step5:表組の関数作成 52def df(list): 53 return pd.DataFrame(list)#,columns=[],index=[]) 54 55##実装 56#1.関数get_textでExcelから文章を習得。関数mplgで形態素解析、名詞の抽出。リストword_listへ格納 57word_list=[] 58texts=get_text()#get_text 59for text in texts: 60 word_list.append(mplg(text)) 61 62#2.関数tfidfで単語の重みづけ、文書ベクトル化 63vecs_list=tfidf(word_list) 64 65#3.リストvecs_pairへ、リストvecs_list内の全ベクトルのペアをリスト([[1,2,3],[1,2,3]],[[2,3,4],[2,3,4]]形式)として格納 66vecs_pair = [] 67for pair in itertools.combinations(vecs_list,2): 68 vecs_pair.append(list(pair)) #タプルをリスト型に変換 69 70#4.関数 cossim(v1,v2)で、リストvecs_pairの全要素のcos類似度を計算(0<cos類似度<1)し、リストcos_simへリスト形式で格納 71cos_sim = [] 72for vecs in vecs_pair: 73 cos_sim.append(cossim(vecs[1],vecs[0])) 74print(cos_sim) 75
前提・実現したいこと
データ整理のために、以下の3点の方法がわからず困っています。
①形態素解析の結果から取り出された名詞とその出現数の獲得
②各文書と各単語の出現の有無(1/0)、および重みづけの結果の表形式での出力
③各文書間のcos類似度計算結果の表形式での出力
###①形態素解析の結果から取り出された名詞とその出現数の獲得
→出力されたword_listから以下のような手続きで、出現単語とその回数を獲得しようとした結果、単語リストの数がカウントされてしまいました。[(私,6),(猫,3),(犬,3),...]のように名詞の数をカウントするためにはどうすればよいでしょうか…
python
1print(word_list) 2#出力結果:[' 私 猫 好き' ' 私 猫 嫌い' ' 私 犬 好き' ' 私 猿 嫌い' ' 私 犬 猫 嫌い' ' 私 犬 猿 嫌い'] 3 4#出現単語数のカウント 5from sklearn.feature_extraction.text import CountVectorizer 6word_list=np.array(word_list)# bow ( bag of words ) 7 8date=word_list 9import collections 10counter = collections.Counter(date) 11d = counter.most_common() 12print(d) 13#出力結果:[(' 私 猫 好き', 1), (' 私 猫 嫌い', 1), (' 私 犬 好き', 1), (' 私 猿 嫌い', 1), (' 私 犬 猫 嫌い', 1), (' 私 犬 猿 嫌い', 1)] 14
②各文書と各単語の出現の有無(1/0)、および重みづけの結果の表形式での出力
→各文書と各単語の関係性を把握するために、出現の有無およびに重みづけの結果を以下のように表形式で出力したのですが、インデックス名を出現単語にする方法がわかりません…
Python
1# CountVectorizer:出現した単語を純粋にカウントします。 2count=CountVectorizer(token_pattern=u'(?u)\b\w+\b'#文字列長が 1 の単語を処理対象に含めることを意味します。 3 ) 4# ベクトル化 5vec_count=count.fit_transform(word_list)#fit_transform:fit(変換式の計算)とtransform(データの変換)を同時に 6#bags=vec_count.transform(word_list) 7print(df(vec_count.toarray()))#表組 8#出力結果: 9 0 1 2 3 4 5 100 1 0 0 1 0 1 111 0 1 0 1 0 1 122 1 0 1 0 0 1 133 0 1 0 0 1 1 144 0 1 1 1 0 1 155 0 1 1 0 1 1 16 17#2.関数tfidfで単語の重みづけ、文書ベクトル化 18vecs_list=tfidf(word_list) 19DF=(df(vecs_list))#表組 20print(DF) 21#出力結果: 22 0 1 2 3 4 5 230 0.706079 0.000000 0.000000 0.596120 0.000000 0.382222 241 0.000000 0.585039 0.000000 0.682719 0.000000 0.437749 252 0.706079 0.000000 0.596120 0.000000 0.000000 0.382222 263 0.000000 0.536798 0.000000 0.000000 0.741972 0.401653 274 0.000000 0.483172 0.563845 0.563845 0.000000 0.361528 285 0.000000 0.454912 0.530867 0.000000 0.628789 0.340383
③各文書間のcos類似度計算結果の表形式での出力
→ cos類似度の結果が、以下のように出力されました。
この結果から、各文書をインデックス、カラム名とした表形式にデータを整理する方法(どの文書間の類似度の結果なのかを把握する方法)が、もしあるのであれば知りたいです…
Python
1#4.関数 cossim(v1,v2)で、リストvecs_pairの全要素のcos類似度を計算(0<cos類似度<1)し、リストcos_simへリスト形式で格納 2cos_sim = [] 3for vecs in vecs_pair: 4 cos_sim.append(cossim(vecs[1],vecs[0])) 5print(cos_sim) 6#出力結果:[0.5532481675265583, 0.6618785905183029, 0.18594500912689635, 0.4677465477227333, 0.18594500912689635, 0.6009965462489593, 0.8454552137315114, 0.5532481675265583, 0.4677465477227333, 0.8454552137315114] 7
補足情報(FW/ツールのバージョンなど)
python.3.8.8 (default, Apr 13 2021, 15:08:03) [MSC v.1916 64 bit (AMD64)
以上、長いうえにわかりづらくて大変恐縮ですが、ご回答いただけると幸いです。