我有一份推文列表,我想只保留英语的那些。
我该怎么做?
textcat
包可以实现这一功能。它可以检测74种“语言”(更准确地说,是语言/编码组合),使用其他扩展还可以检测更多。有关详细信息和示例可在此免费获取的文章中找到:
Hornik,K.,Mair,P.,Rauch,J.,Geiger,W.,Buchta,C.和Feinerer,I. R中用于基于n-gram的文本分类的textcat软件包。《统计软件杂志》,第52期,1-17。
以下是摘要:
确定所使用的语言通常是大多数自然语言处理任务中的第一步。在文献中讨论的各种语言识别方法中,采用基于字符n-gram频率的Cavnar和Trenkle(1994)方法的方法尤其成功。本文介绍了基于n-gram的文本分类的R扩展包textcat,该包实现了Cavnar和Trenkle方法以及旨在消除原始方法冗余的降低n-gram方法。从Wikipedia页面中获得的多语言语料库用于说明包的功能和提供的语言识别方法的性能。
以下是其中一个示例:
library("textcat")
textcat(c(
"This is an English sentence.",
"Das ist ein deutscher Satz.",
"Esta es una frase en espa~nol."))
[1] "english" "german" "spanish"
在之前的答案中,cldr
包已不可用于CRAN且安装可能很困难。然而,Google(Chromium)的cld
库现在通过其他专用包和在R中可用。
在多种欧洲语言的数千条推文测试后,我可以说,在可选项中,textcat
是迄今为止最不可靠的。使用textcat
时,我经常会得到错误识别为“middle_frisian”,“rumantsch”,“sanskrit”或其他不寻常语言的推文。它在其他类型的文本中可能相对较好,但我认为textcat
对于推文来说相当糟糕。
cld2
总体上似乎仍然优于cld3
。如果您想要一个安全的方法来仅包含英语推文,您仍然可以运行和,并仅保留被两者都识别为英语的推文。
以下示例基于Twitter搜索,通常会返回许多不同语言的结果,但始终包括一些英文推文。
if (!require("pacman")) install.packages("pacman") # for package manangement
pacman::p_load("tidyverse")
pacman::p_load("textcat")
pacman::p_load("cld2")
pacman::p_load("cld3")
pacman::p_load("rtweet")
punk <- rtweet::search_tweets(q = "punk") %>% mutate(textcat = textcat(x = text), cld2 = cld2::detect_language(text = text, plain_text = FALSE), cld3 = cld3::detect_language(text = text)) %>% select(text, textcat, cld2, cld3)
View(punk)
# Only English tweets
punk %>% filter(cld2 == "en" & cld3 == "en")
最后,如果这个问题特别涉及推文,那么我应该明确一个显而易见的事情:Twitter通过API为推文提供了自己的语言检测,并且似乎非常准确(对于非常短的推文可能理解能力稍差)。因此,如果你运行rtweet::search_tweets(q = "punk")
,你会发现结果data.frame包括一个“lang”列。如果你通过API获取推文,那么你可以相信Twitter自己的检测系统比上面提到的其他解决方案更可靠(这些解决方案适用于其他文本)。
尝试使用http://cran.r-project.org/web/packages/cldr/,它将Google Chrome的语言检测引入了R。
#install from archive
url <- "http://cran.us.r-project.org/src/contrib/Archive/cldr/cldr_1.1.0.tar.gz"
pkgFile<-"cldr_1.1.0.tar.gz"
download.file(url = url, destfile = pkgFile)
install.packages(pkgs=pkgFile, type="source", repos=NULL)
unlink(pkgFile)
# or devtools::install_version("cldr",version="1.1.0")
#usage
library(cldr)
demo(cldr)
cldr::detectLanguage("Their debut album")
== 100% 印度尼西亚语 - geotheory在R中的一种方法是保留一个英语单词的文本文件。我有几个这样的文件,其中包括来自http://www.sil.org/linguistics/wordlists/english/的一个。在获取.txt文件后,您可以使用该文件与每个推文进行匹配。类似于:
lapply(tweets, function(x) EnglishWordComparisonList %in% x)
如果你想判断一段文本是否为英语,你需要选定一个阈值来进行截断(这里我随意选择了0.06)。
EnglishWordComparisonList<-as.vector(source(path to the list you downloaded above))
Englishinator<-function(tweet, threshold = .06) {
TWTS <- which((EnglishWordComparisonList %in% tweet)/length(tweet) > threshold)
tweet[TWTS]
#or tweet[TWTS,] if the original tweets is a data frame
}
lapply(tweets, Englishinator)
我实际上没有使用过这个,因为我在研究中使用英语单词列表的方式不同,但我认为这应该可以。
cld2
远远比其他算法快(cld3
x22, textcat
x118, 手写解决方案 x252)。cld3
和textcat
的基准测试。tm::stopwords
)。C
中循环)。Englishinator
方案也会很慢(只测试一种语言,但要测试更多的单词和类似的代码)。detect_from_sw <- function(text,candidates){
sapply(strsplit(text,'[ [:punct:]]'),function(y)
names(which.max(sapply(candidates,function(x) sum(tm::stopwords(x) %in% y))))
)
}
基准
data(reuters,package = "kernlab") # a corpus of articles in english
length(reuters)
# [1] 40
sapply(reuters,nchar)
# [1] 1311 800 511 2350 343 388 3705 604 254 239 632 607 867 240
# [15] 234 172 538 887 2500 1030 538 2681 338 402 563 2825 2800 947
# [29] 2156 2103 2283 604 632 602 642 892 1187 472 1829 367
text <- unlist(reuters)
microbenchmark::microbenchmark(
textcat = textcat::textcat(text),
cld2 = cld2::detect_language(text),
cld3 = cld3::detect_language(text),
detect_from_sw = detect_from_sw(text,c("english","french","german")),
times=100)
# Unit: milliseconds
# expr min lq mean median uq max neval
# textcat 212.37624 222.428824 230.73971 227.248649 232.488500 410.576901 100
# cld2 1.67860 1.824697 1.96115 1.955098 2.034787 2.715161 100
# cld3 42.76642 43.505048 44.07407 43.967939 44.579490 46.604164 100
# detect_from_sw 439.76812 444.873041 494.47524 450.551485 470.322047 2414.874973 100
关于textcat
不准确性的说明
我无法评论cld2
与cld3
的准确性(@giocomai在他的答案中声称cld2
更好),但我确认textcat
似乎非常不可靠(在本页面的多个地方提到)。除了这篇文章被textcat
分类为西班牙语外,所有方法都正确地对所有文本进行了分类:
"阿根廷原油产量由于1987年1月份从1986年1月份的13.81百万桶下降10.8%至12.32百万桶,石油公司Yacimientos Petroliferos Fiscales表示。1987年1月的天然气产量总计1.15亿立方米,比1986年1月的11.1亿立方米高3.6%。石油公司Yacimientos Petroliferos Fiscales补充说。路透社"
还有一个相当好用的R包叫做"franc"。虽然速度比其他的要慢,但我使用它的体验比cld2和特别是cld3要好。
我不确定R语言是否有相关库,但其他编程语言有多个库可供使用。你可以在这里找到其中一些:
http://www.detectlanguage.com/
还有一个最近有趣的项目:
http://blog.mikemccandless.com/2011/10/language-detection-with-googles-compact.html
使用这个库生成了Twitter语言地图:http://www.flickr.com/photos/walkingsf/6277163176/in/photostream
如果您在R中找不到一个库,我建议考虑通过Web服务使用远程语言检测器。
textcat()
返回了许多错误分类结果:我刚刚在800篇学术论文摘要上运行了它,这些论文的语言要么是德语,要么是英语。然而,textcat
将其中3篇分类为拉丁语,3篇分类为法语(?!)和2篇分类为加泰罗尼亚语(??!)。然而,由@aykutfirat推荐的cldr
包在所有文本上都准确无误地识别,并提出了第二和第三个备选项。 - KenHBS