好的,所以我找到了两种方法。
我将使用简化的分词器,您可以用更复杂的东西替换我的分词器,一切仍应运行。
对于文本数据,我使用的是小说War and Peace的文本文件
请注意,我对确切的类进行了一些更改,以保持类型兼容。术语计数函数称为study,带有一个参数(输入文件)并返回一个类型DocTerms
方法一
import scala.collection.immutable.WrappedString;
import scala.collection.Map
def tokenize(line:String):Array[String] =
new WrappedString(line).toLowerCase().split(' ')
case class DocTerms(filename:String, terms:Map[String,Int])
def study(filename:String):DocTerms = {
val counts = (sc
.textFile(filename)
.flatMap(tokenize)
.map( (s:String) => (s,1) )
.reduceByKey( _ + _ )
.collectAsMap()
)
DocTerms(filename, counts)
}
val book1 = study("/data/warandpeace.txt")
for(c<-book1.terms.slice(20)) println(c)
输出:
(worried,12)
(matthew.,1)
(follow,32)
(lost--than,1)
(diseases,1)
(reports.,1)
(scoundrel?,1)
(but--i,1)
(road--is,2)
(well-garnished,1)
(napoleon;,2)
(passion,,2)
(nataly,2)
(entreating,2)
(sounding,1)
(any?,1)
("sila,1)
(can,",3)
(motionless,22)
请注意,此输出未排序,通常 Map 类型不可排序,但它们对于查找和类似字典的速度很快。虽然只打印了 20 个元素,但所有术语都被计算并存储在 book1
类型为DocTerms的对象
方法二
或者,DocTerms 的terms 部分可以被设为List[(String,Int)] 类型,并在返回之前进行排序(以一定的计算成本),这样最多的术语首先出现。但这意味着它不会是Map 或快速查找字典。但是,对于某些用途,类似列表的类型可能更可取。
import scala.collection.immutable.WrappedString;
def tokenize(line:String):Array[String] =
new WrappedString(line).toLowerCase().split(' ')
case class DocTerms(filename:String, terms:List[(String,Int)])
def study(filename:String):DocTerms = {
val counts = (sc
.textFile(filename)
.flatMap(tokenize)
.map( (s:String) => (s,1) )
.reduceByKey( _ + _ )
.sortBy[Int]( (pair:Tuple2[String,Int]) => -pair._2 )
.collect()
)
DocTerms(filename, counts.toList)
}
val book1 = study("/data/warandpeace.txt")
for(c<-book1.terms.slice(1,100)) println(c)
输出
(and,21403)
(to,16502)
(of,14903)
(,13598)
(a,10413)
(he,9296)
(in,8607)
(his,7932)
(that,7417)
(was,7202)
(with,5649)
(had,5334)
(at,4495)
(not,4481)
(her,3963)
(as,3913)
(it,3898)
(on,3666)
(but,3619)
(for,3390)
(i,3226)
(she,3225)
(is,3037)
(him,2733)
(you,2681)
(from,2661)
(all,2495)
(said,2406)
(were,2356)
(by,2354)
(be,2316)
(they,2062)
(who,1939)
(what,1935)
(which,1932)
(have,1931)
(one,1855)
(this,1836)
(prince,1705)
(an,1617)
(so,1577)
(or,1553)
(been,1460)
(their,1435)
(did,1428)
(when,1426)
(would,1339)
(up,1296)
(pierre,1261)
(only,1250)
(are,1183)
(if,1165)
(my,1135)
(could,1095)
(there,1094)
(no,1057)
(out,1048)
(into,998)
(now,957)
(will,954)
(them,942)
(more,939)
(about,919)
(went,846)
(how,841)
(we,838)
(some,826)
(him.,826)
(after,817)
(do,814)
(man,778)
(old,773)
(your,765)
(very,762)
("i,755)
(chapter,731)
(princess,726)
(him,,716)
(then,706)
(andrew,700)
(like,691)
(himself,687)
(natasha,683)
(has,677)
(french,671)
(without,665)
(came,662)
(before,658)
(me,657)
(began,654)
(looked,642)
(time,641)
(those,639)
(know,623)
(still,612)
(our,610)
(face,609)
(thought,608)
(see,605)
您可能会注意到最常见的词不是很有趣。但我们也有像“王子”、“公主”、“安德鲁”、“娜塔莎”和“法语”这样的词,它们可能更具体地用于战争与和平。
一旦你有一堆文档,为了减少常用词的权重,人们经常使用 TFIDF,或“词频逆文档频率”,这意味着每个词的计数基本上除以语料库中的文档数它出现在其中(或一些涉及日志的类似功能)。但这是另一个问题的话题。