R tm包:UTF-8文本

5
我想为UTF-8编码的非英文文本(实际上是哈萨克语)创建一个词云。
在tm包的检查功能中,文本显示完全正确。然而,当我搜索单词频率时,一切都显示不正确:
问题在于文本显示为编码字符而不是单词。西里尔字符显示正确。因此,词云变得一团糟。
有没有可能以某种方式为tm函数分配编码?我尝试了this,但是文本本身没问题,问题出在使用tm包上。
让我们用一个样本文本:

One dream was to create an independent state that would stand equal with other countries of the world, taking its rightful place on the world map - a state that would be a source of pride for its people, with a rich history and a bright future. We have realized this dream. We have created the sovereign state of Kazakhstan. We have defined our national idea as "Mangilik El" (Eternal Nation). This is an idea that unites us, helps us to consolidate our nation, and directs us towards great goals. Together with independence, we have achieved the realization of the eternal aspirations of our people.

我的简单代码如下: (基于onertipaday.blogspot.com的教程:)

require(tm)
require(wordcloud)
text<-readLines("text.txt", encoding="UTF-8")
ap.corpus <- Corpus(DataframeSource(data.frame(text)))
ap.corpus <- tm_map(ap.corpus, removePunctuation)
ap.corpus <- tm_map(ap.corpus, tolower)
ap.tdm <- TermDocumentMatrix(ap.corpus)
ap.m <- as.matrix(ap.tdm)
ap.v <- sort(rowSums(ap.m),decreasing=TRUE)
ap.d <- data.frame(word = names(ap.v),freq=ap.v)
table(ap.d$freq)

1  2 
44  4 

findFreqTerms(ap.tdm, lowfreq=2)

[1] "<U+04D9>лем"            "арман"                  "еді"                   
[4] "м<U+04D9><U+04A3>гілік"

那些单词应该是:“Әлем”,“арман”,“еді”,“мәңгілік”。它们在inspect(ap.corpus)输出中正确显示。非常感谢任何帮助! :)
2个回答

7
问题来自于默认的分词器。默认情况下,tm 使用 scan_tokenizer,它会丢失编码(也许您应该联系维护者添加一个编码参数)。

scan_tokenizer函数(x) { scan(text = x, what = "character", quote = "", quiet = TRUE) }

一个解决方案是提供您自己的分词器来创建矩阵术语。我正在使用strsplit
scanner <- function(x) strsplit(x," ")
ap.tdm <- TermDocumentMatrix(ap.corpus,control=list(tokenize=scanner))

然后你会得到一个经过良好编码的结果:
findFreqTerms(ap.tdm, lowfreq=2)
[1] "арман"    "біз"      "еді"      "әлем"     "идеясы"   "мәңгілік"

哦,我的天啊!谢谢你!非常感谢! - Asayat
@Asayat 没问题!我只是好奇,问题中的文本是关于什么的?很难翻译哈萨克语! - agstudy
1
这是我们总统年度演讲的一部分。该段落阐述了我们国家梦想成为自由和发达世界的一部分成真,用了太多花哨的词语 :) 尴尬的是,在最后他说我们的主要民族理念应该是某种“永恒之国”,如果考虑到我们独立以来只有一位总统,他可能意味着某种不同的永恒 :) - Asayat
1
只是想分析不同时间段的年度演讲,并了解他的主要观点 :) 同时,比较相同文本但使用不同语言(在这种情况下是俄语和哈萨克语)的世界云图也很有趣。 - Asayat

5

实际上,我不同意agstudy的答案。这似乎不是一个分词器问题。我正在使用tm包的0.6.0版本,您的代码对我来说完全正常,只是我必须显式地将文本数据的编码设置为UTF-8:

Encoding(text)  <- "UTF-8"

以下是完整的可复制代码。确保您将其保存在使用UTF-8编码的文件中,并使用source()运行它; 不要使用source.with.encoding(),否则会引发错误。

text  <- "Ол арман – әлем елдерімен терезесі тең қатынас құрып, әлем картасынан ойып тұрып орын алатын Тәуелсіз Мемлекет атану еді. Ол арман – тұрмысы бақуатты, түтіні түзу ұшқан, ұрпағы ертеңіне сеніммен қарайтын бақытты Ел болу еді. Біз армандарды ақиқатқа айналдырдық. Мәңгілік Елдің іргетасын қаладық. Мен қоғамда «Қазақ елінің ұлттық идеясы қандай болуы керек?» деген сауал жиі талқыға түсетінін көріп жүрмін. Біз үшін болашағымызға бағдар ететін, ұлтты ұйыстырып, ұлы мақсаттарға жетелейтін идея бар. Ол – Мәңгілік Ел идеясы. Тәуелсіздікпен бірге халқымыз Мәңгілік Мұраттарына қол жеткізді."

Encoding(text)
# [1] "unknown"

Encoding(text)  <- "UTF-8"
# [1] "UTF-8"

ap.corpus <- Corpus(DataframeSource(data.frame(text)))
ap.corpus <- tm_map(ap.corpus, removePunctuation)
ap.corpus <- tm_map(ap.corpus, content_transformer(tolower))

content(ap.corpus[[1]])

ap.tdm <- TermDocumentMatrix(ap.corpus)

ap.m <- as.matrix(ap.tdm)
ap.v <- sort(rowSums(ap.m),decreasing=TRUE)
ap.d <- data.frame(word = names(ap.v),freq=ap.v)

print(table(ap.d$freq))
# 1  2  3 
# 62  5  1 

print(findFreqTerms(ap.tdm, lowfreq=2))
# [1] "арман"    "біз"      "еді"      "әлем"     "идеясы"   "мәңгілік"

对我有用,希望对你也有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接