首先抛出官方文档
http://spark.apache.org/docs/latest/mllib-feature-extraction.html
TF-IDF
TF-IDF
特征抽取:从原始数据中抽取特征
TF-IDF:词频-逆向文件频率。一种在文本挖掘中广泛使用的特征向量化方法,可以体现一个文档中词语在语料库中的重要程度
词语:用t表示
文档:用d表示
语料库:用D表示
词频TF(t,d) :词语t在文档d中出现的次数
文件词频DF(t,D):包含词语t的文档个数
如果我们只使用词频来衡量重要性,很容易过度强调在文档中经常出现,却没有什么实际信息的词语,比如“a”,“the”以及“of” 如果一个词语经常出现在语料库中,意味着它并不能很好的对文档进行分区,TF-IDF就是在数值化文档信息,衡量词语提供多少信息以及分区文档
**|D|**是语料库中文档总个数
如果一个词语出现在所有文档中,那么它的IDF就是0 ,由于是对数函数,为了避免分母为0的情况,都加1
TF-IDF度量值为
在Spark ML中,TF-IDF分为两部分:TF和IDF
TF:HashingTF是一个 transfomer,在文本处理中,接受词条的集合,然后把集合转化为固定长度的特征向量
IDF:IDF是一个Estimator 在数据及上应用fit()方法,产生一个IDFModel,用该模型接受特征向量,然后计算每一个词在文档中出现频次。
现在有一篇博客,一共100个词,其中词语‘学习’ 出现3词,那么按照上面计算
TF =3/100=0.03
假设博客总数为99999份,‘学习’在999份文件中出现过,那么逆向文件频率
IDF=log(100000+1/1000+1)= 3
最终TF-IDF 3*0.03=0.09
package com.scala.sparkML
import org.apache.spark.ml.feature.{HashingTF, IDF, Tokenizer}
import org.apache.spark.sql.SparkSession
case class Product(id:String,companyName:String,direction:String,productInfo:String)
object TFIDFTest2 {
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("TFIDF@2")
.master("local")
//.config("spark.sql.warehouse.dir", "C:\\Users\\Administrator\\Desktop\\spark-warehouse")
.getOrCreate()
// 导入spark的隐式转换
import spark.implicits._
val products = spark.sparkContext.textFile("dataFrametext").map { x =>
val data = x.split(",")
Product(data(0),data(1),data(2),data(3))
}.toDS().cache()
val productData = new Tokenizer().setInputCol("productInfo").setOutputCol("productWords").transform(products)
val tf=new HashingTF().setNumFeatures(30).setInputCol("productWords").setOutputCol("productFeatures").transform(productData)
val idfModel = new IDF().setInputCol("productFeatures").setOutputCol("features").fit(tf)
idfModel.save("idfModelData")
val idfData = idfModel.transform(tf)
idfData.select("id","companyName","features").show()
}
}
dataFrametext
131648,东华工程塑料有限公司,1,沙特 基础 pc fxe183889 美国 ge
131345,西单工程塑料有限公司,2,伊朗 fuck pe fxe183889 日本 ne