Spark TF-IDF


1、概念

TF-IDF (Term frequency-inverse document frequency)
TF-IDF(HashingTF and IDF)
“詞頻-逆向文件頻率”(TF-IDF)是一種在文本挖掘中廣泛使用的特征向量化方法,它可以體現一個文檔中詞語在語料庫中的重要程度。
詞語由t表示,文檔由d表示,語料庫由D表示。詞頻TF(t,d)是詞語t在文檔d中出現的次數。文件頻率DF(t,D)是包含詞語的文檔的個數。
如果我們只使用詞頻來衡量重要性,很容易過度強調在文檔中經常出現,卻沒有太多實際信息的詞語,比如“a”,“the”以及“of”。
如果一個詞語經常出現在語料庫中,意味着它並不能很好的對文檔進行區分。TF-IDF就是在數值化文檔信息,衡量詞語能提供多少信息以區分文檔。

公式中使用log函數,當詞出現在所有文檔中時,它的IDF值變為0。加1是為了避免分母為0的情況。IDF 度量值表示如下:
IDF(t,D)=log((|D|+1)/(DF(t,D)+1))
,此處的|D]語料庫中總的文檔數,

術語頻率和文檔頻率的定義有幾種變體。在MLlib中,我們將TF和IDF分開以使其靈活。TF-IDF 度量值表示如下:
TFIDF(t,d,D)=TF(t,d)*IDF(t,D).

TF: HashingTF 是一個Transformer,在文本處理中,接收詞條的集合然后把這些集合轉化成固定長度的特征向量。
這個算法在哈希的同時會統計各個詞條的詞頻。
IDF: IDF是一個Estimator,在一個數據集上應用它的fit()方法,產生一個IDFModel。
該IDFModel 接收特征向量(由HashingTF產生),然后計算每一個詞在文檔中出現的頻次。
IDF會減少那些在語料庫中出現頻率較高的詞的權重。
在下面的代碼段中,我們以一組句子開始。首先使用分解器Tokenizer把句子划分為單個詞語。
對每一個句子(詞袋),我們使用HashingTF將句子轉換為特征向量,最后使用IDF重新調整特征向量。
這種轉換通常可以提高使用文本特征的性能。

Spark.mllib 中實現詞頻率統計使用特征hash的方式,原始特征通過hash函數,映射到一個索引值。后面只需要統計這些索引值的頻率,就可以知道對應詞的頻率。

這種方式避免設計一個全局1對1的詞到索引的映射,這個映射在映射大量語料庫時需要花費更長的時間。

通過hash的方式可能會映射到同一個值的情況,即不同的原始特征通過Hash映射后是同一個值。

為了降低這種情況出現的概率,我們只能對特征向量升維。i.e., 提高hash表的桶數,默認特征維度是 2^20 = 1,048,576.

2、code,參考地址:https://github.com/asker124143222/spark-demo

package com.home.spark.ml

import org.apache.spark.SparkConf
import org.apache.spark.ml.feature._
import org.apache.spark.sql.{DataFrame, SparkSession}

object Ex_TF_IDF {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf(true).setMaster("local[*]").setAppName("spark ml label")
    val spark = SparkSession.builder().config(conf).getOrCreate()


    val sentenceData = spark.createDataFrame(Seq(
      (0.0, "Hi I heard about Spark,I love spark"),
      (0.0, "I wish Java could use case classes"),
      (1.0, "Logistic regression models are neat,I like it")
    )).toDF("label", "sentence")

    //分詞
    val tokenizer = new RegexTokenizer().setInputCol("sentence").setOutputCol("words")
      .setPattern("\\W").setToLowercase(true)
    val wordsData: DataFrame = tokenizer.transform(sentenceData)
    wordsData.show(false)


    //hash向量化,hash桶的數量少容易出現hash碰撞
    val hashingTF = new HashingTF().setInputCol("words").setOutputCol("rowFeatures").setNumFeatures(2000)
    val featurizedData  = hashingTF.transform(wordsData)
    // alternatively, CountVectorizer can also be used to get term frequency vectors
    featurizedData.select("words","rowFeatures").show(false)

    //IDF是一個評估器,需要使用fit進行轉換,生成模型
    val idf = new IDF().setInputCol("rowFeatures").setOutputCol("features")
    val model: IDFModel = idf.fit(featurizedData)

    //IDF減少那些在語料庫中出現頻率較高的詞的權重
    //通過TF-IDF轉換后得到帶權重的向量值
    val rescaleData = model.transform(featurizedData)
    rescaleData.select("words","rowFeatures","features").show(false)

    spark.stop()
  }
}

3、result

-------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
rowFeatures                                                                    |features                                                                                                                                                                                 |
-------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
(2000,[240,1105,1329,1357,1777,1960],[1.0,2.0,2.0,1.0,1.0,1.0])                |(2000,[240,1105,1329,1357,1777,1960],[0.6931471805599453,1.3862943611198906,0.0,0.6931471805599453,0.6931471805599453,0.6931471805599453])                                               |
(2000,[213,342,489,495,1329,1809,1967],[1.0,1.0,1.0,1.0,1.0,1.0,1.0])          |(2000,[213,342,489,495,1329,1809,1967],[0.6931471805599453,0.6931471805599453,0.6931471805599453,0.28768207245178085,0.0,0.6931471805599453,0.6931471805599453])                         |
(2000,[286,495,695,1138,1193,1329,1330,1604],[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0])|(2000,[286,495,695,1138,1193,1329,1330,1604],[0.6931471805599453,0.28768207245178085,0.6931471805599453,0.6931471805599453,0.6931471805599453,0.0,0.6931471805599453,0.6931471805599453])|
-------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

 

所有詞向量值都重新按權重計算。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM