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

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

ただいまの
回答率

87.51%

pythonで、Excelから読み込んだ文書リストをMeCabで形態素解析し、文書間類似度を計算したいです、、、

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 75

Excelから読み込んだ大量の単文書間の類似度をpython,Mecabをつかって計算したい

プログラミングのぷの字もわからない、超初心者です。急遽、Excelの表にまとめられた大量のインタビューの結果から、各発話(単文書:例「これがかっこいいと思います。」,「私はこれが好きです。」など)間の類似度を計算する必要がでてきてしまい、文書間類似度を計算するシステムを作るために、ネットをあさりながらPython上でMecabを使った形態素解析までできるようになりました。しかし、そのあとの文書をベクトル化してcos類似度を計算する段階で、以下のようなエラーメッセージが発生しました。

発生している問題・エラーメッセージ

Traceback (most recent call last):
  File "C:\Users\lklng\test.py", line 59, in <module>
    vecs=tfidf(word_list)
  File "C:\Users\lklng\test.py", line 42, in tfidf
    vectorizer=TfidfVectorizer(
  File "C:\Users\lklng\anaconda3\lib\site-packages\sklearn\feature_extraction\text.py", line 1850, in fit_transform
    X = super().fit_transform(raw_documents)
  File "C:\Users\lklng\anaconda3\lib\site-packages\sklearn\feature_extraction\text.py", line 1203, in fit_transform
    vocabulary, X = self._count_vocab(raw_documents,
  File "C:\Users\lklng\anaconda3\lib\site-packages\sklearn\feature_extraction\text.py", line 1134, in _count_vocab
    raise ValueError("empty vocabulary; perhaps the documents only"
ValueError: empty vocabulary; perhaps the documents only contain stop words
[Finished in 0.942s]

該当のソースコード

import pandas as pd
import MeCab as mc
from time import sleep
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer

##関数定義
#step1:テキストデータをデータフレームとして読み込む
def get_text():
    text_list=""
    csv_input=pd.read_csv(filepath_or_buffer="C:\\Users\\lklng\\OneDrive\\デスクトップ\\Book1.csv",encoding="utf_8",sep=',',engine="python")
    text_list=csv_input["発話内容"].values
    # 指定したカラムだけ抽出したDataFrameオブジェクトを返却します。
    #値を二次元配列形式?で返却します。
    #返却される型は、numpy.ndarray
    #行インデックス、カラムインデックスの順番で指定して項目の値を取得できます。
    return text_list



# Step2:それらをMeCabで形態素解析。名詞だけ抽出。
def mplg(text_list):
    word_list=""
    m=mc.Tagger("-Ochasen")
    m1=m.parse(text)
    for row in m1.split("\n"):
        word=row.split("\t")[0]#タブ区切りになっている1つ目を取り出す。ここには形態素が格納されている
        if word=="EOS":#EOS は end of sentence で文末
            break
        else:
            pos=row.split("\t")[1]#タブ区切りになっている2つ目を取り出す。ここには品詞が格納されている
            slice=pos[:2]
            if slice=="名詞":
                word_list=word_list+" "+word
    return word_list

#step3:文書ベクトル化関数
def tfidf(word_list):
    docs=np.array(word_list)#Numpyの配列に変換
    #単語をベクトル化して、TF-IDFを計算する
    vectorizer=TfidfVectorizer(
                       token_pattern=u'(?u)\\b\\w+\\b'#文字列長が 1 の単語を処理対象に含めることを意味します。
                       ).fit_transform(docs) #fit_transform:BagofWords(単語の出現回数) へ
    vecs=vectorizer.toarray()
    return vecs

#step4:類似度行列作成
def cossim(v1,v2):
    #二つのベクトルの内積をそれぞれのL2ノルムで割る
    return np.dot(v1,v2) / (np.linaling.norm(v1) * np.linaling.norm(v2))

##実装
word_list=[]
texts=get_text()
for text in texts:
    word_list.append(mplg(text))

vecs=tfidf(word_list)
print(cossim(vecs[1],vecs[0]))

試したこと

エラーメッセージをなんとか読んで、ストップワードしかないからだめらしいというところまではわかりましたが、なにをどうすればいいのかわかりません。助けてください、、、。(質問の仕方もこれでよいのかわかりません、、、わかりにくい内容、的外れなことをやっているようでしたら申し訳ありません、、)

補足情報(FW/ツールのバージョンなど)

python.3.8.8 (default, Apr 13 2021, 15:08:03) [MSC v.1916 64 bit (AMD64)]

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

mplg関数のfor row~ループの中にprint([row])と入れてみて、その表示結果を確認してみてください。
['リンゴ\tリンゴ\tリンゴ\t名詞-一般\t\t']というふうに表示されると思います。

つまりpos=row.split("\t")[1]ではなくpos=row.split("\t")[3]であるべきだと思います。
また、np.linalingnp.linalgが正しいです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/10/15 12:16

    エラーが解決しました!
    ありがとうございます。

    キャンセル

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

  • ただいまの回答率 87.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Pythonに関する質問
  • pythonで、Excelから読み込んだ文書リストをMeCabで形態素解析し、文書間類似度を計算したいです、、、