我正在尝试使用tm包对俄语文本进行一些文本挖掘并遇到一些问题。
预处理速度在很大程度上取决于编码。
library(tm)
rus_txt<-paste(readLines('http://lib.ru/LITRA/PUSHKIN/dubrowskij.txt',encoding='cp1251'), collapse=' ')
object.size(rus_txt)
eng_txt<-paste(readLines('http://www.gutenberg.org/cache/epub/1112/pg1112.txt',encoding='UTF-8'), collapse=' ')
object.size(eng_txt)
# text sizes nearly identical
rus_txt_utf8<-iconv(rus_txt, to='UTF-8')
system.time(rus_txt_lower<-tolower(rus_txt_utf8))
#3.17 0.00 3.19
system.time(rus_txt_lower<-tolower(eng_txt))
#0.03 0.00 0.03
system.time(rus_txt_lower<-tolower(rus_txt))
#0.07 0.00 0.08
快40倍!而对于大型语料库,差异高达500倍!
让我们尝试标记一些文本(TermDocumentMatrix中使用的这个函数):
some_text<-"Несколько лет тому назад в одном из своих поместий жил старинный
русской барин, Кирила Петрович Троекуров. Его богатство, знатный род и связи
давали ему большой вес в губерниях, где находилось его имение. Соседи рады
были угождать малейшим его прихотям; губернские чиновники трепетали при его
имени; Кирила Петрович принимал знаки подобострастия как надлежащую дань;
дом его всегда был полон гостями, готовыми тешить его барскую праздность,
разделяя шумные, а иногда и буйные его увеселения. Никто не дерзал
отказываться от его приглашения, или в известные дни не являться с должным
почтением в село Покровское."
scan_tokenizer(some_text)
#[1] "Несколько" "лет" "тому" "назад" "в" "одном" "из" "своих"
# [9] "поместий" "жил" "старинный" "русской" "барин," "Кирила" "Петрович" "Троекуров."
#[17] "Его" "богатство," "знатный" "род" "и" "св"
oops ...似乎R核心功能扫描()将俄语小写字母'я'视为EOF。我尝试了不同的编码,但我没有回答如何解决这个问题。
好的,让我们尝试删除标点符号:
removePunctuation("жил старинный русской барин, Кирила Петрович Троекуров")
#"жил старинный русской барин Кирила Петрови Троекуров"
嗯......字母'ч'在哪里?好的UTF-8编码可以正常工作,但需要一些时间才能找到它。
我也遇到了removeWords()函数性能问题但无法重现它。
主要问题是:如何阅读和标记带有字母'я'的文字?
我的语言环境:
Sys.getlocale()
#[1] "LC_COLLATE=Russian_Russia.1251;LC_CTYPE=Russian_Russia.1251;LC_MONETARY=Russian_Russia.1251;LC_NUMERIC=C;LC_TIME=Russian_Russia.1251"
答案 0 :(得分:2)
1)问题:如何阅读和标记带有字母'я'的文字? 回答:尝试编写自己的标记生成器并使用它。例如:
my_tokenizer <- function (x)
{
strsplit(iconv(x, to='UTF-8'), split='([[:space:]]|[[:punct:]])+', perl=F)[[1]]
}
TDM <- TermDocumentMatrix(corpus,control=list(tokenize=my_tokenizer, weighting=weightTf, wordLengths = c(3,10)))
2)性能在很大程度上取决于 tolower功能的性能。可能这是一个错误,我不知道,但每次调用它时,你必须使用enc2native将文本转换为本机编码。 (当然,如果你的文字不是英文)。
doc.corpus <- Corpus(VectorSource(enc2native(textVector)))
此外,在您的语料库上进行所有文本预处理后,您必须再次转换它。 (这是因为TermDocumentMatrix和 tm 包中的许多其他功能在内部使用 tolower )
tm_map(doc.corpus, enc2native)
所以你的全部流程看起来像这样:
createCorp <-function(textVector)
{
doc.corpus <- Corpus(VectorSource(enc2native(textVector)))
doc.corpus <- tm_map(doc.corpus, tolower)
doc.corpus <- tm_map(doc.corpus, removePunctuation)
doc.corpus <- tm_map(doc.corpus, removeWords, stopwords("russian"))
doc.corpus <- tm_map(doc.corpus, stemDocument, "russian")
doc.corpus <- tm_map(doc.corpus, stripWhitespace)
return(tm_map(doc.corpus, enc2native))
}
my_tokenizer <- function (x)
{
strsplit(iconv(x, to='UTF-8'), split='([[:space:]]|[[:punct:]])+', perl=F)[[1]]
}
TDM <- TermDocumentMatrix(corpus,control=list(tokenize=my_tokenizer, weighting=weightTf, wordLengths = c(3,10)))