Spark MLlib
機器學習是什麼?
機器學習
數據挖掘有着50多年的發展歷史。機器學習就是其子領域之一,特點是利用大型計算機集羣來從海量數據中分析和提取知識
機器學習與計算統計學密切相關。它與數學優化緊密關聯,爲其提供方法、理論和應用領域。機器學習在各種傳統設計和編程不能勝任的計算機任務中有廣泛應用。典型的應用如垃圾郵件過濾
、光學字符識別(OCR)
、搜索引擎和計算機視覺
。機器學習有時和數據挖掘聯用,但更偏向探索性數據分析
,亦稱爲無監督學習
。
與學習系統的可用輸入自然屬性不同,機器學習系統可分爲3種
。學習算法發現輸入數據的內在結構。它可以有目標(隱含模式)
,也可以是發現特徵的一種途徑。
無監督學習 | 學習系統的輸入數據中並不包含對應的標籤(或期望的輸出) ,它需要自行從輸入中找到輸入數據的內在結構 |
監督學習 | 系統已知各輸入對應的期望輸出 系統的目標是學習如何將輸入映射到輸出 |
強化學習 | 系統與環境進行交互,它有已定義的目標,但沒有人類顯式地告知其是否正在接近目標 |
Spark MLlib
MLlib是Spark的機器學習(ML)庫。其目標是使實用的機器學習可擴展且容易。在較高級別,它提供了以下工具:
- ML算法:常見的學習算法,例如分類,迴歸,聚類和協同過濾
- 特徵化:特徵提取,變換,降維和選擇
- 管道:用於構建,評估和調整ML管道的工具
- 持久性:保存和加載算法,模型和管道
- 實用程序:線性代數,統計信息,數據處理等。
Spark MLlib案例
基於
DataFrame
的API是主要API
快速入門
- pom.xml
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-mllib -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-mllib_2.11</artifactId>
<version>2.2.1</version>
</dependency>
def main(args: Array[String]): Unit = {
// 屏蔽日誌
Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
Logger.getLogger("org.apache.jetty.server").setLevel(Level.OFF)
val spark = SparkSession
.builder()
.master("local[*]")
.appName(Demo01.getClass.getName)
.getOrCreate()
import spark.implicits._
val data = Seq(
/**
* 稀疏向量表示方式
* 4, Seq((0, 1.0), (3, -2.0))
* 表示向量長度爲4 有兩個非0位置:0和3位置,0和3的值分別爲1.0、-2.0
* 該向量可表示爲(1.0, 0, 0, -2.0)
*/
Vectors.sparse(4, Seq((0, 1.0), (3, -2.0))),
// 密集向量表示方式
Vectors.dense(4.0, 5.0, 0.0, 3.0),
Vectors.dense(6.0, 7.0, 0.0, 8.0),
Vectors.sparse(4, Seq((0, 9.0), (3, 1.0)))
)
val df = data.map(Tuple1.apply).toDF("features")
df.show()
// 計算df features列的相關性
val Row(coeff1: Matrix) = Correlation.corr(df, "features").head
println(s"Pearson correlation matrix:\n $coeff1")
val Row(coeff2: Matrix) = Correlation.corr(df, "features", "spearman").head
println(s"Spearman correlation matrix:\n $coeff2")
spark.stop()
}
基本統計
Correlation(相關性)
Correlation 使用指定的方法爲向量的輸入數據集計算相關矩陣。輸出將是一個DataFrame,其中包含向量列的相關矩陣。
皮爾森係數公式:
當兩個變量的線性關係增強時,相關係數趨於1或-1。正相關時趨於1,負相關時趨於-1。當兩個變量獨立時相關係統爲0,但反之不成立。當Y和X服從聯合正態分佈時,其相互獨立和不相關是等價的
val data = Seq(
/**
* 稀疏向量表示方式
* 4, Seq((0, 1.0), (3, -2.0))
* 表示向量長度爲4 有兩個非0位置:0和3位置,0和3的值分別爲1.0、-2.0
* 該向量可表示爲(1.0, 0, 0, -2.0)
*/
Vectors.sparse(4, Seq((0, 1.0), (3, -2.0))),
// 密集向量表示方式
Vectors.dense(4.0, 5.0, 0.0, 3.0),
Vectors.dense(6.0, 7.0, 0.0, 8.0),
Vectors.sparse(4, Seq((0, 9.0), (3, 1.0)))
)
val df = data.map(Tuple1.apply).toDF("features")
df.show()
// 計算features的相關性, method係數默認爲Pearson
val Row(coeff1: Matrix) = Correlation.corr(df, "features").head
println(s"Pearson correlation matrix:\n $coeff1")
// 計算features的相關性, method係數爲Spearson
val Row(coeff2: Matrix) = Correlation.corr(df, "features", "spearman").head
println(s"Spearman correlation matrix:\n $coeff2")
Hypothesis testing(假設檢驗)
假設檢驗是一種強大的統計工具,可用來確定結果是否具有統計學意義,以及該結果是否偶然發生。spark.ml當前支持Pearson的卡方(
數學處理錯誤
)測試獨立性。
ChiSquareTest針對標籤上的每個功能進行Pearson的獨立性測試。對於每個要素,(要素,標籤)對將轉換爲列聯矩陣,針對該列矩陣計算卡方統計量。所有標籤和特徵值必須是分類的。
import org.apache.spark.ml.linalg.{Vector, Vectors}
import org.apache.spark.ml.stat.ChiSquareTest
val data = Seq(
(0.0, Vectors.dense(0.5, 10.0)),
(0.0, Vectors.dense(1.5, 20.0)),
(1.0, Vectors.dense(1.5, 30.0)),
(0.0, Vectors.dense(3.5, 30.0)),
(0.0, Vectors.dense(3.5, 40.0)),
(1.0, Vectors.dense(3.5, 40.0))
)
val df = data.toDF("label", "features")
df.show()
val chi = ChiSquareTest.test(df, "features", "label").head
println(s"pValues = ${chi.getAs[Vector](0)}")
println(s"degreesOfFreedom ${chi.getSeq[Int](1).mkString("[", ",", "]")}")
println(s"statistics ${chi.getAs[Vector](2)}")
Summarizer(總結器)
import spark.implicits._
import org.apache.spark.ml.stat.Summarizer._
val data = Seq(
(Vectors.dense(2.0, 3.0, 5.0), 1.0),
(Vectors.dense(4.0, 6.0, 7.0), 2.0)
)
val df = data.toDF("features", "weight")
val (meanVal, varianceVal) = df.select(metrics("mean", "variance")
.summary($"features", $"weight").as("summary"))
.select("summary.mean", "summary.variance")
.as[(Vector, Vector)].first()
println(s"with weight: mean = ${meanVal}, variance = ${varianceVal}")
val (meanVal2, varianceVal2) = df.select(mean($"features"), variance($"features"))
.as[(Vector, Vector)].first()
println(s"without weight: mean = ${meanVal2}, sum = ${varianceVal2}")