R tm包和Spark/python对文档词频任务提供不同的词汇大小

2024-06-27 02:49:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个单一列的csv,每行是一个文本文档。所有文本已规范化:

  • 全部小写
  • 没有标点符号
  • 没有数字
  • 单词之间的空格不能超过一个
  • 无标记(xml、html)

我还有一个R脚本,它在这些文档上构造文档术语矩阵,并进行一些机器学习分析。我需要把它转换成火花。你知道吗

第一步是生成文档术语矩阵,其中每个术语都有文档中的相对频率计数。问题是我使用R得到了不同的词汇表大小,与sparkapi或pythonsklearn有关(spark和python在结果上是一致的)。你知道吗

这是R的相关代码:

library(RJDBC)
library(Matrix)
library(tm)
library(wordcloud)
library(devtools)
library(lsa)
library(data.table)
library(dplyr)
library(lubridate)

corpus <- read.csv(paste(inputDir, "corpus.csv", sep="/"), stringsAsFactors=FALSE)
DescriptionDocuments<-c(corpus$doc_clean)
DescriptionDocuments <- VCorpus(VectorSource(DescriptionDocuments))
DescriptionDocuments.DTM <- DocumentTermMatrix(DescriptionDocuments, control = list(tolower = FALSE,
                                                                                    stopwords = FALSE,
                                                                                    removeNumbers = FALSE,
                                                                                    removePunctuation = FALSE,
                                                                                    stemming=FALSE))

# VOCABULARY SIZE = 83758



这是Spark(1.6.0,Scala 2.10)中的相关代码:

import org.apache.spark.ml.feature.{CountVectorizer, CountVectorizerModel, RegexTokenizer}

var corpus = sqlContext.read.format("com.databricks.spark.csv").option("header", "true").option("inferSchema", "false").load("/path/to/corpus.csv")

// RegexTokenizer splits by default on one or more spaces, which is ok
val rTokenizer = new RegexTokenizer().setInputCol("doc").setOutputCol("words")
val words = rTokenizer.transform(corpus)

val cv = new CountVectorizer().setInputCol("words").setOutputCol("tf")
val cv_model = cv.fit(words)
var dtf = cv_model.transform(words)

// VOCABULARY SIZE = 84290



我还检查了python sklearn,得到了与spark一致的结果:

import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer

corpus = pd.read_csv("/path/to/corpus.csv")
docs = corpus.loc[:, "doc"].values

def tokenizer(text):
    return text.split

cv = CountTokenizer(tokenizer=tokenizer, stop_words=None)
dtf = cv.fit_transform(docs)
print len(dtf.vocabulary_)

# VOCABULARY SIZE = 84290



我不太了解R tm package,但在我看来,默认情况下应该在空白处进行标记化。有人知道为什么我的词汇量不同吗?你知道吗


Tags: csv文档falsereadsizedoclibraryval
1条回答
网友
1楼 · 发布于 2024-06-27 02:49:20

产生这种差异的原因是创建文档术语矩阵时的默认选项。如果您选中?termFreq,您可以找到选项wordlength:

An integer vector of length 2. Words shorter than the minimum word length wordLengths[1] or longer than the maximum word length wordLengths[2] are discarded. Defaults to c(3, Inf), i.e., a minimum word length of 3 characters.

c(3,Inf)的默认设置会删除所有短于3的单词,如“at”、“in”、“I”等

这个默认值是导致tm和spark/python之间差异的原因

请参见下面示例中字长设置的差异。你知道吗

library(tm)

data("crude")

dtm <- DocumentTermMatrix(crude)
nTerms(dtm)
[1] 1266

dtm2 <- DocumentTermMatrix(crude, control = list(wordLengths = c(1, Inf)))
nTerms(dtm2)
[1] 1305

相关问题 更多 >