Spark数据挖掘-TF-IDF文档矩阵
2015-11-19 00:00
597 查看
摘要: 得到词文档矩阵往往都是文本挖掘算法的第一步,词文档矩阵中行表示语料库中出现过的词(实际代码都是对词进行整数编码),列表示所有的文档,矩阵中的每个值就代表词在文档中的重要程度。目前已经有很多计算词在文档中权重的模型,不过最通用的模型应该就是 **词频-逆文档频率(简称:TF-IDF)** 矩阵。
termFrequencyInDoc:Int 词在文档中出现的次数
totalTermsInDoc: Int 文档中所有词的个数
termFreqInCorpus: Int 语料库中出现这个词的不同文档数
totalDocs: Int 整个语料库包含的文档数量
利用上面的几个值就可以计算一个词在文档中的重要程度,代码如下:
首先,词在某篇文档中出现的越多越重要
其次,词在其他文档中尽量少出现,如果每篇文档中它都出现的很多,它就没有区分度了。所以这里采用的是文档频率取逆,也就是取倒数。
但是有个问题,首先词频是近似服从指数分布,一些通用词出现的次数可能是低频词几十或者几百倍,直接采用文档频率取逆会导致稀缺词获得一个巨大的权重,实际上就会忽略其他词的影响,这样显然不妥,为了去掉这个影响,算法采用对文档频率取逆之后再取对数,这样就把乘法差异转化为加法差异。使得稀缺词权重降低了。
实际工作中对每篇文档往往都有一个唯一的标识主键,这样方便以后的统计
文档清洗(去掉不符合要求的文档:比如文档内容为空)
文档分词(去掉停用词、按词性过滤一下词、过滤低频词、词干提取),其中词干提取指的是将比如:“大款、大款们”合并为一个词,中文实现这个难度很大。
数据加载,词编码、文档编码
将数据编码之后转为文档词向量再合并为矩阵
计算IF-IDF
数据清洗、停词库每个项目都会有不同的要求,但是分词、词编码、文档编码等工作还是比较通用的,下面会对通用技术通过 Spark 实战详细讲解(尤其是分布式编程需要注意的地方:)
停词库需要广播到所有机器
每个 executor 只需启动一个分词模型即可,分词模型很耗资源,与连接数据库一样,每个executor只需启动一个实例
Spark数据挖掘-TF-IDF文档矩阵
前言
得到词文档矩阵往往都是文本挖掘算法的第一步,词文档矩阵中行表示语料库中出现过的词(实际代码都是对词进行整数编码),列表示所有的文档,矩阵中的每个值就代表词在文档中的重要程度。目前已经有很多计算词在文档中权重的模型,不过最通用的模型应该就是 词频-逆文档频率(简称:TF-IDF) 矩阵。TF-IDF
先看一下TF-IDF如何计算每个词在文档中的重要程度,先假设得到了下面几个变量的值:termFrequencyInDoc:Int 词在文档中出现的次数
totalTermsInDoc: Int 文档中所有词的个数
termFreqInCorpus: Int 语料库中出现这个词的不同文档数
totalDocs: Int 整个语料库包含的文档数量
利用上面的几个值就可以计算一个词在文档中的重要程度,代码如下:
def termDocWeight(termFrequencyInDoc: Int, totalTermsInDoc: Int, termFreqInCorpus: Int, totalDocs: Int): Double = { val tf = termFrequencyInDoc.toDouble / totalTermsInDoc val docFreq = totalDocs.toDouble / termFreqInCorpus val idf = math.log(docFreq) tf * idf }
TF-IDF含义解读
直观理解,TF-IDF考虑了如下两个方面:首先,词在某篇文档中出现的越多越重要
其次,词在其他文档中尽量少出现,如果每篇文档中它都出现的很多,它就没有区分度了。所以这里采用的是文档频率取逆,也就是取倒数。
但是有个问题,首先词频是近似服从指数分布,一些通用词出现的次数可能是低频词几十或者几百倍,直接采用文档频率取逆会导致稀缺词获得一个巨大的权重,实际上就会忽略其他词的影响,这样显然不妥,为了去掉这个影响,算法采用对文档频率取逆之后再取对数,这样就把乘法差异转化为加法差异。使得稀缺词权重降低了。
TF-IDF的局限
这个算法本质还是词袋模型,它没有考虑词与词之间的顺序、语法结构以及语义。通过对每个不同的词计数,这个模型很难区别一词多义、以及同义词。实际编程中往往每篇文档表示为行向量,每个元素代表词对应的索引位置,这样可以适应语料库中文档变的越来越多,通常情况下,语料库文档的增加速度肯定大过词的增长速度。而且这样的行向量也是稀疏表示,节省空间。TF-IDF实战
TF-IDF原理非常简单,实际工作中还是有很多需要注意的地方,下面就用 Spark 实战的方式讲解如何将一个语料库转为 TF-IDF 矩阵,首先给出具体的步骤:实际工作中对每篇文档往往都有一个唯一的标识主键,这样方便以后的统计
文档清洗(去掉不符合要求的文档:比如文档内容为空)
文档分词(去掉停用词、按词性过滤一下词、过滤低频词、词干提取),其中词干提取指的是将比如:“大款、大款们”合并为一个词,中文实现这个难度很大。
数据加载,词编码、文档编码
将数据编码之后转为文档词向量再合并为矩阵
计算IF-IDF
数据清洗、停词库每个项目都会有不同的要求,但是分词、词编码、文档编码等工作还是比较通用的,下面会对通用技术通过 Spark 实战详细讲解(尤其是分布式编程需要注意的地方:)
分布式文本分词
分布式文本分词注意两个地方:停词库需要广播到所有机器
每个 executor 只需启动一个分词模型即可,分词模型很耗资源,与连接数据库一样,每个executor只需启动一个实例
计算TF-IDF
val documents: RDD[Seq[String]] = sc.textFile("your_data_dir").map(_.split(" ").toSeq) val hashingTF = new HashingTF() val tf: RDD[Vector] = hashingTF.transform(documents) tf.cache() //没有在两个文档中出现过的词语不要 val idf = new IDF(minDocFreq = 2).fit(tf) val tfidf: RDD[Vector] = idf.transform(tf)
相关文章推荐
- Spark RDD API详解(一) Map和Reduce
- 使用spark和spark mllib进行股票预测
- Spark随谈——开发指南(译)
- Spark,一种快速数据分析替代方案
- 数据挖掘之Apriori算法详解和Python实现代码分享
- python实现TF-IDF算法解析
- eclipse 开发 spark Streaming wordCount
- Spark中将对象序列化存储到hdfs
- 详解BI/数据分析/数据挖掘/业务分析概念 7fe0
- Spark初探
- Spark Streaming初探
- Sedgewick之巨著《算法》,与高德纳TAOCP一脉相承
- 普通最小二乘法的推导证明
- 搭建hadoop/spark集群环境
- 整合Kafka到Spark Streaming——代码示例和挑战
- Spark 性能相关参数配置详解-任务调度篇
- 基于spark1.3.1的spark-sql实战-01
- 基于spark1.3.1的spark-sql实战-02
- 在 Databricks 可获得 Spark 1.5 预览版
- spark standalone模式 zeppelin安装