質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Mecab

Mecabは、オープンソースの形態素解析エンジンです。 言語、辞書、コーパスに依存しない汎用的な設計を基本方針としています。 Mecabの由来は、開発者の好物である和布蕪(めかぶ)から名づけられました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

データマイニング

データマイニングは、購買履歴やクレジットカードの利用履歴、電話の通話履歴など企業にある大量のデータを解析して、その中に隠れたパターンやルールを探し出す技術です。DMと略されることもあります。

Q&A

1回答

2410閲覧

Python、MeCAbを用いた文書間類似度の計算結果から、データを整理する方法

hasegawahakase

総合スコア1

Mecab

Mecabは、オープンソースの形態素解析エンジンです。 言語、辞書、コーパスに依存しない汎用的な設計を基本方針としています。 Mecabの由来は、開発者の好物である和布蕪(めかぶ)から名づけられました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

データマイニング

データマイニングは、購買履歴やクレジットカードの利用履歴、電話の通話履歴など企業にある大量のデータを解析して、その中に隠れたパターンやルールを探し出す技術です。DMと略されることもあります。

0グッド

0クリップ

投稿2021/10/18 07:30

プログラミング超初心者です。
現在、アンケート結果の大量の単文書(例:これがかっこいいと思います。/私はこれが好きです。等)の文書間類似度を計算するために以下のような、システムをネットなどの情報から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)

以上、長いうえにわかりづらくて大変恐縮ですが、ご回答いただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2021/10/18 08:07

1つの質問あたりの解決したい問題数は少なくしたほうが回答得られやすいと思います。 また、今回の問題ではMeCab解析部分は不要そうなので 「word_list = [~]」で具体的なデータ例をセットした行から始まるコードを提示されると、第三者が実行、検証しやすくなります。
hasegawahakase

2021/10/18 08:29

ご指摘、回答していただきありがあとうございます。要領を得ておらず、載せるべき部分がわからずこのような質問になってしまいました、、
guest

回答1

0

①と②の前半のみの回答となります。

②についてですがCountVectorizer解析器自体が名称(get_feature_names)を持っているので、それを利用します。
②の後半(重みづけ)についても同様にできます。
参考:機械学習 〜 テキスト特徴量(CountVectorizer, TfidfVectorizer) 〜

Python

1import pandas as pd 2import numpy as np 3from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer 4pd.set_option('display.unicode.east_asian_width', True) 5 6word_list = [' 私 猫 好き',' 私 猫 嫌い',' 私 犬 好き',' 私 猿 嫌い',' 私 犬 猫 嫌い',' 私 犬 猿 嫌い'] 7 8 9# ①形態素解析の結果から取り出された名詞とその出現数の獲得 10words = [] 11for doc in word_list: 12 words += doc.split() 13 14import collections 15counter = collections.Counter(words) 16d = counter.most_common() 17print(d) # [('私', 6), ('嫌い', 4), ('猫', 3), ('犬', 3), ('好き', 2), ('猿', 2)] 18 19 20# ②各文書と各単語の出現の有無(1/0) 21 22count = CountVectorizer(token_pattern=u'(?u)\b\w+\b') 23vec_count = count.fit_transform(word_list)#fit_transform:fit(変換式の計算)とtransform(データの変換)を同時に 24 25df = pd.DataFrame(vec_count.toarray(), columns=count.get_feature_names()) 26print(df) 27""" 28 好き 嫌い 犬 猫 猿 私 290 1 0 0 1 0 1 301 0 1 0 1 0 1 312 1 0 1 0 0 1 323 0 1 0 0 1 1 334 0 1 1 1 0 1 345 0 1 1 0 1 1 35"""

投稿2021/10/18 08:08

can110

総合スコア38341

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問