【问题标题】:Exclude outliers in colSums for Term Document Matrix in R为 R 中的术语文档矩阵排除 colSums 中的异常值
【发布时间】:2015-05-22 10:04:30
【问题描述】:

我创建了一个术语文档矩阵“myDtm”,其中包含大量专利中包含的一组关键字。我想获得一个有序的、前 100 名、关键字频率最高的专利列表。

代码行是

myDtm <- TermDocumentMatrix(myCorpus, control = list(minWordLength = 1))
keywords <- unique(c("labor","cost","autom", "human" ,"person", "intens","reduc","machin","algorithm"))
inspect(myDtm[keywords,tail(order(colSums(v)),100)])

结果如下所示(摘录):

Terms       2435 33164 27276 1874 20447 41149 35987 21765 798 2461 19249 6822 27640
  labor        0     0     0    0     1     0     0     0   0    0     0    0     2
  cost        11     0     0    0    13     0     0     0   2    9     0    0     9
  autom        0     0     0    0    26     0     0     0   0    0     0    0     0
  human        0     0     0  270   150    16     0   279   0    0    54    0     1
  person       0    29     0    0    46     3     0     0   0    0     0    0     1
  intens       0     0     0    1     0     0     0     0   0    0     0    0    41
  reduc        8     0     8    9    13   289     2    12  12  305   292    0    44
  machin     264    77     0    0     2     0     0     2   0    0     0  323    31
  algorithm    0     0     8    0     0     0     1     0   2    0     0    0    95

问题:如何排除异常值,例如专利号。 6822?对于异常值,我指的是仅包含一两个关键字但频率非常高的专利。我想获得看起来像专利号的前 100 名专利列表。 20447 或 27640,其中包含大多数关键字。更具体地说,有没有一种说法:按关键字提及的频率对列进行排序,并确保至少 50% 的关键字被提及? ?

提前谢谢你。

【问题讨论】:

  • 离群值是什么意思?你如何定义异常值? “包含大多数关键字的位置”太模糊而无法正式化,您需要更加具体,例如:应该包含 60% 的单词还是多少?你能做的是计算每个文档的术语数,用箱线图绘制它,然后决定截止应该是什么,比如newDtm &lt;- lapply(myDtm, function(x) ifelse(x &gt; 0, 1,0)); boxplot(colSums(newDtm)
  • 一项专利,其中仅代表一个或两个关键字但经常使用,因此位于前 100 名列表中(例如专利 41149 或 2461)。我只对提及多个关键字的专利感兴趣(例如专利 20447)

标签: r subset text-mining outliers term-document-matrix


【解决方案1】:

以下内容排除了存在少于 2 个关键字的所有专利,并为您提供了一个数据框,其中仅包含存在多于 2 个关键字的专利:

myDtm[ ,c(TRUE, sapply(myDtm[-1], function(x) sum(ifelse(x > 0, 1,0)) > 2))]

如果您只想为前 100 名执行此操作,只需将上面的代码与行的过滤器(您已经在 OP 的代码中)结合起来,

如果您想要至少 50% 的关键字,您必须执行以下操作:

myDtm[ ,c(TRUE, sapply(myDtm[-1], function(x) sum(ifelse(x > 0, 1,0))/length(x) > 0.5))]

或等效:

myDtm[ ,c(TRUE, sapply(myDtm[-1], function(x) mean(ifelse(x > 0, 1,0)) >= 0.5))]

或者用函数表示法:

cbind(myDtm[1], Filter(function(x) mean(ifelse(x > 0, 1, 0)) >= 0.5, myDtm[-1]))

如果您想检查频率计数,请创建一个新的 df 并生成一些箱线图、汇总统计等(例如,1.5 * IQR 四分位数范围通常用作异常值的截止值):

table_Frequency_counts <- sapply(myDtm[-1], function(x) mean(ifelse(x > 0, 1, 0)))
boxplot(table_Frequency_counts)
summary(table_Frequency_counts)
1.5 * IQR(table_Frequency_counts)

【讨论】:

  • 嘿,非常感谢您的帮助。这已经让我更进一步了。我刚刚遇到包“textir”,其中包含一个名为“tf-idf”的函数,该函数根据频率计数而不是绝对计数对文档进行排名(请参见此处的第 9 页:cran.r-project.org/web/packages/textir/textir.pdf) - 你认为这会有所帮助吗?
  • 就像我说的,我会使用汇总统计和绘图(例如箱线图)查看频率计数的分布,然后决定一个截止值,我不知道你想展示什么,做等等。什么是合适的决定取决于很多事情,所以我身边的任何答案都只是猜测,我编辑了我的帖子,这样你就有了这样做的代码......
  • 不客气,如果确实回答了您的问题,请单击勾号接受答案,然后单击向上箭头
猜你喜欢
  • 2015-05-19
  • 1970-01-01
  • 2015-08-05
  • 2015-05-05
  • 1970-01-01
  • 2018-05-16
  • 2018-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多