概述
在文本挖掘中用于衡量一个单词在该文档中的重要性。声明单词
t
t
t,.文档
d
d
d,文档集合
D
D
D,单词
t
t
t在文档
d
d
d中出现的频率为
T
F
(
t
,
d
)
TF(t,d)
TF(t,d),
D
F
(
t
,
D
)
DF(t,D)
DF(t,D)表示多少文档含有该单词。如果我们只用
T
F
TF
TF衡量单词的重要性,很容易过度重视在一个文档经常出现但是带有很少信息量的单词,例如停用词,语气词,礼貌用词等。TD-IDF提出了一种他的解决办法:
I
D
F
(
t
,
D
)
=
log
∣
D
∣
+
1
D
F
(
t
,
D
)
+
1
,
IDF(t, D) = \log \frac{|D| + 1}{DF(t, D) + 1},
IDF(t,D)=logDF(t,D)+1∣D∣+1,
上式表明:越多的文档含有这个单词(DF越大),IDF值越小。如果一个单词在所有的文档都出现了,那么他的IDF值为0。
T
F
I
D
F
(
t
,
d
,
D
)
=
T
F
(
t
,
d
)
⋅
I
D
F
(
t
,
D
)
.
TFIDF(t, d, D) = TF(t, d) \cdot IDF(t, D).
TFIDF(t,d,D)=TF(t,d)⋅IDF(t,D).
spark实现
package edu.ysu.spark
import com.huaban.analysis.jieba.JiebaSegmenter
import org.apache.spark.ml.feature.{HashingTF, IDF, IDFModel, Tokenizer}
import org.apache.spark.sql.{Column, DataFrame, SparkSession}
import org.apache.spark.{SparkConf, SparkContext}
object NewsEmbeddingApp {
def main(args: Array[String]): Unit = {
val spark: SparkSession = SparkSession.builder()
.appName("News Embedding")
.master("local[*]")
.getOrCreate()
val sentendata: DataFrame = spark.createDataFrame(
Seq(
(1.0, "今天 我 吃 早饭 了"),
(0.0, "你们 吃了 早饭 吗")
)).toDF("label", "sentence")
val tokenizer: Tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words")
val wordData: DataFrame = tokenizer.transform(sentendata)
val hashingTF: HashingTF = new HashingTF().setInputCol("words").setOutputCol("rawFeatures").setNumFeatures(1000)
val featurizeData: DataFrame = hashingTF.transform(wordData)
println(hashingTF.indexOf("今天"))
val idf: IDF = new IDF().setInputCol("rawFeatures").setOutputCol("features")
val model: IDFModel = idf.fit(featurizeData)
val rescaleData: DataFrame = model.transform(featurizeData)
rescaleData.select("words","label","features").show(truncate = false)
spark.stop()
}
}