機器學習(Machine Learning, ML)是一門多領域交叉學科,涉及機率論、統計學、逼近論、凸分析、算法複雜度理論等多門學科。專門研究計算機怎樣模擬或實現人類的學習行爲,以獲取新的知識或技能,從新組織已有的知識結構使之不斷改善自身的性能。
它是人工智能的核心,是使計算機具備智能的根本途徑,其應用遍佈人工智能的各個領域。目前,世界上共有幾百種不一樣的機器學習算法。java
Classification (分類)
給定一堆樣本數據以及這些數據所屬的類別標籤,經過算法來預測新數據的類別,有先驗知識。算法
對於一個 classifier ,一般須要你告訴它「這個東西被分爲某某類」這樣一些例子,理想狀況下,一個 classifier 會從它獲得的訓練集中進行「學習」,從而具有對未知數據進行分類的能力,這種提供訓練數據的過程一般叫作 supervised learning (監督學習)網絡
Clustering(聚類)
事先並不知道一堆數據能夠被劃分到哪些類,經過算法來發現數據之間的類似性,從而將類似的數據劃入相應的類,簡單地說就是把類似的東西分到一組,沒有先驗知識。dom
聚類的時候,咱們並不關心某一類是什麼,咱們須要實現的目標只是把類似的東西聚到一塊兒,所以,一個聚類算法一般只須要知道如何計算類似度就能夠開始工做了,所以 clustering 一般並不須要使用訓練數據進行學習,這在 Machine Learning 中被稱做 unsupervised learning (無監督學習).機器學習
常見的分類與聚類算法工具
經常使用的分類算法:k-最近鄰法(k-nearest neighbor,kNN),決策樹分類法,樸素貝葉斯分類算法(native Bayesian classifier)、支持向量機(SVM)的分類器,神經網絡法,模糊分類法等等。oop
常見聚類算法: K均值(K-means clustering)聚類算法、K-MEDOIDS算法、CLARANS算法;BIRCH算法、CURE算法、CHAMELEON算法等;基於密度的方法:DBSCAN算法、OPTICS算法、DENCLUE算法等;基於網格的方法:STING算法、CLIQUE算法、WAVE-CLUSTER算法;性能
機器學習按照訓練數據是否有「先驗知識」,通常劃分爲三類:
1) 監督學習(supervised learning)
2) 無監督學習(unsupervised learning)
3) 半監督學習(semi-supervised learning)學習
監督式學習技術須要關於結果的先驗知識
例如,若是咱們正在研究一個市場活動的歷史數據,咱們能夠根據市場是否產生預期的反應來對數據進行分類,或決定下一步要花多少錢。監督式學習技術爲預測和分類提供了強大的工具。測試
無監督學習技術不須要先驗知識
例如,在某些欺詐的案例中,只有當事情發生好久之後,咱們纔可能知道某次交易是否是欺詐。在這種狀況下,與其試圖預測哪些交易是欺詐,咱們不如使用機器學習來識別那些可疑的交易,並作出標記,以備後續觀察。咱們對某種特定的結果缺少先驗知識、但仍但願從數據中汲取有用的洞察時,就要用到無監督式學習。
是一個簡單的聚類算法,目的是把n個對象根據他們的屬性分爲k個分類,k<n。
優勢:算法速度很快
缺點:分組的數目k是一個輸入參數,不合適的k可能返回較差的結果。
spark kmeans算法demo
object KMeansDemo { def main(args: Array[String]) { val conf = new SparkConf() conf.setAppName("ML") conf.setMaster("local[*]") val sc = new SparkContext(conf) sc.setLogLevel("ERROR") // Load and parse the data val data = sc.textFile("D:/mllib/kmeans_data.txt") // 數據轉換成向量,每一行三個數據,所以是三維的 val parsedData = data.map(s => Vectors.dense(s.split(' ').map(_.toDouble))).cache() // Cluster the data into two classes using KMeans val numClusters = 2 // 最大迭代次數 val numIterations = 20 // 訓練KMeansModel數據模型 val clusters = KMeans.train(parsedData, numClusters, numIterations) // 打印聚類中心點 println(" cluster center ") for (c <- clusters.clusterCenters) { println(" " + c.toString) } // 打印每一個點屬於哪一個分類 for (data <- parsedData) { println(data + " " + clusters.predict(data)) } // 預測數據屬於哪一個類別 println("Vectors 0.2 0.2 0.2 is belongs to clusters:" + clusters.predict(Vectors.dense("0.2 0.2 0.2".split(' ').map(_.toDouble)))) println("Vectors 8 8 8 is belongs to clusters:" + clusters.predict(Vectors.dense("8 8 8".split(' ').map(_.toDouble)))) // Evaluate clustering by computing Within Set Sum of Squared Errors val WSSSE = clusters.computeCost(parsedData) println("Within Set Sum of Squared Errors = " + WSSSE) // Save and load model // clusters.save(sc, "D:/mllib/save/kmeans/") // val sameModel = KMeansModel.load(sc, "D:/mllib/save/kmeans/") sc.stop() } }
D:/mllib/kmeans_data.txt數據
0.0 0.0 0.0 0.1 0.1 0.1 0.2 0.2 0.2 9.0 9.0 9.0 9.1 9.1 9.1 9.2 9.2 9.2
樸素貝葉斯法是基於貝葉斯定理與特徵條件獨立假設的分類方法。算法的基礎是機率問題,分類原理是經過某對象的先驗機率,利用貝葉斯公式計算出其後驗機率,即該對象屬於某一類的機率,選擇具備最大後驗機率的類做爲該對象所屬的類。樸素貝葉斯假設是約束性很強的假設,假設特徵條件獨立,但樸素貝葉斯算法簡單,快速,具備較小的出錯率。 在樸素貝葉斯的應用中,主要研究了電子郵件過濾以及文本分類研究。
spark Naive Bayes算法demo
def main(args: Array[String]) { val conf = new SparkConf() conf.setAppName("ML") conf.setMaster("local[*]") val sc = new SparkContext(conf) sc.setLogLevel("ERROR") // 加載數據 val data = sc.textFile("D:/mllib/sample_naive_bayes_data.txt") // 0,1 0 0 數據格式,第一個0是label,後面的1 0 0是特徵 val parsedData = data.map { line => val parts = line.split(',') // 轉換數據爲LabeledPoint LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(' ').map(_.toDouble))) } // 數據分爲training(60%)和測試數據(40%). val splits = parsedData.randomSplit(Array(0.6, 0.4), seed = 11L) val training = splits(0) val test = splits(1) // 開始訓練模型 modelType指定方法類型,multinomial或者bernoulli val model = NaiveBayes.train(training, lambda = 1.0, modelType = "multinomial") val testData = LabeledPoint(0, Vectors.dense("1 0 0".split(' ').map(_.toDouble))) // 根據特徵預測label println("label:" + model.predict(testData.features)) // model.predict(p.features) 預測值 p.label 實際值 val predictionAndLabel = test.map(p => (model.predict(p.features), p.label)) // 計算準確率 val accuracy = 1.0 * predictionAndLabel.filter(x => x._1 == x._2).count() / test.count() sc.stop() }
數據
0,1 0 0 0,2 0 0 0,3 0 0 0,4 0 0 1,0 1 0 1,0 2 0 1,0 3 0 1,0 4 0 2,0 0 1 2,0 0 2 2,0 0 3 2,0 0 4
分類算法,分類思想比較簡單,從訓練樣本中找出K個與其最相近的樣本,而後看這k個樣本中哪一個類別的樣本多,則待斷定的值(或說抽樣)就屬於這個類別。近朱者赤,近墨者黑。
分類算法,SVM可分爲三類:線性可分(linear SVM in linearly separable case)的線性SVM、線性不可分的線性SVM、非線性(nonlinear)SVM
spark demo
def main(args: Array[String]) { val conf = new SparkConf() conf.setAppName("ML") conf.setMaster("local[*]") val sc = new SparkContext(conf) sc.setLogLevel("ERROR") // 加載數據,把數據轉換成特徵向量 val data = MLUtils.loadLibSVMFile(sc, "D:/mllib/sample_libsvm_data.txt") // 數據分爲training (60%)和test (40%). val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L) val training = splits(0).cache() val test = splits(1) // 迭代次數 val numIterations = 200 val model = SVMWithSGD.train(training, numIterations) // Clear the default threshold. model.clearThreshold() // 計算預測數據 val scoreAndLabels = test.map { point => val score = model.predict(point.features) // 打印預測值與實際值 println(score + " : " + point.label) (score, point.label) } // 對數據進行評估 val metrics = new BinaryClassificationMetrics(scoreAndLabels) val auROC = metrics.areaUnderROC() println("Area under ROC = " + auROC) // 計算正確率 val trainErr = scoreAndLabels.filter(r => r._1 != r._2).count.toDouble / test.count println("train error = " + trainErr) sc.stop() }
數據在spark目錄spark-2.1.0-bin-hadoop2.7\data\mllib\sample_libsvm_data.txt
分類算法,主要在流行病學中應用較多,比較經常使用的情形是探索某疾病的危險因素,根據危險因素預測某疾病發生的機率
def main(args: Array[String]) { val conf = new SparkConf() conf.setAppName("ML") conf.setMaster("local[*]") val sc = new SparkContext(conf) sc.setLogLevel("ERROR") // 加載數據,把數據轉換成特徵向量 val data = MLUtils.loadLibSVMFile(sc, "D:/mllib/sample_libsvm_data.txt") // 數據分爲training (60%)和test (40%). val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L) val training = splits(0).cache() val test = splits(1) // 邏輯迴歸 val model = new LogisticRegressionWithLBFGS().setNumClasses(10) .run(training) // 計算預測數據 val predictionAndLabels = test.map { point => val score = model.predict(point.features) // 打印預測值與實際值 println(score + " : " + point.label) (score, point.label) } // 對數據進行評估 val metrics = new MulticlassMetrics(predictionAndLabels) val precision = metrics.precision println("Precision = " + precision) // 計算正確率 val trainErr = predictionAndLabels.filter(r => r._1 != r._2).count.toDouble / test.count println("train error = " + trainErr) sc.stop() }
協同過濾經常被用於分辨某位特定顧客可能感興趣的東西,這些結論來自於對其餘類似顧客對哪些產品感興趣的分析。協同過濾以其出色的速度和健壯性,在全球互聯網領域煊赫一時
def main(args: Array[String]) { val conf = new SparkConf() conf.setAppName("ML") conf.setMaster("local[*]") val sc = new SparkContext(conf) sc.setLogLevel("ERROR") // 加載數據,把數據轉換成特徵向量 val data = sc.textFile("D:/mllib/als/test.data") val ratings = data.map(_.split(',') match { case Array(user, item, rate) => // 用戶 產品 評分 Rating(user.toInt, item.toInt, rate.toDouble) }) // 構建推薦模型 val rank = 10 // 迭代次數 val numIterations = 10 // rank使用的特徵的數量 val model = ALS.train(ratings, rank, numIterations, 0.01) // 數據轉換成(user, product) val usersProducts = ratings.map { case Rating(user, product, rate) => (user, product) } val predictions = model.predict(usersProducts).map { case Rating(user, product, rate) => println(rate) ((user, product), rate) } // 基於用戶推薦產品 val recommends = model.recommendProducts(4, 1) for (r <- recommends) { println(r) } // 基於產品推薦用戶 // model.recommendUsers() // 實際值和預測值進行join val ratesAndPreds = ratings.map { case Rating(user, product, rate) => println(rate) ((user, product), rate) }.join(predictions) val MSE = ratesAndPreds.map { case ((user, product), (r1, r2)) => val err = (r1 - r2) // 平方 err * err }.mean() // 均值 // 均方偏差 println("Mean Squared Error = " + MSE) sc.stop() }
決策樹(Decision Tree)是一種簡單可是普遍使用的分類器。經過訓練數據構建決策樹,能夠高效的對未知的數據進行分類。決策數有兩大優勢:1)決策樹模型能夠讀性好,具備描述性,有助於人工分析;2)效率高,決策樹只須要一次構建,反覆使用,每一次預測的最大計算次數不超過決策樹的深度。
def main(args: Array[String]) { val conf = new SparkConf() conf.setAppName("ML") conf.setMaster("local[*]") val sc = new SparkContext(conf) sc.setLogLevel("ERROR") // 加載數據,把數據轉換成特徵向量 val data = MLUtils.loadLibSVMFile(sc, "D:/mllib/sample_libsvm_data.txt") // 數據70%training 30% test val splits = data.randomSplit(Array(0.7, 0.3)) val (trainingData, testData) = (splits(0), splits(1)) val numClasses = 2 val categoricalFeaturesInfo = Map[Int, Int]() val impurity = "gini" val maxDepth = 5 val maxBins = 32 // 構建決策樹模型 numClasses分幾類 // impurity "gini" (recommended) or "entropy" // maxDepth 樹的最大深度 // maxBins 建議 32 val model = DecisionTree.trainClassifier(trainingData, numClasses, categoricalFeaturesInfo, impurity, maxDepth, maxBins) // 經過模型預測測試數據 val labelAndPreds = testData.map { point => val prediction = model.predict(point.features) (point.label, prediction) } // 計算錯誤率 val testErr = labelAndPreds.filter(r => r._1 != r._2).count().toDouble / testData.count() println("Test Error = " + testErr) // println("Learned classification tree model:\n" + model.toDebugString) sc.stop() }