当 doc_term_matrix 至少有一行所有元素都为零时使用 LDAvis
Using LDAvis when doc_term_matrix has at least one row that all elements are zero
我正在使用 LDA 进行主题建模:
dtm <- DocumentTermMatrix(docs)
但是,dtm
中的所有元素都为零的行。所以我按照 here
中的说明进行操作
ui = unique(dtm$i)
dtm.new = dtm[ui,]
然后,LDA 工作,我有主题和一切。我的下一次尝试是使用 here 中推荐的 LDAvis。源代码:
topicmodels_json_ldavis <- function(fitted, corpus, doc_term){
# Required packages
library(topicmodels)
library(dplyr)
library(stringi)
library(tm)
library(LDAvis)
# Find required quantities
phi <- posterior(fitted)$terms %>% as.matrix
theta <- posterior(fitted)$topics %>% as.matrix
vocab <- colnames(phi)
doc_length <- vector()
for (i in 1:length(corpus)) {
temp <- paste(corpus[[i]]$content, collapse = ' ')
doc_length <- c(doc_length, stri_count(temp, regex = '\S+'))
}
temp_frequency <- inspect(doc_term)
freq_matrix <- data.frame(ST = colnames(temp_frequency),
Freq = colSums(temp_frequency))
rm(temp_frequency)
# Convert to json
json_lda <- LDAvis::createJSON(phi = phi, theta = theta,
vocab = vocab,
doc.length = doc_length,
term.frequency = freq_matrix$Freq)
return(json_lda)
}
当我调用 topicmodels_json_ldavis
函数时,我收到此错误:
Length of doc.length not equal to the number of rows in theta;
both should be equal to the number of documents in the data.
我检查了 theta
和 doc.length
的长度。它们是不同的。我假设是因为我通过了语料库 (docs
),它使 dtm
具有(至少)零行。为了使语料库与 doc_term_matrix 匹配,我决定按照 here 中的建议从 dtm.new
制作一个新语料库。源代码:
dtm2list <- apply(dtm, 1, function(x) {
paste(rep(names(x), x), collapse=" ")
})
myCorp <- VCorpus(VectorSource(dtm2list))
我什至用 dtm.new 创建了一个新的 ldaOut 并将以下参数传递给 topicmodels_json_ldavis
:ldaOut22, myCorp, dtm.new
我仍然收到 theta
和 doc.length
必须具有相同长度的错误消息。
我遇到了完全相同的问题,我能够删除具有所有零向量的行以进行 LDA 分析,但随后陷入稀疏矩阵的行数不再匹配 LDAvis 文档的行数。我已经解决了,不幸的是只针对 Python,但您可以使用以下方法作为起点:
让我们先看看我得到了什么:
print(f'The tf matrix:\n {cvz.toarray()[:100]}\n')
sparseCountMatrix = np.array(cvz.toarray())
print(f'Number of non-zero vectors: {len(x[x>0])} Number of zero vectors: {len(x[x==0])}\n')
print(f'Have a look at the non-zero vectors:\n{x[x>0][:200]}\n')
print(f'This is our sparse matrix with {x.shape[0]} (# of documents) by {x.shape[1]} (# of terms in the corpus):\n{x.shape}')
输出:
The tf matrix:
[[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]]
Number of non-zero vectors: 4721 Number of zero vectors: 232354
Have a look at the non-zero vectors:
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
This is our sparse matrix with 545 (# of documents) by 435 (# of terms in the corpus):
(545, 435)
有多少行包含全零向量?
len(list(np.array(sparseCountMatrix[(sparseCountMatrix==0).all(1)])))
输出:12
有多少行包含至少一个非零向量?
len(list(np.array(sparseCountMatrix[~(sparseCountMatrix==0).all(1)])))
输出:533
删除包含所有零向量的 12 行用于 LDA 分析:
cleanedSparseCountMatrix = np.array(sparseCountMatrix[~(sparseCountMatrix==0).all(1)])
同时从原始 Pandas 系列(标记)中删除这些文档,因此文档计数与稀疏矩阵行计数匹配,这对于使用 pyLDAVis 可视化 LDA 结果很重要:
首先,要获取全为零向量的行的索引位置,使用np.where
:
indexesToDrop = np.where((sparseCountMatrix==0).all(1))
print(f"Indexes with all zero vectors: {indexesToDrop}\n")
输出:
Indexes with all zero vectors: (array([ 47, 77, 88, 95, 106, 109, 127, 244, 363, 364, 367, 369],
dtype=int64),)
其次,使用此索引列表删除 Pandas 系列中的原始行 series.drop
:
data_tokens_cleaned = data['tokens'].drop(data['tokens'].index[indexesToDrop])
清理标记的新长度(应匹配稀疏矩阵长度!):
len(data_tokens_cleaned)
输出:
533
这是我们清理过的稀疏矩阵,准备好进行 LDA 分析:
print(cleanedSparseCountMatrix.shape)
输出:(533, 435)
我正在使用 LDA 进行主题建模:
dtm <- DocumentTermMatrix(docs)
但是,dtm
中的所有元素都为零的行。所以我按照 here
ui = unique(dtm$i)
dtm.new = dtm[ui,]
然后,LDA 工作,我有主题和一切。我的下一次尝试是使用 here 中推荐的 LDAvis。源代码:
topicmodels_json_ldavis <- function(fitted, corpus, doc_term){
# Required packages
library(topicmodels)
library(dplyr)
library(stringi)
library(tm)
library(LDAvis)
# Find required quantities
phi <- posterior(fitted)$terms %>% as.matrix
theta <- posterior(fitted)$topics %>% as.matrix
vocab <- colnames(phi)
doc_length <- vector()
for (i in 1:length(corpus)) {
temp <- paste(corpus[[i]]$content, collapse = ' ')
doc_length <- c(doc_length, stri_count(temp, regex = '\S+'))
}
temp_frequency <- inspect(doc_term)
freq_matrix <- data.frame(ST = colnames(temp_frequency),
Freq = colSums(temp_frequency))
rm(temp_frequency)
# Convert to json
json_lda <- LDAvis::createJSON(phi = phi, theta = theta,
vocab = vocab,
doc.length = doc_length,
term.frequency = freq_matrix$Freq)
return(json_lda)
}
当我调用 topicmodels_json_ldavis
函数时,我收到此错误:
Length of doc.length not equal to the number of rows in theta;
both should be equal to the number of documents in the data.
我检查了 theta
和 doc.length
的长度。它们是不同的。我假设是因为我通过了语料库 (docs
),它使 dtm
具有(至少)零行。为了使语料库与 doc_term_matrix 匹配,我决定按照 here 中的建议从 dtm.new
制作一个新语料库。源代码:
dtm2list <- apply(dtm, 1, function(x) {
paste(rep(names(x), x), collapse=" ")
})
myCorp <- VCorpus(VectorSource(dtm2list))
我什至用 dtm.new 创建了一个新的 ldaOut 并将以下参数传递给 topicmodels_json_ldavis
:ldaOut22, myCorp, dtm.new
我仍然收到 theta
和 doc.length
必须具有相同长度的错误消息。
我遇到了完全相同的问题,我能够删除具有所有零向量的行以进行 LDA 分析,但随后陷入稀疏矩阵的行数不再匹配 LDAvis 文档的行数。我已经解决了,不幸的是只针对 Python,但您可以使用以下方法作为起点:
让我们先看看我得到了什么:
print(f'The tf matrix:\n {cvz.toarray()[:100]}\n')
sparseCountMatrix = np.array(cvz.toarray())
print(f'Number of non-zero vectors: {len(x[x>0])} Number of zero vectors: {len(x[x==0])}\n')
print(f'Have a look at the non-zero vectors:\n{x[x>0][:200]}\n')
print(f'This is our sparse matrix with {x.shape[0]} (# of documents) by {x.shape[1]} (# of terms in the corpus):\n{x.shape}')
输出:
The tf matrix:
[[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]]
Number of non-zero vectors: 4721 Number of zero vectors: 232354
Have a look at the non-zero vectors:
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
This is our sparse matrix with 545 (# of documents) by 435 (# of terms in the corpus):
(545, 435)
有多少行包含全零向量?
len(list(np.array(sparseCountMatrix[(sparseCountMatrix==0).all(1)])))
输出:12
有多少行包含至少一个非零向量?
len(list(np.array(sparseCountMatrix[~(sparseCountMatrix==0).all(1)])))
输出:533
删除包含所有零向量的 12 行用于 LDA 分析:
cleanedSparseCountMatrix = np.array(sparseCountMatrix[~(sparseCountMatrix==0).all(1)])
同时从原始 Pandas 系列(标记)中删除这些文档,因此文档计数与稀疏矩阵行计数匹配,这对于使用 pyLDAVis 可视化 LDA 结果很重要:
首先,要获取全为零向量的行的索引位置,使用np.where
:
indexesToDrop = np.where((sparseCountMatrix==0).all(1))
print(f"Indexes with all zero vectors: {indexesToDrop}\n")
输出:
Indexes with all zero vectors: (array([ 47, 77, 88, 95, 106, 109, 127, 244, 363, 364, 367, 369],
dtype=int64),)
其次,使用此索引列表删除 Pandas 系列中的原始行 series.drop
:
data_tokens_cleaned = data['tokens'].drop(data['tokens'].index[indexesToDrop])
清理标记的新长度(应匹配稀疏矩阵长度!):
len(data_tokens_cleaned)
输出:
533
这是我们清理过的稀疏矩阵,准备好进行 LDA 分析:
print(cleanedSparseCountMatrix.shape)
输出:(533, 435)