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-特徵工程機器學習特徵工程
- 什麼是機器學習的特徵工程?【資料集特徵抽取(字典,文字TF-Idf)、特徵預處理(標準化,歸一化)、特徵降維(低方差,相關係數,PCA)】機器學習特徵工程PCA
- python基礎學習之 特徵工程Python特徵工程
- 機器學習之良好特徵的特點機器學習特徵
- 機器學習的靜態特徵和動態特徵機器學習特徵
- 百面機器學習總結--第一章特徵工程機器學習特徵工程
- 機器學習中,有哪些特徵選擇的工程方法?機器學習特徵
- 使用SAP Cloud Platform Leonardo機器學習提取圖片的特徵向量CloudPlatform機器學習特徵
- 【火爐煉AI】機器學習050-提取影像的Star特徵AI機器學習特徵
- 影象特徵提取之HoG特徵特徵HOG
- 機器學習之 基於xgboost的特徵篩選機器學習特徵
- 【火爐煉AI】機器學習049-提取影象的SIFT特徵點AI機器學習特徵
- 【火爐煉AI】機器學習049-提取影像的SIFT特徵點AI機器學習特徵
- 機器學習-無監督學習(人臉識別,使用NMF進行特徵提取)機器學習特徵
- 特徵提取-map特徵
- 使用SAP Leonardo上的機器學習服務提取圖片的特徵向量機器學習特徵
- 機器學習之特徵組合:組合獨熱向量機器學習特徵
- 語音的關鍵聲學特徵(語音情感特徵提取)特徵
- 機器學習1-sklearn&字典特徵抽取機器學習特徵
- 機器學習筆記——特徵標準化機器學習筆記特徵
- 機器學習的未來——深度特徵融合機器學習特徵
- 特徵工程之特徵表達特徵工程
- 特徵工程之特徵選擇特徵工程
- 美團機器學習實踐第二章-特徵工程總結機器學習特徵工程
- 特徵工程特徵工程
- 08 特徵工程 - 特徵降維 - LDA特徵工程LDA
- 特徵工程之特徵預處理特徵工程
- 在大型金融資料集上使用機器學習的特徵工程測試機器學習特徵工程
- 特徵工程:互動特徵與多項式特徵理解特徵工程
- 流量特徵提取工具NFStream特徵NFS
- LOAM演算法核心解析之特徵點的提取(一)演算法特徵
- 特徵工程思路特徵工程