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

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

ただいまの
回答率

90.04%

scikit-learn tfidf求め方

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,431

SAMUSAMUN

score 26

前提・実現したいこと

pythonのscikit-learnを使い,tfidfを求めようと考えています.
形態素解析を行って,単語だけを集めたテキストファイルを読み込み,
値が0.5以上の単語だけを表示しようとしています.

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

Traceback (most recent call last):
  File "tfidf6.py", line 15, in <module>
    if vecs > 0.5:
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/sparse/base.py", line 183, in __bool__
    raise ValueError("The truth value of an array with more than one "
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().

該当のソースコード

# -*- coding: utf-8 -*-
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer

np.set_printoptions(precision=2)

f = open('part-time_negaword.txt', 'r')#読み込むファイルを開く
text = f.read()#ファイルから全データを読み込む
f.close()#ファイルを閉じる

docs = np.array([text])

vectorizer = TfidfVectorizer(use_idf=True,token_pattern=u'(?u)\\b\\w+\\b',min_df=1.0)
vecs = vectorizer.fit_transform(docs)
if vecs > 0.5:
 print vecs.toarray()

試したこと

多次元配列が問題となっていると書いていたんですが,イマイチ理解できずエラーが直せません.
どうかご協力お願い致します.

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

OS X
python2系

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+3

つい最近おなじような回答をした気がしますが、

結果を表示する部分は

if vecs > 0.5:
    print(vecs.toarray())


ではなく、先に配列に変換(toarray())してから

TF_IDF = vecs.toarray()
print(TF_IDF[TF_IDF>0.5])

のように書けます。

しかしながら、上記のように書くと何の単語のTF-IDF値が 0.5 以上なのか分からなくなるので、

np.where() を使い、条件に当てはまる値の配列の位置データを求めることで、行・単語(列データ)・TF-IDF値を同時に表示することができるようになります。

TF_IDF = vecs.toarray()
terms = vectorizer.get_feature_names() #単語リスト
x,y = np.where(TF_IDF>0.5)
for pos in zip(x,y):
    print(pos) # 位置を表示
    print(TF_IDF[pos]) # TF-IDF値を表示
    print(terms[pos[1]]) # 単語を表示

まとめるとこんな感じで書けます

TF_IDF = vecs.toarray()
terms = vectorizer.get_feature_names()
for idx, word in zip(*np.where(TF_IDF> 0.5)):
    print("INDEX:{}, WORD:{}, TF-IDF:{}".format(idx, terms[word], TF_IDF[(idx,word)]))

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/07/13 01:53

    自分が回答したものよりもわかりやすく、見やすいですね
    勉強になります

    キャンセル

  • 2017/07/13 16:48

    ご回答ありがとうございます!
    おかげさまで解決することができました!

    キャンセル

0

http://nishidy.hatenablog.com/entry/2016/04/23/120519
こちらを参考に

基本的にエラーメッセージで検索すれば解決できますのでまずはggrましょう。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/07/13 16:50

    今回も調べてみたのですがもっと自分で解決できるようにしようと思います.
    ありがとうございます!!

    キャンセル

0

python3系でTfidfVectorizer日常的に使用している者です

結果のvecsの中身がどうなっているか確認しましたか?
2系と得られるものは大差ないはずなので多分下記のようになっていると思います。
データ自体は同じように形態素解析の結果を使っていますが、データの都合上tfidf値の設定は行っていません。

vectorizer = TfidfVectorizer()
dictionary2 = vectorizer.fit_transform(data)
print(dictionary2)
#(0, 996)    0.407322789896
#(0, 887)    0.381311993422
#(0, 259)    0.407322789896
#(0, 118)    0.407322789896
#(0, 1142)    0.282491647013
#(0, 228)    0.362857039626
#(0, 1276)    0.381311993422
 :    :


それを解釈した上で、tfidf値が高いものを引き出す場合、以下のような感じでやればできるんではないかと思います。
データの都合上0.4より大きいものを検知するようにしています

vectorizer = TfidfVectorizer()
dictionary2 = vectorizer.fit_transform(data)
print(dictionary2[0])
dictionary2 = dictionary2.toarray()
vec = []
for i in range(len(dictionary2[0])):
    if dictionary2[0][i] >0.4:
        vec.append(i)
print(vec)
for i in range(len(vec)):
    print(vectorizer.get_feature_names()[vec[i]])


出力結果がこれです

print(dictionary2[0])
 (0, 996)    0.407322789896
 (0, 887)    0.381311993422
 (0, 259)    0.407322789896
 (0, 118)    0.407322789896
 (0, 1142)    0.282491647013
 (0, 228)    0.362857039626
 (0, 1276)    0.381311993422

print(vec)
[118, 259, 996]

print(vectorizer.get_feature_names()[vec[i]])
おやすみ
つぶやき
新緑

ここら辺のサイトなんかは参考になるんじゃないかと思います
http://qiita.com/katryo/items/f86971afcb65ce1e7d40

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/07/13 16:49

    とてもわかりやすくて参考になりました.
    ありがとうございます!!

    キャンセル

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

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