SparkML機器學習之特徵工程(一)特徵提取(TF-IDF、Word2Vec、CountVectorizer)
特徵工程
我們都知道特徵工程在機器學習中是很重要的,然而特徵工程到底是什麼?怎麼樣通俗的理解它呢?打個比方,即使你有再好的漁具,如果給你一片沒有魚的池塘,那也是白費力氣的。而特徵工程就是找有魚的那片水域。所以我們可以這麼理解,特徵是資料中抽取出來的對結果預測有用的資訊(水域),而特徵工程就是使用專業知識來處理資料,篩選出具有價值的特徵(從100個水域中挑選出魚最多最好的水域)。所以有句話是這麼說的:演算法再牛逼,其上限也是由特徵工程決定的,就像你漁具再好,捕魚多少也是由水域這個特徵決定的。
在SparkML中、對於特徵工程的操作主要分為特徵提取,特徵轉化、特徵選擇。
特徵提取
從原始資料中提取特徵
TF-IDF (Term frequency-inverse document frequency)
TF-IDF稱為詞頻-逆檔案頻率,先搞清楚它有什麼作用吧!很經典的一個問題,如何得到一篇文章的關鍵詞??大家都能想到,看看這篇文章什麼詞出現最多!思路是沒問題,但是,一篇文章,出現最多的,應該都是諸如“的”之類的停用詞吧?這就沒意義了啊!那就把這些停用詞過濾掉唄,這樣還是會出問題。比如一篇文章,叫做中國功夫,中國和功夫出現了同樣多次數,可是顯而易見,該文重點應該是功夫。而出現問題的原因,是因為中國是個熱門詞。這讓我想到我曾寫過的基於物品的協同過濾演算法,也是要將熱門物品做一個懲罰,否則會導致推薦不精確。
TF-IDF完美的解決了這個問題,TF-IDF作用就是體現一個文件中詞語重要程度。TF是某個詞或短語在一篇文章中出現的頻率。而IDF,就是一種對熱門詞語的懲罰,對於較熱門詞語比如”中國”會給予較小的權重,較少見的詞“功夫”給予較大的權重。至於如何判斷它是否為熱門詞,則通過該詞在整個語料庫的出現次數決定。比如中國這個詞,語料庫一共1000篇文章他就出現了100次,自然為熱門詞,而功夫,1000篇文章只有1篇出現了,那就為冷門詞了。
package ml.test
import org.apache.spark.ml.feature.{HashingTF, IDF, Tokenizer}
import org.apache.spark.sql.SparkSession
/**
* Created by LYL on 2018/4/4.
*/
object TFDemo {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("TF-IDF Demo").master("local").getOrCreate()
val sentenceData = spark.createDataFrame(Seq(
(0.0, "china kungfu kungfu is good"),
(1.0, "I lova china"),
(2.0, "I love china shenzhen")
)).toDF("label", "sentence")
//Tokenizer分詞器 將句子分成單詞
val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words")
val wordsData = tokenizer.transform(sentenceData)
//將每個詞轉換成Int型,並計算其在文件中的詞頻(TF)
//setNumFeatures(200)表示將Hash分桶的數量設定為200個,可以根據你的詞語數量來調整,一般來說,這個值越大不同的詞被計算為一個Hash值的概率就越小,資料也更準確,但需要消耗更大的記憶體
val hashingTF = new HashingTF().setInputCol("words").setOutputCol("TF Features").setNumFeatures(200)
val featurizedData = hashingTF.transform(wordsData)
//計算IDF
val idf = new IDF().setInputCol("TF Features").setOutputCol("TF-IDF features")
val idfModel = idf.fit(featurizedData)
val rescaledData = idfModel.transform(featurizedData)
rescaledData.select("words","TF Features","TF-IDF features")show(false)
}
}
輸出結果為:
由於china在三個文件中都出現了,所以TF-IDF=0.0,而kungfu只在第一個文件出現(說明是冷門詞),卻是第一個文件中出現次數最多的,因此計算出來的TF-IDF=1.3862943611198906也是最高的
+---------------------------------+----------------------------------------+---------------------------------------------------------------------------------------+
|words |TF Features |TF-IDF features |
+---------------------------------+----------------------------------------+---------------------------------------------------------------------------------------+
|[china, kungfu, kungfu, is, good]|(200,[81,168,169,198],[1.0,1.0,1.0,2.0])|(200,[81,168,169,198],[0.6931471805599453,0.28768207245178085,0.0,1.3862943611198906]) |
|[i, lova, china] |(200,[91,129,169],[1.0,1.0,1.0]) |(200,[91,129,169],[0.6931471805599453,0.28768207245178085,0.0]) |
|[i, love, china, shenzhen] |(200,[40,129,168,169],[1.0,1.0,1.0,1.0])|(200,[40,129,168,169],[0.6931471805599453,0.28768207245178085,0.28768207245178085,0.0])|
+---------------------------------+----------------------------------------+---------------------------------------------------------------------------------------+
Word2Vec
word2vec是用一個向量去表示一個物件(因為計算機是無法識別物件實體的),物件可以是單詞,句子,文章,使用者等等。然後基於向量相似度去計算物件的相似度,找到相關的物件,發現相關關係,可以用來做分類、聚類、也可以做詞的相似度計算。應用非常廣泛,比如:相關詞(搜尋賈伯斯會出來蘋果),補全句子中缺失的單詞,推薦系統,分析使用者關係等等。
object Word2VecDemo {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().master("local[2]").appName("Word2VecDemo").getOrCreate()
val documentDF = spark.createDataFrame(Seq(
"Hi I love Spark".split(" "),
"Hi I love java".split(" "),
"Logistic regression models are neat".split(" ")
).map(Tuple1.apply)).toDF("text")
// setVectorSize 目標數值向量的維度大小 setMinCount 只有當某個詞出現的次數大於或者等於 minCount 時,才會被包含到詞彙表裡,否則會被忽略掉
val word2Vec = new Word2Vec()
.setInputCol("text")
.setOutputCol("result")
.setVectorSize(3)
.setMinCount(0)
val model = word2Vec.fit(documentDF)
//利用Word2VecModel把文件轉變成特徵向量。
val result = model.transform(documentDF)
result.show(false)
}
}
輸出結果為:
+-----------------------------------------+-------------------------------------------------------------------+
|text |result |
+-----------------------------------------+-------------------------------------------------------------------+
|[Hi, I, love, Spark] |[-0.03605498746037483,-0.02823249064385891,0.06127407215535641] |
|[Hi, I, love, java] |[-0.046827200800180435,-0.052235052920877934,0.0025074686855077744]|
|[Logistic, regression, models, are, neat]|[0.04324783757328987,0.030185341089963916,-5.047338083386422E-4] |
+-----------------------------------------+-------------------------------------------------------------------+
CountVectorizer
由於計算機是不能識別單詞的,所以我們要把它轉為向量。Countvectorizer和Countvectorizermodel旨在通過計數來將一個文件轉換為向量。
object CountVectorizerDemo {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().master("local[2]").getOrCreate()
val dataFrame = spark.createDataFrame(Seq(
(0, Array("a", "b","b","c","d","d")),
(1, Array("a","c","b" ))
)).toDF("id", "words")
//setVocabSize設定詞彙表的最大容量為3,setMinDF設定詞彙表中的詞至少要在2個文件中出現過。
//如果setMinDF=2 那麼就不會出現d(只在一個文件存在)了。
val cv = new CountVectorizer().setVocabSize(3).setMinDF(2).setInputCol("words").setOutputCol("features")
//如果setVocabSize=2 那麼就不會出現a,c(次數少)了。
val cv1 = new CountVectorizer().setVocabSize(2).setInputCol("words").setOutputCol("features")
val cvModel = cv.fit(dataFrame)
val cvModel1 = cv1.fit(dataFrame)
cvModel.transform(dataFrame).show(truncate = false)
cvModel1.transform(dataFrame).show(truncate = false)
}
}
輸出結果為:
//3代表詞彙表的容量,[0,1,2]分別對應b,a,c,[2.0,1.0,1.0]代表出現次數
+---+------------------+-------------------------+
|id |words |features |
+---+------------------+-------------------------+
|0 |[a, b, b, c, d, d]|(3,[0,1,2],[2.0,1.0,1.0])|
|1 |[a, c, b] |(3,[0,1,2],[1.0,1.0,1.0])|
+---+------------------+-------------------------+
+---+------------------+-------------------+
|id |words |features |
+---+------------------+-------------------+
|0 |[a, b, b, c, d, d]|(2,[0,1],[2.0,2.0])|
|1 |[a, c, b] |(2,[0],[1.0]) |
+---+------------------+-------------------+
相關文章
- 機器學習之特徵工程(一)機器學習特徵工程
- 機器學習之特徵工程機器學習特徵工程
- 機器學習-特徵提取機器學習特徵
- 機器學習 | 特徵工程機器學習特徵工程
- 機器學習——特徵工程機器學習特徵工程
- 機器學習特徵工程機器學習特徵工程
- 機器學習之資料清洗與特徵提取機器學習特徵
- 機器學習 特徵工程之特徵選擇機器學習特徵工程
- 面向機器學習的特徵工程一、引言機器學習特徵工程
- 機器學習2-特徵工程機器學習特徵工程
- 特徵提取之Haar特徵特徵
- 影象特徵提取之HoG特徵特徵HOG
- 什麼是機器學習的特徵工程?【資料集特徵抽取(字典,文字TF-Idf)、特徵預處理(標準化,歸一化)、特徵降維(低方差,相關係數,PCA)】機器學習特徵工程PCA
- 特徵提取-map特徵
- 特徵工程之特徵表達特徵工程
- 特徵工程之特徵選擇特徵工程
- 特徵工程特徵工程
- 08 特徵工程 - 特徵降維 - LDA特徵工程LDA
- 特徵工程之特徵預處理特徵工程
- 機器學習之良好特徵的特點機器學習特徵
- [特徵工程系列一] 論特徵的重要性特徵工程
- 流量特徵提取工具NFStream特徵NFS
- 特徵工程:互動特徵與多項式特徵理解特徵工程
- 百面機器學習總結--第一章特徵工程機器學習特徵工程
- LOAM演算法核心解析之特徵點的提取(一)演算法特徵
- 特徵工程梗概特徵工程
- 特徵工程思路特徵工程
- sift、surf、orb 特徵提取及最優特徵點匹配ORB特徵
- 【火爐煉AI】機器學習050-提取影像的Star特徵AI機器學習特徵
- 機器學習的靜態特徵和動態特徵機器學習特徵
- 機器學習中,有哪些特徵選擇的工程方法?機器學習特徵
- 特徵工程 特徵選擇 reliefF演算法特徵工程演算法
- 【火爐煉AI】機器學習049-提取影像的SIFT特徵點AI機器學習特徵
- 【火爐煉AI】機器學習049-提取影象的SIFT特徵點AI機器學習特徵
- 一文讀懂特徵工程特徵工程
- [特徵工程] encoding特徵工程Encoding
- 語音的關鍵聲學特徵(語音情感特徵提取)特徵
- 機器學習處理流程、特徵工程,模型設計例項機器學習特徵工程模型