术语频率/文档反向频率(TF / IDF):加权


12

我有一个数据集,代表1000个文档以及其中出现的所有单词。因此,行代表文档,列代表单词。因此,例如,单元格代表单词j在文档i中出现的时间。现在,我必须使用tf / idf方法找到单词的“权重”,但实际上我不知道该怎么做。有人可以帮我吗?(i,j)ji


Answers:


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))。您也可以过滤掉不常用的条款。
Zach 2013年

非常清楚!非常感谢。
美国广播公司

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诸如纽约时报。据称,这是一个很小的“身体”,可以说是一个很小的图书馆,但是这个“数字”图书馆中的条目并不是随机的:第一个第五个条目涉及足球(或“社交俱乐部”的“足球”) (?)在这里),更具体地说是关于今天最伟大的团队。因此,例如,text 1从...开始

“在过去的九年中,梅西带领巴塞罗那足球俱乐部获得了国内和国际冠军,同时以似乎超乎寻常的方式打破了个人记录……”

非常好!另一方面,您肯定要跳过这三个条目之间的内容。这是一个示例(text 2):

“在得克萨斯州的几个小时内,卢比奥先生建议特朗普先生在他的裤子里撒尿,并利用非法移民来挖掘他不断的推特消息……”

那么怎样做才能避免不惜一切代价从“冲浪” text 1text 2,同时继续在文学欢喜约全能巴塞罗那足球俱乐部text 5


TC-IDF:我将每个单词都text分为长矢量。然后计算每个单词的出现频率,创建五个向量(每个单词一个text),其中仅对相应单词中遇到的单词text进行计数-属于其他texts的所有其他单词的值为零。text 1例如,在的第一个代码段中,单词“梅西”的向量的计数为1,而“特朗普”的计数为0。这就是tc部分。

IDF部分还分别为每个计算text,并导致5“载体”(我觉得我对待他们为数据帧),包含文件(可惜计数的对数变换,刚刚从零到五,给我们的小图书馆)包含给定的单词,例如:

log(No. documents1+No. docs containing a word)text01text

tc×idftext


比较器:现在只需要在这些“单词重要性向量”中执行点积即可。

可以预见,text 1with 的点积text 513.42645,而text 1v。text2仅为2.511799

笨拙的R代码(无需模仿)在这里

同样,这是一个非常基本的模拟,但是我认为它非常图形化。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.