R tm 包和西里尔文字

标签 r encoding text-mining tm

我正在尝试使用 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] "Его"        "богатство," "знатный"    "род"        "и"          "св" 

糟糕...似乎 R 核心函数 scan() 将俄语小写字母 'я' 视为 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"

最佳答案

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 function 的性能。可能这是一个错误,我不知道,但每次调用它时,都必须使用 enc2native 将文本转换为 native 编码。 (当然,如果您的文本语言不是英语)。

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)))

关于R tm 包和西里尔文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20781499/

相关文章:

mysql - 使用来自服务器的 MySQL 数据更新 Shiny R 中的 selectInput

node.js - 在 NodeJS 中取消转义字符串

php - mysql + php编码

java - 大规模机器学习

r - 查看包中是否存在变量/函数?

R:尝试为 Weibull 分布创建 Q-Q 图,出现错误 "NAs Introduced by Coersion"

r - 在 dplyr 中使用 get() 而不是 SE 有什么缺点吗?

Perl:从 cp1251 转换为 utf8

R:按索引合并文本文档

r - 在 R 中使用西类牙语文本创建语料库