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

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

ただいまの
回答率

90.75%

  • Python 3.x

    5333questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • Jupyter

    200questions

  • リストボックス

    9questions

    ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

tf(Term Frequency)とdf(Document Frequency)の求め方

解決済

回答 1

投稿 編集

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

ryuuu.ss

score 10

記事ごとの名詞を格納した2次元リスト
イメージとして
noun = [['私','子育て','問題','問題']['トランプ','今朝','会談','来日']・・・]
「私、子育て、問題」は記事1の名詞集、「トランプ、今朝、会談、来日」は記事2の名詞集
みたいなものを作りました。

そして以下のようにtfとdfを定義して求めたいと思いました。
tf = ある単語の記事内での出現回数 / 記事内のすべての単語の出現回数の和
例えば上の例なら、私:1/4 子育て:1/4 問題:2/4
df = ある単語が出現する記事の数
例えば私という単語が他の記事5つにも出てくるなら私のdf値は5です。

それでtfを求めるためにCounterのmost_commonを使って全単語の出現回数をカウントすることはできたのですが、この出現回数を全部足しすのどうやるんだってところで詰んでしまいました。。。

tfとdfを求めるためのアルゴリズム、手順をご教授いただけないでしょうか(汗)

<追記>コードはこんな感じです。
nounsというリストが上で説明したような名刺を入れている2次元のリストになります。
また、jupyter notebookでコードを書いています。

from collections import Counter

def flatten_2dim(array):
    return [item for sublist in array for item in sublist] 

counter = Counter(flatten_2dim(nouns))
for word, cnt in counter.most_common():
    print(word, cnt)
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • can110

    2017/11/07 14:50

    途中までで良いのでコードを提示ください。

    キャンセル

  • ryuuu.ss

    2017/11/07 16:17

    すみません、そうですよね。。。

    キャンセル

回答 1

checkベストアンサー

0

tfは、記事毎に、さらに(記事内の)単語毎に値を持ちます。
dfは、単語毎に値を持ちます。

提示コードでは元データを1次元化することで記事毎の情報が抜け落ちてしまっています。
少なくともtf記事毎のループで算出する必要があります。

Counterを使っても良いのですが、どうせtfは 頻度 / 合計で算出しなければならないので
以下のように単純なリストと辞書で実装してもよいと思います。

nouns = [['ブドウ','バナナ'],
        ['レモン','レモン','バナナ','ブドウ'],
        ['ブドウ']]

tfs = [] # 記事毎のリスト。リスト要素は記事内の単語毎のtf値
dfs = {} # 単語毎のdf値
for idx,doc in enumerate(nouns): # idx=記事番号
    tf = {}
    for term in doc:
        TERM_CNT = len(doc) # 記事内の単語数

        # (記事内の)単語毎のtf値
        if term not in tf:
            tf[term] = 0
        tf[term] += 1 / TERM_CNT # コード短縮のため、割り込むと同時に足す

        # 単語毎のdf値
        if term not in dfs:
            dfs[term] = set()
        dfs[term].add(idx) # 集合(set)で記事番号(idx)を保持

    tfs.append(tf)

# 記事番号の集合の大きさ=出現数
for term,doc_set in dfs.items():
    dfs[term] = len(doc_set)

print('nouns:',nouns)
print('tfs:',tfs)
print('dfs:',dfs)
"""
nouns: [['ブドウ', 'バナナ'], ['レモン', 'レモン', 'バナナ', 'ブドウ'], ['ブドウ']]
tfs: [{'バナナ': 0.5, 'ブドウ': 0.5}, {'レモン': 0.5, 'ブドウ': 0.25, 'バナナ': 0.25}, {'ブドウ': 1.0}]
dfs: {'バナナ': 2, 'ブドウ': 3, 'レモン': 1}
"""

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/11/08 14:14

    なるほどです!理解しました!

    勉強になります、分かりやすい解説どうもありがとうございましたm(__)m

    キャンセル

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

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

関連した質問

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

  • Python 3.x

    5333questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • Jupyter

    200questions

  • リストボックス

    9questions

    ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。