R - tm包:减少术语矩阵的数量,以创建术语 - 术语邻接可视化

时间:2016-01-28 13:13:07

标签: r text-mining tm adjacency-matrix

我有问题要对我的语料库进行可重现的术语 - 术语邻接可视化,其中大约有800K字。

我关注a tutorial,其术语矩阵仅包含20个术语,因此,结果是最佳的:

Term-Term Adjacency Graph

我认为,我的问题是,我无法将我的术语矩阵缩减为,例如,我的语料库中最相关的50个术语。我从SO以外的网站发现了一条可能有帮助的评论,但我无法根据我的需求进行调整。在这个评论中,有人说,当我创建Term矩阵时,我应该使用我的界限,所以我结束了这段代码:

dtm2 <- DocumentTermMatrix(ds4.1g, control=list(wordLengths=c(1, Inf), +
bounds=list(global=c(floor(length(ds4.1g)*0.3), floor(length(ds4.1g)*0.6)))))


tdm92.1g2 <- removeSparseTerms(dtm2, 0.99)

tdm2.1g2 <- tdm92.1g2

# Creates a Boolean matrix (counts # docs w/terms, not raw # terms)
tdm3.1g <- inspect(tdm2.1g2)
tdm3.1g[tdm3.1g>=1] <- 1 

# Transform into a term-term adjacency matrix
termMatrix.1gram <- tdm3.1g %*% t(tdm3.1g)

因此,如果我正确理解这一点,我可以使Term-Matrix只获得至少在30%的文档中出现的条款,但不超过60%的条款。

然而,无论我如何定义这个边界,我的术语矩阵termMatrix.1gram总是有115K个元素,根据我的需要,它不可能实现可视化。有没有办法将这些元素限制为,仅举50个元素?

如何获取语料库?

为了澄清,我在这里写下了用于生成带有tm包的语料库的代码:

#specify where is the directory of the files.
folderdir <- paste0(dirname(myFile),"/", project, "/")

#load the corpus.
corpus <- Corpus(DirSource(folderdir, encoding = "UTF-8"), readerControl=list(reader=readPlain,language="de"))
#cleanse the corpus.
ds0.1g <- tm_map(corpus, content_transformer(tolower))
ds1.1g <- tm_map(ds0.1g, content_transformer(removeWords), stopwords("german"))
ds2.1g <- tm_map(ds1.1g, stripWhitespace)
ds3.1g <- tm_map(ds2.1g, removePunctuation)
ds4.1g <- tm_map(ds3.1g, stemDocument)
ds4.1g <- tm_map(ds4.1g, removeNumbers)
ds5.1g   <- tm_map(ds4.1g, content_transformer(removeWords), c("a", "b", "c", "d", "e", "f","g","h","i","j","k","l",
                                                               "m","n","o","p","q","r","s","t","u","v","w","x","y","z"))
#create matrixes.
tdm.1g <- TermDocumentMatrix(ds4.1g)
dtm.1g <- DocumentTermMatrix(ds4.1g)
#reduce the sparcity.
tdm89.1g <- removeSparseTerms(tdm.1g, 0.89)
tdm9.1g  <- removeSparseTerms(tdm.1g, 0.9)
tdm91.1g <- removeSparseTerms(tdm.1g, 0.91)
tdm92.1g <- removeSparseTerms(tdm.1g, 0.92)

tdm2.1g <- tdm92.1g

正如您所看到的,是使用tm包获取它的传统方法。该文本最初单独保存在计算机文件夹中的不同txt文档中。

3 个答案:

答案 0 :(得分:4)

  

我的问题是我无法将术语矩阵缩小为   比方说,50个最相关的术语

如果&#34;相关性&#34;意味着频率,你可以这样做:

library(tm)
data("crude")
tdm <- TermDocumentMatrix(crude)
dtm <- DocumentTermMatrix(crude)
head(as.matrix(tdm))
tdm <- tdm[names(tail(sort(rowSums(as.matrix(tdm))), 50)), ]
tdm
# <<TermDocumentMatrix (terms: 50, documents: 20)>>
# ...
dtm <- dtm[, names(tail(sort(colSums(as.matrix(dtm))), 50))]
inspect(dtm)
# <<DocumentTermMatrix (documents: 20, terms: 50)>>
# ...

答案 1 :(得分:1)

为减少术语数量,我更喜欢使用quanteda包,因为您可以选择要使用的术语的确切数量,然后在需要执行其他功能时将文档特征矩阵转换为其他对象类型。 / p>

topfeatures()返回排名最高的n个术语计数。通过获取向量的标签()来访问术语。

然后,您可以通过向下钻取到要素名称来对quanteda dfm进行子集化。

这是我的项目中的一个示例,我将其从超过120K的术语减少到只有16K:

library(quanteda)
length(char_vec)

# [1] 758917

train.tokens <- tokens(char_vec, what = "word", ngrams = 1)
train.tokens <- tokens_select(train.tokens, stopwords(), selection = "remove")
train.tokens.dfm <- dfm(train.tokens)
dim(train.tokens.dfm)

# [1] 758917 128560

a <- topfeatures(train.tokens.dfm, n = 16000, decreasing = TRUE, scheme = c("count", "docfreq"), groups = NULL)
# Be sure to take the labels, because those are your terms you will use to search later
b <- labels(a)
length(b)

# [1] 16000

head(b)

# [1] "say"  "can"  "much" "will" "good" "get" 

train.tokens.dfm <- train.tokens.dfm[, which(train.tokens.dfm@Dimnames$features %in% b)]
dim(train.tokens.dfm)

# [1] 758917  16000

这不是最短的答案,但效果非常好。

现在你可以把你的dfm转换成tm包中使用的dtm。

dtm <- convert(train.tokens.dfm, to = "tm", docvars = NULL)
class(dtm)

# [1] "DocumentTermMatrix"    "simple_triplet_matrix"

从这里你可以使用tm包将dtm转换为术语文档矩阵,这似乎是你需要的。

tdm <- as.TermDocumentMatrix(dtm)
class(tdm)

# [1] "TermDocumentMatrix"    "simple_triplet_matrix"

dim(tdm)

# [1]  16000 758917

从这一点开始,您应该能够执行邻接可视化。

答案 2 :(得分:0)

@agustin:如果通过&#34;相关性&#34;您的意思是预先确定的特定术语(可以命名为实体,组织或短语),您可以将其在特定术语列表中进行子集化。例如,在原油数据集中,您可能希望检查油价预计会上涨&#34;,&#34;油价预计会下降&#34;,&#34;尼日利亚冲突&#34; ,&#34;伊朗石油&#34;和#34;严重的美国冬天&#34;: tdm <- TermDocumentMatrix(crude) short.list<-c("oil prices are expected to rise", "oil prices are expected to fall", "nigerian conflict", "iran oil" and "severe US winter") tdm.short.list<-tdm[rownames(tdm)%in%short.list,] HTH