编辑:新包text2vec非常好,并且很好地解决了这个问题(和许多其他问题).
关于github 插图的CRAN text2vec上的text2vec,用于说明ngram标记化
我在R中有一个非常大的文本数据集,我已将其作为字符向量导入:
#Takes about 15 seconds
system.time({
set.seed(1)
samplefun <- function(n, x, collapse){
paste(sample(x, n, replace=TRUE), collapse=collapse)
}
words <- sapply(rpois(10000, 3) + 1, samplefun, letters, '')
sents1 <- sapply(rpois(1000000, 5) + 1, samplefun, words, ' ')
})
Run Code Online (Sandbox Code Playgroud)
我可以将此字符数据转换为词袋表示,如下所示:
library(stringi)
library(Matrix)
tokens <- stri_split_fixed(sents1, ' ')
token_vector <- unlist(tokens)
bagofwords <- unique(token_vector)
n.ids <- sapply(tokens, length)
i <- rep(seq_along(n.ids), n.ids)
j <- match(token_vector, bagofwords)
M <- sparseMatrix(i=i, j=j, x=1L)
colnames(M) <- bagofwords
Run Code Online (Sandbox Code Playgroud)
所以R可以在大约3秒钟内将1,000,000,000个短句矢量化为一个单词表示形式(不错!):
> M[1:3, …Run Code Online (Sandbox Code Playgroud) 我正在阅读 Levy 等人的论文“Improving Distributional Comparison\nwith Lessons Learned from Word Embeddings”,在讨论他们的超参数时,他们说:
\n\n\n\n\n向量归一化 (nrm)正如第 2 节中提到的,所有向量(即 W\xe2\x80\x99s 行)都归一化为单位长度(L2 归一化),使点积运算等效于余弦相似度。
\n
然后我想起sim2Rtext2vec包中向量相似度函数的默认值首先是 L2 范数向量:
sim2(x, y = NULL, method = c("cosine", "jaccard"), norm = c("l2", "none"))\nRun Code Online (Sandbox Code Playgroud)\n\n所以我想知道,归一化和余弦(无论是在 text2vec 方面还是一般情况下)的动机可能是什么。我尝试阅读 L2 范数,但大多数情况下它是在使用欧几里德距离之前进行标准化的背景下出现的。我(令人惊讶地)找不到任何关于在词向量空间/嵌入的余弦相似性的情况下是否推荐或反对 L2 范数的任何信息。而且我不太具备计算分析差异的数学技能。
\n\n所以这里有一个问题,意味着在从文本数据学习的词向量空间的背景下(要么只是可能由 tfidf、ppmi 等加权的共现矩阵;或者像 GloVe 这样的嵌入),并计算词相似度(目标是当然使用最能反映现实世界单词相似性的向量空间+度量)。
简而言之,在计算向量/单词之间的余弦相似度之前,是否有任何理由(不)在单词特征矩阵/术语共现矩阵上使用 L2 范数?
我在R中使用text2vec并且难以编写一个与text2vec包中的itoken函数一起使用的词干函数.text2vec文档建议了这个词干功能:
stem_tokenizer1 =function(x) {
word_tokenizer(x) %>% lapply(SnowballC::wordStem(language='en'))
}
Run Code Online (Sandbox Code Playgroud)
但是,此功能不起作用.这是我运行的代码(借用之前的stackoverflow答案):
library(text2vec)
library(data.table)
library(SnowballC)
data("movie_review")
train_rows = 1:1000
prepr = tolower
stem_tokenizer1 =function(x) {
word_tokenizer(x) %>% lapply(SnowballC::wordStem(language='en'))
}
tok = stem_tokenizer1
it <- itoken(movie_review$review[train_rows], prepr, tok, ids = movie_review$id[train_rows])
Run Code Online (Sandbox Code Playgroud)
这是它产生的错误:
错误{:argument"words"缺失,没有默认值
我认为问题是wordStem需要一个字符向量,但是word_tokenizer会产生一个字符向量列表.
mr<-movie_review$review[1]
stem_mr1<-stem_tokenizer1(mr)
Run Code Online (Sandbox Code Playgroud)
SnowballC中的错误:: wordStem(language ="en"):缺少参数"words",没有默认值
为了解决这个问题,我编写了这个词干函数:
stem_tokenizer2 = function(x) {
list(unlist(word_tokenizer(x)) %>% SnowballC::wordStem(language='en') )
}
Run Code Online (Sandbox Code Playgroud)
但是,此函数不适用于create_vocabulary函数.
data("movie_review")
train_rows = 1:1000
prepr = tolower
stem_tokenizer2 = function(x) {
list(unlist(word_tokenizer(x)) %>% SnowballC::wordStem(language='en') )
}
tok = stem_tokenizer2
it <- itoken(movie_review$review[train_rows], prepr, tok, …Run Code Online (Sandbox Code Playgroud) 我正在使用 GloVe 词嵌入将文本数据的分类模型分为两类(即将每个评论分为两类)。我有两列,一列包含文本数据(评论),另一列是二进制目标变量(评论是否可操作)。我能够使用 text2vec 文档中的以下代码为文本数据生成 Glove 词嵌入。
glove_model <- GlobalVectors$new(word_vectors_size = 50,vocabulary =
glove_pruned_vocab,x_max = 20L)
#fit model and get word vectors
word_vectors_main <- glove_model$fit_transform(glove_tcm,n_iter = 20,convergence_tol=-1)
word_vectors_context <- glove_model$components
word_vectors <- word_vectors_main+t(word_vectors_context)
Run Code Online (Sandbox Code Playgroud)
如何构建模型并生成对测试数据的预测?
我正在R中构建一个语言模型,根据前面的单词预测句子中的下一个单词.目前我的模型是一个简单的ngram模型,带有Kneser-Ney平滑.它通过在训练集中找到具有最大概率(频率)的ngram来预测下一个字,其中平滑提供了一种内插低阶ngrams的方法,这在高阶ngram具有低频率并且可能不提供可靠预测的情况下是有利的. .虽然这种方法工作得相当好,但是在n-gram无法捕获上下文的情况下它会失败.例如,"外面温暖而阳光充足,让我们去......"和"外面寒冷和下雨,让我们去......"将提出相同的预测,因为没有捕捉到天气的背景在最后的n-gram中(假设n <5).
我正在寻找更高级的方法,我找到了text2vec包,它允许将单词映射到向量空间,其中具有相似含义的单词用相似(近似)向量表示.我有一种感觉,这种表示可能有助于下一个单词预测,但我无法弄清楚如何定义训练任务.我的问题是,如果text2vec是用于下一个单词预测的正确工具,如果是,那么可以用于此任务的合适预测算法是什么?
我正在尝试tm通过text2vecLDA 实现从-package运行 AssociatedPress 数据集。
我面临的问题是数据类型的不兼容:AssociatedPressis atm::DocumentTermMatrix又是slam::simple_triplet_matrix. text2vec然而期望输入x 到text2vec::lda$fit_transform(x = ...)要Matrix::dgTMatrix。
因此,我的问题是:有没有办法强制DocumentTermMatrix接受text2vec?
最小(失败)示例:
library('tm')
library('text2vec')
data("AssociatedPress", package="topicmodels")
dtm <- AssociatedPress[1:10, ]
lda_model = LDA$new(
n_topics = 10,
doc_topic_prior = 0.1,
topic_word_prior = 0.01
)
doc_topic_distr =
lda_model$fit_transform(
x = dtm,
n_iter = 1000,
convergence_tol = 0.001,
n_check_convergence = 25,
progressbar = FALSE
)
Run Code Online (Sandbox Code Playgroud)
...这使:
base::rowSums(x, na.rm = na.rm, dims = dims, …
我使用text2vec从专有文本数据集合中生成自定义单词嵌入,其中包含许多行业专用术语(因此像谷歌那样的库存嵌入将无效).这些类比很有用,但是我很难应用嵌入来评估新数据.我想使用我已经训练过的嵌入来理解新数据中的关系.我正在使用的方法(如下所述)似乎令人费解,而且速度很慢.有更好的方法吗?也许我已经错过了一些内置于包装中的东西?
这是我的方法(由于我使用专有数据源,我可以生成最接近可重现代码的方法):
d =包含新数据的列表.每个元素都是类字符
vecs =从text2vec的手套实现中获得的单词矢量化
new_vecs <- sapply(d, function(y){
it <- itoken(word_tokenizer(y), progressbar=FALSE) # for each statement, create an iterator punctuation
voc <- create_vocabulary(it, stopwords= tm::stopwords()) # for each document, create a vocab
vecs[rownames(vecs) %in% voc$vocab$terms, , drop=FALSE] %>% # subset vecs for the words in the new document, then
colMeans # find the average vector for each document
}) %>% t # close y function and sapply, then transpose to return matrix w/ one row for each statement …Run Code Online (Sandbox Code Playgroud) text2vec包中的LDA主题建模非常棒.它确实比topicmodel快得多
但是,我不知道如何获得每个文档属于每个主题的概率,如下例所示:
V1 V2 V3 V4
1 0.001025237 7.89E-05 7.89E-05 7.89E-05
2 0.002906977 0.002906977 0.014534884 0.002906977
3 0.003164557 0.003164557 0.003164557 0.003164557
4 7.21E-05 7.21E-05 0.000360334 7.21E-05
5 0.000804433 8.94E-05 8.94E-05 8.94E-05
6 5.63E-05 5.63E-05 5.63E-05 5.63E-05
7 0.001984127 0.001984127 0.001984127 0.001984127
8 0.003515625 0.000390625 0.000390625 0.000390625
9 0.000748503 0.000748503 0.003742515 0.003742515
10 0.000141723 0.00297619 0.000141723 0.000708617
Run Code Online (Sandbox Code Playgroud)
这是text2vec lda的代码
ss2 <- as.character(stressor5$weibo)
seg2 <- mmseg4j(ss2)
# Create vocabulary. Terms will be unigrams (simple words).
it_test = itoken(seg2, progressbar = FALSE)
vocab2 …Run Code Online (Sandbox Code Playgroud)