我想在utf-8中为非英语文本创建一个wordcloud(实际上,它是用哈萨克语).
文本在tm包的检查功能中完全显示.但是,当我搜索单词频率时,所有内容都显示不正确:
问题是文本显示的是编码字符而不是单词.西里尔字符正确显示.通常,wordcloud变得一团糟.
有可能以某种方式为tm函数分配编码吗?我试过这个,但文本本身很好,问题是使用tm包.
让示例文本为:
Оларман - әлемелдеріментерезесітеңңатынасқұрып,әлемкартасынанойыптұрыпорыналатынТәуелсізМемлекетатануеді.Оларман - тұрмысыбақуатты,түтінітүзуұшқан,ұрпағыертеңінесенімменқарайтынбақыттыЕлболуеді.Бізармандардыақиқатқаайналдырдық.МәңгілікЕлдіңіргетасынқаладық.Менқоғамда«Қазақелініңңлттықидеясықандайболуыкерек?»дегенсауалжиіталқығатүсетінінкөріпжүрмін.Бізүшінболашағымызғабағдарететін,ұлттыұйыстырып,ұлымақсаттарғажетелейтінидеябар.Ол - МәңгілікЕлидеясы.ТәуелсіздікпенбіргехалқымызМәңгілікМұраттарынақолжеткізді.
我的简单代码是:(基于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>?????"
Run Code Online (Sandbox Code Playgroud)
这些词应该是:"Әлем",арман","еді","мәңгілік".它们在inspect(ap.corpus)输出中正确显示.
非常感谢任何帮助!:)
问题来自默认的tokenizer.tm默认情况下使用scan_tokenizer它丢失编码(也许你应该联系维护者来添加编码参数).
scan_tokenizer function(x){scan(text = x,what ="character",quote ="",quiet = TRUE)}
一种解决方案是提供自己的标记生成器来创建矩阵术语.我正在使用strsplit:
scanner <- function(x) strsplit(x," ")
ap.tdm <- TermDocumentMatrix(ap.corpus,control=list(tokenize=scanner))
Run Code Online (Sandbox Code Playgroud)
然后你得到编码良好的结果:
findFreqTerms(ap.tdm, lowfreq=2)
[1] "?????" "???" "???" "????" "??????" "????????"
Run Code Online (Sandbox Code Playgroud)
实际上,我不同意agstudy的回答.它似乎不是一个令牌化问题.我正在使用0.6.0版的tm软件包,你的代码对我来说很合适,除了我必须使用以下方法将文本数据的编码显式设置为UTF-8:
Encoding(text) <- "UTF-8"
Run Code Online (Sandbox Code Playgroud)
下面是完整的可重现代码.只需确保将其保存在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] "?????" "???" "???" "????" "??????" "????????"
Run Code Online (Sandbox Code Playgroud)
它对我有用,希望它也适合你.