0 相關源碼
1 樸素貝葉斯算法及原理概述
1.1 樸素貝葉斯簡介
◆ 樸素貝葉斯算法是基于貝葉斯定理
和特征條件獨立假設
的一種分類方法
◆ 樸素貝葉斯算法是一種基于聯合概率分布的統計學習方法
◆ 樸素貝葉斯算法實現簡單,效果良好,是一種常用的機器學習方法
1.2 貝葉斯定理
◆ 樸素貝葉斯算法的一個基礎是貝葉斯定理
貝葉斯定理(英語:Bayes' theorem)是[概率論]中的一個[定理],描述在已知一些條件下,某事件的發生概率。
比如,如果已知某癌癥與壽命有關,使用貝葉斯定理則可以通過得知某人年齡,來更加準確地計算出他罹患癌癥的概率。
通常,事件A在事件B已發生的條件下發生的概率,與事件B在事件A已發生的條件下發生的概率是不一樣的。
然而,這兩者是有確定的關系的,貝葉斯定理就是這種關系的陳述。
貝葉斯公式的一個用途,即通過已知的三個概率而推出第四個概率。貝葉斯定理跟[隨機變量]的[條件概率]以及[邊緣概率分布]有關。
作為一個普遍的原理,貝葉斯定理對于所有概率的解釋是有效的。這一定理的主要應用為[貝葉斯推斷],是[推論統計學]中的一種推斷法。這一定理名稱來自于[托馬斯·貝葉斯]。
1.2.1 陳述
貝葉斯定理是關于隨機事件A和B的條件概率的一則定理。
其中P(A|B)是指在事件B發生的情況下事件A發生的概率。
在貝葉斯定理中,每個名詞都有約定俗成的名稱:
- P(A|B)是已知B發生后A的條件概率,也由于得自B的取值而被稱作A的后驗概率。
- P(A)是A的先驗概率(或邊緣概率)。之所以稱為"先驗"是因為它不考慮任何B方面的因素。
- P(B|A)是已知A發生后B的條件概率,也由于得自A的取值而被稱作B的后驗概率。
- P(B)是B的先驗概率或邊緣概率。
按這些術語,貝葉斯定理可表述為:
后驗概率 = (似然性*先驗概率)/標準化常量
也就是說,后驗概率與先驗概率和相似度的乘積成正比。
另外,比例P(B|A)/P(B)也有時被稱作標準似然度(standardised likelihood),貝葉斯定理可表述為:
后驗概率 = 標準似然度*先驗概率
1.2.2 二中擇一的形式
-
貝氏定理通??梢栽賹懗上旅娴男问?/p>
-
其中AC是A的補集(即非A)。故上式亦可寫成:
-
在更一般化的情況,假設{Ai}是事件集合里的部分集合,對于任意的Ai,貝氏定理可用下式表示:
1.3 樸素貝葉斯算法
◆ 樸素葉斯算法的基本假設是條件獨立性
,這是一一個較強的前提條件,因而樸素貝葉斯算法易于實現,但是分類性能可能不會很高
◆ 樸素貝葉斯算法要求輸入變量是條件獨立
的,但是如果它們之間存在概率依存關系,就超出該算法范疇,屬于貝葉斯網絡
◆ 首先計算先驗概率及條件概率
代表第j個特征可能取第I個值
◆ 對于每一個給定的特征向量X ,在不同類別中出現的概率為
◆ 那么,最終預測結果y自然是其中概率最大的那個:
1.4 樸素貝葉斯算法示例
那么某個特征[1,B]T
應屬于哪一類呢?
2 實戰樸素貝葉斯分類
樸素貝葉斯分類器是一類簡單的概率多類分類器,它基于應用貝葉斯定理,在每對特征之間具有強(天真)獨立假設。
樸素貝葉斯可以非常有效地訓練。通過對訓練數據的單次傳遞,它計算給定每個標簽的每個特征的條件概率分布。
對于預測,它應用貝葉斯定理來計算給定觀察的每個標簽的條件概率分布。
MLlib支持多項式樸素貝葉斯和伯努利樸素貝葉斯。
輸入數據:這些模型通常用于文檔分類。在該上下文中,每個觀察是一個文檔,每個特征代表一個術語。特征值是術語的頻率(在多項式樸素貝葉斯中)或零或一個,表示該術語是否在文檔中找到(在伯努利樸素貝葉斯中)。要素值必須為非負值。使用可選參數“multinomial”或“bernoulli”選擇模型類型,默認為“multinomial”。對于文檔分類,輸入特征向量通常應該是稀疏向量。由于訓練數據僅使用一次,因此不必對其進行緩存。
通過設置參數λ(默認為1.0)可以使用加法平滑。
-
file.show
-
打亂順序 - data.show
-
在特征標簽形成vector數組
-
訓練集預測
都是正確的,完美預測!
[分類數據]是[機器學習]中的一項常見任務。
假設某些給定的數據點各自屬于兩個類之一,而目標是確定新數據點將在哪個類中。
對于支持向量機來說,數據點被視為
維向量,而我們想知道是否可以用
維[超平面]來分開這些點。這就是所謂的[線性分類器]。
可能有許多超平面可以把數據分類。最佳超平面的一個合理選擇是以最大間隔把兩個類分開的超平面。因此,我們要選擇能夠讓到每邊最近的數據點的距離最大化的超平面。如果存在這樣的超平面,則稱為最大間隔超平面,而其定義的線性分類器被稱為最大[間隔分類器],或者叫做最佳穩定性[感知器]
3 支持向量機算法
3.1 簡介
◆ 支持向量機(SVM)是一種用來分類的算法,當然,在這基礎上進行改進,也可以進行回歸分析(SVR)
◆ SVM是最優秀的分類算法之一,即便是在如今深度學習盛行的時代,仍然具有很廣泛的應用
◆ SVM被設計成一種二分類的算法, 當然,也有人提出了使用SVM進行多分類的方法,但是SVM依然主要被用在二分類
中
在[機器學習]中,支持向量機(英語:support vector machine,常簡稱為SVM,又名支持向量網絡)是在[分類]與[回歸分析]中分析數據的監督式學習模型與相關的學習算法。
給定一組訓練實例,每個訓練實例被標記為屬于兩個類別中的一個或另一個,SVM訓練算法創建一個將新的實例分配給兩個類別之一的模型,使其成為非概率[二元][線性分類器]。
SVM模型是將實例表示為空間中的點,這樣映射就使得單獨類別的實例被盡可能寬的明顯的間隔分開。然后,將新的實例映射到同一空間,并基于它們落在間隔的哪一側來預測所屬類別。
除了進行線性分類之外,SVM還可以使用所謂的[核技巧]有效地進行非線性分類,將其輸入隱式映射到高維特征空間中。
當數據未被標記時,不能進行監督式學習,需要用[非監督式學習],它會嘗試找出數據到簇的自然聚類,并將新數據映射到這些已形成的簇。將支持向量機改進的聚類算法被稱為支持向量聚類,當數據未被標記或者僅一些數據被標記時,支持向量聚類經常在工業應用中用作分類步驟的預處理。
H1 不能把類別分開。H2 可以,但只有很小的間隔。H3 以最大間隔將它們分開。
3.2 簡單的分類
◆ 可能大家認為最簡單的一種分類方法大概就是劃分"閾值"
了
◆ 例如判斷一一個人是否是禿頭:頭頂區域頭發數量小于100根則是禿頭
◆ 而SVM也是遵循這個道理,只不過它的"閾值”尋找過程更復雜,也更科學
3.3 SVM的基本思想
◆ SVM的主要思想是尋找能夠將數據進行分類的平面或超平面,在平面上的則是A類,在平面下的則是B類, 因此,SVM是一種二分類算法
◆ 因此,這個“閾值”更貼切地說應該稱為“邊界”, 而這個"邊界"恰恰就是通過向量來表示的,故而這個"邊界"我們就稱為支持向量
3.4 SVM處理非線性問題
◆ 在很多情況下,數據集并不是線性可分的,譬如:
3.5 SVM的核函數
◆ SVM雖然只能進行線性分類, 但是,可以通過引入核函數
,將非線性的數據,轉化為另一個空間中的線性可分數據,這叫做支持向量機的核技巧,可以認為是支持向量機的精髓之一
3.6 SVM的類別
◆ 基于硬間隔最大化的線性可分 支持向量機
◆ 基于軟間隔最大化的線性支持向量機
◆ 使用核函數的非線性支持向量機
3.7 線性支持向量機的數學原理
4 實戰SVM分類
-
-
支持向量機在高維或無限維空間中構造超平面或超平面集,其可用于分類,回歸或其他任務。 直觀地,通過與任何類的最近的訓練數據點具有最大距離的超平面(所謂的功能邊界)實現良好的分離,因為通常邊緣越大,分類器的泛化誤差越低。
Spark ML中的LinearSVC支持使用線性SVM進行二進制分類。 在內部,它使用OWLQN優化器優化鉸鏈損耗
-
代碼
-
iris數據集特征三列,所以報錯
-
只是用2列
-
計算結果
5 決策樹算法
5.1 決策樹介紹
◆ 決策樹因其進行決策判斷的結構與數據結構中的樹相同,故而得名
◆ 決策樹算法既可以實現分類,也可以實現回歸, 一-般用作分類的比較多
例如if-then就是一種簡單的決策樹
◆ 決策樹的解法有很多
例如ID3,C4.5等,其使用了信息論中熵的概念
5.2 決策樹的缺點
◆ 對輸入特征要求較高,很多情況下需要作預處理
◆ 識別類別過多時,發生錯誤的概率較大
5.3 決策樹示例
◆ 如圖展示了一個能否批準貸款的決策樹
5.4 決策樹的特征選擇
◆ 輸入變量的特征有很多,選擇特征作為分類判斷的依據之一便是能夠具有很好的區分度
◆ 那么也就是說,選擇出的變量能夠更具有代表性,以至于區分程度更高,作為決策樹的判斷節點
5.5 信息增益
◆ 定義隨機變量X的信息熵
◆ 已知隨機變量X ,對于變量Y的不確定性,使用條件熵
來衡量
◆ 當得知X而使得Y的不確定性減少的程度即為信息增益
5.6 決策樹生成 - ID3算法
◆ ID3算法是一種決策樹生成算法,其對于決策樹各個節點應用信息增益準則從而選取特征,在樹的每一層進行遞歸
,從而構建整棵樹
◆ 從根節點開始 ,在每層選擇信息增益最大的作為該節點的判斷特征
◆ 對所有節點進行相同操作,直到沒有特征選擇或者所有特征的信息增益均很小為止
5.7 決策樹的剪枝
◆ 決策樹是針對訓練集進行遞歸生成的,這樣對于訓練集效果自然非常好,但是對未知數據的預測結果可能并不會很好
◆ 即使用決策樹生成算法生成的決策樹模型過于復雜,對未知數據的泛化能力下降,即出現了過擬合
現象
◆ 過擬合是因為樹的結構過于復雜,將樹的結構精簡,就能夠減輕過擬合現象,即決策樹的剪枝
◆ 決策樹從葉節點開始遞歸地向根節點剪枝
◆ 判斷一個節點能否被減掉,只需比較修剪后與修剪前的損失函數值大小即可
◆ 如果在修剪之后,損失函數值小于等于原先的損失函數值,則將該父節點變為新的葉節點即可
5.8 CART算法
◆ CART即分類與回歸決策樹,其實是一棵二叉樹,根據判斷結果劃分為”是否”二分類
◆ 決策樹生成
基于訓練集生成 一個盡可能大的決策樹
◆ 決策樹剪枝
使用驗證集對生成的決策樹進行剪枝,以便使損失函數最小化
6 實戰基于決策樹的分類--案例1
決策樹是一種流行的分類和回歸方法。有關spark.ml實現的更多信息可以在決策樹的部分中找到。
示例
以下示例以LibSVM格式加載數據集,將其拆分為訓練和測試集,在第一個數據集上訓練,然后評估保持測試集。我們使用兩個特征變換器來準備數據;這些幫助標記和分類特征的索引類別,向決策樹算法可識別的DataFrame添加元數據。
import org.apache.spark.ml.Pipeline
import org.apache.spark.ml.classification.DecisionTreeClassificationModel
import org.apache.spark.ml.classification.DecisionTreeClassifier
import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator
import org.apache.spark.ml.feature.{IndexToString, StringIndexer, VectorIndexer}
// Load the data stored in LIBSVM format as a DataFrame.
val data = spark.read.format("libsvm").load("data/mllib/sample_libsvm_data.txt")
// Index labels, adding metadata to the label column.
// Fit on whole dataset to include all labels in index.
val labelIndexer = new StringIndexer()
.setInputCol("label")
.setOutputCol("indexedLabel")
.fit(data)
// Automatically identify categorical features, and index them.
val featureIndexer = new VectorIndexer()
.setInputCol("features")
.setOutputCol("indexedFeatures")
.setMaxCategories(4) // features with > 4 distinct values are treated as continuous.
.fit(data)
// Split the data into training and test sets (30% held out for testing).
val Array(trainingData, testData) = data.randomSplit(Array(0.7, 0.3))
// Train a DecisionTree model.
val dt = new DecisionTreeClassifier()
.setLabelCol("indexedLabel")
.setFeaturesCol("indexedFeatures")
// Convert indexed labels back to original labels.
val labelConverter = new IndexToString()
.setInputCol("prediction")
.setOutputCol("predictedLabel")
.setLabels(labelIndexer.labels)
// Chain indexers and tree in a Pipeline.
val pipeline = new Pipeline()
.setStages(Array(labelIndexer, featureIndexer, dt, labelConverter))
// Train model. This also runs the indexers.
val model = pipeline.fit(trainingData)
// Make predictions.
val predictions = model.transform(testData)
// Select example rows to display.
predictions.select("predictedLabel", "label", "features").show(5)
// Select (prediction, true label) and compute test error.
val evaluator = new MulticlassClassificationEvaluator()
.setLabelCol("indexedLabel")
.setPredictionCol("prediction")
.setMetricName("accuracy")
val accuracy = evaluator.evaluate(predictions)
println(s"Test Error = ${(1.0 - accuracy)}")
val treeModel = model.stages(2).asInstanceOf[DecisionTreeClassificationModel]
println(s"Learned classification tree model:\n ${treeModel.toDebugString}")
這里要詳解管道概念
6.1 ML Pipeline
Spark ML Pipeline 的出現,是受到了 scikit-learn 項目的啟發,并且總結了 MLlib 在處理復雜機器學習問題上的弊端,旨在向用戶提供基于 DataFrame 之上的更加高層次的 API 庫,以更加方便的構建復雜的機器學習工作流式應用。一個 Pipeline 在結構上會包含一個或多個 PipelineStage,每一個 PipelineStage 都會完成一個任務,如數據集處理轉化,模型訓練,參數設置或數據預測等,這樣的 PipelineStage 在 ML 里按照處理問題類型的不同都有相應的定義和實現。接下來,我們先來了解幾個重要概念。
在本節中,我們將介紹ML管道的概念。 ML Pipelines提供了一組基于DataFrame構建的統一的高級API,可幫助用戶創建和調整實用的機器學習流程。
6.1.1 主要概念(Main concepts in Pipelines)
6.1.1.1 DataFrame
- 此ML API使用Spark SQL中的DataFrame作為ML數據集,它可以包含各種數據類型.
例如,DataFrame可以具有存儲文本,特征向量,真實標簽和預測的不同列.
它較之 RDD,包含了 schema 信息,更類似傳統數據庫中的二維表格。它被 ML Pipeline 用來存儲源數據。
DataFrame 可以被用來保存各種類型的數據,如我們可以把特征向量存儲在 DataFrame 的一列中,這樣用起來是非常方便的。
機器學習可以應用于各種數據類型,例如矢量,文本,圖像和結構化數據。 此API采用Spark SQL的DataFrame以支持各種數據類型。
DataFrame支持許多基本和結構化類型, 除了Spark SQL指南中列出的類型之外,DataFrame還可以使用ML Vector類型。
可以從常規RDD隱式或顯式創建DataFrame
6.1.1.2 Transformer
- Transformer是一種可以將一個DataFrame轉換為另一個DataFrame的算法.
例如,ML模型是變換器,其將具有特征的DataFrame轉換為具有預測的DataFrame.
Transformer 中文可以被翻譯成轉換器,是一個 PipelineStage,實現上也是繼承自 PipelineStage 類
主要是用來把 一個 DataFrame 轉換成另一個 DataFrame,比如一個模型就是一個 Transformer,因為它可以把 一個不包含預測標簽的測試數據集 DataFrame 打上標簽轉化成另一個包含預測標簽的 DataFrame,顯然這樣的結果集可以被用來做分析結果的可視化.
6.1.1.3 Estimator
- Estimator是一種算法,可以適應DataFrame以生成Transformer.
例如,學習算法是Estimator,其在DataFrame上訓練并產生模型。
Estimator 中文可以被翻譯成評估器或適配器,在 Pipeline 里通常是被用來操作 DataFrame 數據并生產一個 Transformer,如一個隨機森林算法就是一個 Estimator,因為它可以通過訓練特征數據而得到一個隨機森林模型。實現上 Estimator 也是繼承自 PipelineStage 類
6.1.1.4 Parameter
Parameter 被用來設置 Transformer 或者 Estimator 的參數。
要構建一個 Pipeline,首先我們需要定義 Pipeline 中的各個 PipelineStage,如指標提取和轉換模型訓練等。有了這些處理特定問題的 Transformer 和 Estimator,我們就可以按照具體的處理邏輯來有序的組織 PipelineStages 并創建一個 Pipeline,如 val pipeline = new Pipeline().setStages(Array(stage1,stage2,stage3,…))。然后就可以把訓練數據集作為入參并調用 Pipelin 實例的 fit 方法來開始以流的方式來處理源訓練數據,這個調用會返回一個 PipelineModel 類實例,進而被用來預測測試數據的標簽,它是一個 Transformer。
6.1.1.5 Pipeline
管道:管道將多個Transformers和Estimators鏈接在一起以指定ML工作流程。
6.1.2 How It Works
管道被指定為階段序列,并且每個階段是變換器或估計器。 這些階段按順序運行,輸入DataFrame在通過每個階段時進行轉換。 對于Transformer階段,在DataFrame上調用transform()方法。 對于Estimator階段,調用fit()方法以生成Transformer(它成為PipelineModel或擬合管道的一部分),并在DataFrame上調用Transformer的transform()方法。
-
我們為簡單的文本文檔工作流說明了這一點。 下圖是管道的培訓時間使用情況。
上圖中,頂行表示具有三個階段的管道。前兩個(Tokenizer和HashingTF)是變形金剛(藍色),第三個(LogisticRegression)是Estimator(紅色)。底行表示流經管道的數據,其中柱面表示DataFrame。在原始DataFrame上調用Pipeline.fit()方法,該原始DataFrame具有原始文本文檔和標簽。 Tokenizer.transform()方法將原始文本文檔拆分為單詞,向DataFrame添加一個帶有單詞的新列。 HashingTF.transform()方法將單詞列轉換為要素向量,將包含這些向量的新列添加到DataFrame?,F在,由于LogisticRegression是一個Estimator,因此Pipeline首先調用LogisticRegression.fit()來生成LogisticRegressionModel。如果Pipeline有更多的Estimators,它會在將DataFrame傳遞給下一個階段之前在DataFrame上調用LogisticRegressionModel的transform()方法。
管道是估算器。因此,在Pipeline的fit()方法運行之后,它會生成一個PipelineModel,它是一個Transformer。這個PipelineModel在測試時使用;下圖說明了這種用法。
在上圖中,PipelineModel具有與原始Pipeline相同的階段數,但原始Pipeline中的所有Estimators都變為Transformers。 當在測試數據集上調用PipelineModel的transform()方法時,數據將按順序通過擬合的管道傳遞。 每個階段的transform()方法都會更新數據集并將其傳遞給下一個階段。
Pipelines和PipelineModel有助于確保培訓和測試數據經過相同的功能處理步驟。
-
代碼
-
結果
7 實戰基于決策樹的分類--案例2
-
-
復制數據得到女生數據集
-
復制數據得到男生數據集
-
代碼
-
預測結果
參考
貝葉斯定理
使用 ML Pipeline 構建機器學習工作流