用語頻度/逆文書頻度(TF / IDF):重み付け


12

1000個のドキュメントとその中に表示されるすべての単語を表すデータセットがあります。したがって、行はドキュメントを表し、列は単語を表します。したがって、たとえば、セルの値は、ドキュメントで単語が出現する回数を表します。ここで、tf / idfメソッドを使用して、単語の「重み」を見つける必要がありますが、実際にはこれを行う方法がわかりません。誰かが私を助けてくれますか?jj


回答:


12

ウィキペディアには、に関する完全なトピックに関する良い記事があります。マトリックスの値は、頻度の用語です。idf:(log((total documents)/(number of docs with the term))と複数の2つの値を見つけるだけです。

Rでは、次のようにできます。

set.seed(42)
d <- data.frame(w=sample(LETTERS, 50, replace=TRUE))
d <- model.matrix(~0+w, data=d)

tf <- d
idf <- log(nrow(d)/colSums(d))
tfidf <- d

for(word in names(idf)){
  tfidf[,word] <- tf[,word] * idf[word]
}

データセットは次のとおりです。

> colSums(d)
wA wC wD wF wG wH wJ wK wL wM wN wO wP wQ wR wS wT wV wX wY wZ 
 3  1  3  1  1  1  1  2  4  2  2  1  1  3  2  2  2  4  5  5  4 
> head(d)
  wA wC wD wF wG wH wJ wK wL wM wN wO wP wQ wR wS wT wV wX wY wZ
1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0
2  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0
3  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
4  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0
5  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0  0  0  0
6  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0
> head(round(tfidf, 2))
  wA wC wD wF wG   wH wJ wK wL wM   wN wO wP   wQ wR wS wT   wV  wX  wY wZ
1  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 0.00  0  0  0 0.00 2.3 0.0  0
2  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 0.00  0  0  0 0.00 0.0 2.3  0
3  0  0  0  0  0 3.91  0  0  0  0 0.00  0  0 0.00  0  0  0 0.00 0.0 0.0  0
4  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 0.00  0  0  0 2.53 0.0 0.0  0
5  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 2.81  0  0  0 0.00 0.0 0.0  0
6  0  0  0  0  0 0.00  0  0  0  0 3.22  0  0 0.00  0  0  0 0.00 0.0 0.0  0

各用語のidfも確認できます。

> log(nrow(d)/colSums(d))
      wA       wC       wD       wF       wG       wH       wJ       wK       wL       wM       wN       wO       wP       wQ       wR       wS       wT       wV       wX       wY       wZ 
2.813411 3.912023 2.813411 3.912023 3.912023 3.912023 3.912023 3.218876 2.525729 3.218876 3.218876 3.912023 3.912023 2.813411 3.218876 3.218876 3.218876 2.525729 2.302585 2.302585 2.525729 

ご協力いただきありがとうございます!しかし、(単語全体ではなく)重みを表す各単語の値を取得することは可能ですか?これで、重みのマトリックス全体ができました。私はいくつかの特徴選択を行うと、TF / IDFフィルタ法など...使いたいんだ
ABC

定義により、@ ABC tf-idfは重みの完全なマトリックスを参照します。おそらく、idfの重みだけに興味があるでしょうlog((number of docs)/(number of docs containing the term))。また、頻度の低い用語を除外することもできます。
ザック

非常に明確な!本当に感謝。
ABC

13

パッケージtm(テキストマイニング)http://cran.r-project.org/web/packages/tm/index.htmlがあります。

#read 1000 txt articles from directory data/txt
corpus  <-Corpus(DirSource("data/txt"), readerControl = list(blank.lines.skip=TRUE));
#some preprocessing
corpus <- tm_map(corpus, removeWords, stopwords("english"))
corpus <- tm_map(corpus, stripWhitespace)
corpus <- tm_map(corpus, stemDocument, language="english")
#creating term matrix with TF-IDF weighting
terms <-DocumentTermMatrix(corpus,control = list(weighting = function(x) weightTfIdf(x, normalize = FALSE)))

#or compute cosine distance among documents
dissimilarity(tdm, method = "cosine")

Rは関数型言語であるため、コードの読み取りが難しい場合があります(たとえばxは用語)


2

コードにエラーがあります:colSumsは、単語を含むテキストの数ではなく、コーパス内の出現数を計算します。

そのようなバージョンの計算は次のようになります。

tfidf=function(mat){
  tf <- mat
  id=function(col){sum(!col==0)}
  idf <- log(nrow(mat)/apply(mat, 2, id))
  tfidf <- mat
  for(word in names(idf)){tfidf[,word] <- tf[,word] * idf[word]}
  return(tfidf)
  }

1

これを行うことができる新しいRパッケージがあります:textir:テキスト分析の逆回帰

関連するコマンドはtfidf、マニュアルの例です:

data(we8there)
## 20 high-variance tf-idf terms
colnames(we8thereCounts)[
order(-sdev(tfidf(we8thereCounts)))[1:20]]

1

私はこのパーティーに遅れていますが、tc-idfの概念で遊んでいました(実際の計算のために本を読んでいないので、「コンセプト」という言葉を強調したいです。などのパッケージを使用してより簡単に実行できます{tm: Text Mining Package})、私が得たものはこの質問に関連している可能性があります、または、いずれにしても、これは投稿するのに適した場所かもしれません


SET-UP:私が持っているコーパス5印刷媒体、から取られた長い段落text 1を通じて5ようなニューヨーク・タイムズ紙が。言われているように、それはいわば非常に小さな「ボディ」、小さな図書館です、この「デジタル」ライブラリのエントリはランダムではありません。最初5番目のエントリはフットボール(または「ソーシャルクラブ」の「サッカー」 (?)このあたり)、より具体的には今日の最高のチームについてです。したがって、たとえば、次のようにtext 1始まります...

「過去9年間で、メッシはFCバルセロナを国内および国際的なタイトルに導きましたが、個々の記録を異世界のように見せています...」

非常に素晴らしい!一方、間にある3つのエントリの内容は必ずスキップする必要があります。次に例を示します(text 2)。

「テキサス全体で数時間の間に、ルビオ氏は、トランプ氏がズボンで排尿し、不法移民を使って絶え間ないTwitterメッセージを盗み出したことを示唆した...」

だから何から「サーフィン」すべてのコストで回避するために行うにtext 1するtext 2には、続けながらは全能バルセロナFCについての文献に喜ぶためにtext 5


TC-IDF:すべての単語textを長いベクトルに分離しました。次に、各単語の頻度を数え、5つのベクトル(各に1つ)を作成textし、対応する単語のみtextがカウントtextされます。他のsに属する他のすべての単語はゼロに評価されました。text 1たとえば、の最初のスニペットでは、そのベクトルは「メッシ」という単語に対して1のカウントを持ち、「トランプ」は0を持ちます。これはtcの部分でした。

IDFの部分もそれぞれに別々に計算されたtext私たちの小さなライブラリ与え、ちょうどゼロから5に、悲しげに文書(の数の対数変換を含む、(私はデータフレームとしてそれらを扱うと思う)、そして5「ベクター」の結果)のように特定の単語を含む:

ログいいえ文書1+いいえ。単語を含むドキュメントtext01text

のエントリごとの乗算 tc×idfすべてのためにtextしたすべての単語の重要性 -ライブラリ項目のそれぞれについて、ローカルに普及し、世界的に珍しい言葉


比較:今では、これらの「単語の重要度のベクトル」の間でドット積を実行するだけの問題でした。

予想どおり、text 1with の内積text 5はvでしたが13.42645text 1v text2のみでした2.511799

不格好なRコード(模倣するものはありません)はこちらです。

繰り返しますが、これは非常に初歩的なシミュレーションですが、私はそれが非常にグラフィックだと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.