Spark MLlib回归算法------线性回归、逻辑回归、SVM和ALS
Spark MLlib回歸算法------線性回歸、邏輯回歸、SVM和ALS
?
1、線性回歸:
(1)模型的建立:
回歸正則化方法(Lasso,Ridge和ElasticNet)在高維和數(shù)據(jù)集變量之間多重共線性情況下運行良好。
?
數(shù)學上,ElasticNet被定義為L1和L2正則化項的凸組合:
通過適當設(shè)置α,ElasticNet包含L1和L2正則化作為特殊情況。例如,如果用參數(shù)α設(shè)置為1來訓練線性回歸模型,則其等價于Lasso模型。另一方面,如果α被設(shè)置為0,則訓練的模型簡化為ridge回歸模型。?
(2)實戰(zhàn):
利用線性回歸+隨機梯度下降算法構(gòu)建一個線性模型,并進行預測,最后計算均方誤差(Mean Squared Errors)來對模型進行評估。
val conf = new SparkConf().setAppName("LeanerRegressionModelDemo").setMaster("local[4]")val sc = new SparkContext(conf)val data = sc.textFile("C://Users//BIGDATA//Desktop//文件//BigData//Spark//7.SparkMLlib_2//resource//resource//ridge-data//lpsa.data")val parsedData = data.map { line =>val parts = line.split(',')LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(' ').map(_.toDouble)))}.cache()// Building the modelval numIterations = 20val model = LinearRegressionWithSGD.train(parsedData, numIterations)// Evaluate model on training examples and compute training errorval valuesAndPreds = parsedData.map { point =>val prediction = model.predict(point.features)(point.label, prediction)}val MSE = valuesAndPreds.map{ case(v, p) => math.pow((v - p), 2)}.reduce(_ + _)/valuesAndPreds.countprintln("training Mean Squared Error = " + MSE)
2、邏輯回歸:
(1)數(shù)學公式
邏輯回歸一般是用來預測二元分類的,它的線性方法可以用公式(1)進行描述,它的損失函數(shù)用公式(2)進行描術(shù):
f(w):=λR(w)+1n∑i=1nL(w;xi,yi)? ????????(1)這里,xi∈Rd 代表訓練數(shù)據(jù), 1≤i≤n , yi∈R對應的是labels.?
目標函數(shù)f有兩部分:正則化和損失函數(shù),前者的作用是為了去躁,后者是用來評估訓練數(shù)據(jù)模型的誤差。在w中損失函數(shù)L(w;.)是一個典型的凸函數(shù)。固定的正則化參數(shù)λ≥0(代碼中用regParam 表示),用來權(quán)衡兩目標間的最小損失。?
下面是sparkmllib當中的損失函數(shù)和它對應的梯度下降方法數(shù)學表達式:?
?
接下來的正則化函數(shù)公式:?
?
sign(w) 是由 (±1)組成的向量。
對于二元分類問題,訓練輸出一個預測模型,給定一組向量X,能過通過公式(3)進行預測。
f(z)=1/(1+e?z)???????????? (3)其中 z=wTx,(數(shù)學公式不好弄,T代表轉(zhuǎn)置),默認情況下,f(wTx)>0.5代表正面,其他就是反面。?
在sparkmllib當中,我們使用 mini-batch gradient descent 和 L-BFGS 來解決邏輯回歸,推薦使用L-BFGS算法,因為它收斂更快。
(2)實戰(zhàn):
val conf = new SparkConf().setAppName("LogisticRegressionDemo").setMaster("local")val sc = new SparkContext(conf)// Load training data in LIBSVM format.val data = MLUtils.loadLibSVMFile(sc, "C://Users//BIGDATA//Desktop//文件//BigData//Spark//7.SparkMLlib_2//resource//resource//sample_libsvm_data.txt")// Split data into training (60%) and test (40%).val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L)val training = splits(0).cache()val test = splits(1)// Run training algorithm to build the modelval model = new LogisticRegressionWithLBFGS().setNumClasses(10).run(training)// Compute raw scores on the test set.val predictionAndLabels = test.map { case LabeledPoint(label, features) =>val prediction = model.predict(features)(prediction, label)}// Get evaluation metrics.val metrics = new MulticlassMetrics(predictionAndLabels)val precision = metrics.precisionprintln("Precision = " + precision)// Save and load modelmodel.save(sc, "target/tmp/scalaLogisticRegressionWithLBFGSModel")val sameModel = LogisticRegressionModel.load(sc,"target/tmp/scalaLogisticRegressionWithLBFGSModel")?
3、Svm:
(1)方法簡介:
? 支持向量機SVM是一種二分類模型。它的基本模型是定義在特征空間上的間隔最大的線性分類器。支持向量機學習方法包含3種模型:線性可分支持向量機、線性支持向量機及非線性支持向量機。當訓練數(shù)據(jù)線性可分時,通過硬間隔最大化,學習一個線性的分類器,即線性可分支持向量機;當訓練數(shù)據(jù)近似線性可分時,通過軟間隔最大化,也學習一個線性的分類器,即線性支持向量機;當訓練數(shù)據(jù)線性不可分時,通過使用核技巧及軟間隔最大化,學習非線性支持向量機。線性支持向量機支持L1和L2的正則化變型。
(2)基本原理
? 支持向量機,因其英文名為support?vector?machine,故一般簡稱SVM。SVM從線性可分情況下的最優(yōu)分類面發(fā)展而來。最優(yōu)分類面就是要求分類線不但能將兩類正確分開(訓練錯誤率為0),且使分類間隔最大。SVM考慮尋找一個滿足分類要求的超平面,并且使訓練集中的點距離分類面盡可能的遠,也就是尋找一個分類面使它兩側(cè)的空白區(qū)域(margin)最大。這兩類樣本中離分類面最近,且平行于最優(yōu)分類面的超平面上的點,就叫做支持向量(下圖中紅色的點)。
svm
假設(shè)超平面可描述為:
\(wx+b=0, w\in R^n, b\in R \)
其分類間隔等于?\(\frac{2}{||w||}\)?。其學習策略是使數(shù)據(jù)間的間隔最大化,最終可轉(zhuǎn)化為一個凸二次規(guī)劃問題的求解。
分類器的損失函數(shù)(hinge loss鉸鏈損失)如下所示:
\(L(w;x,y):=max(0,1-yw^Tx)\)
默認情況下,線性SVM是用L2 正則化來訓練的,但也支持L1正則化。在這種情況下,這個問題就變成了一個線性規(guī)劃。
? 線性SVM算法輸出一個SVM模型。給定一個新的數(shù)據(jù)點,比如說?\(x\)?,這個模型就會根據(jù)?\(w^Tx\)?的值來進行預測。默認情況下,如果?\(w^Tx \ge 0\)?,則輸出預測結(jié)果為正(因為我們想要損失函數(shù)最小,如果預測為負,則會導致?lián)p失函數(shù)大于1),反之則預測為負。
(3)實戰(zhàn):
? 下面的例子具體介紹了如何讀入一個數(shù)據(jù)集,然后用SVM對訓練數(shù)據(jù)進行訓練,然后用訓練得到的模型對測試集進行預測,并計算錯誤率。以iris數(shù)據(jù)集為例進行分析。iris以鳶尾花的特征作為數(shù)據(jù)來源,數(shù)據(jù)集包含150個數(shù)據(jù)集,分為3類,每類50個數(shù)據(jù),每個數(shù)據(jù)包含4個屬性,是在數(shù)據(jù)挖掘、數(shù)據(jù)分類中非常常用的測試集、訓練集。
????
? ? ?
val conf = new SparkConf().setAppName("LogisticRegressionDemo").setMaster("local")val sc = new SparkContext(conf)//讀取數(shù)據(jù)/*首先,讀取文本文件;然后,通過map將每行的數(shù)據(jù)用“,”隔開,在我們的數(shù)據(jù)集中,每行被分成了5部分,前4部分是鳶尾花的4個特征,最后一部分是鳶尾花的分類。把這里我們用LabeledPoint來存儲標簽列和特征列。LabeledPoint在監(jiān)督學習中常用來存儲標簽和特征,其中要求標簽的類型是double,特征的類型是Vector。所以,我們把鶯尾花的分類進行了一下改變,"Iris-setosa"對應分類0,"Iris-versicolor"對應分類1,其余對應分類2;然后獲取鶯尾花的4個特征,存儲在Vector中。*/val data = sc.textFile("C://Users//BIGDATA//Desktop//文件//BigData//Spark//7.SparkMLlib_2//resource//resource//iris.data")val parsedData = data.map { line =>val parts = line.split(',')LabeledPoint(if(parts(4)=="Iris-setosa") 0.toDouble else if (parts(4) =="Iris-versicolor") 1.toDoubleelse 2.toDouble, Vectors.dense(parts(0).toDouble,parts(1).toDouble,parts(2).toDouble,parts(3).toDouble))}//構(gòu)建模型:/*?* 因為SVM只支持2分類,所以我們要進行一下數(shù)據(jù)抽取,這里我們通過filter過濾掉第2類的數(shù)據(jù),只選取第0類和第1類的數(shù)據(jù)。然后,我們把數(shù)據(jù)集劃分成兩部分,其中訓練集占60%,測試集占40%:* 接下來,通過訓練集構(gòu)建模型SVMWithSGD。這里的SGD即著名的隨機梯度下降算法(Stochastic Gradient Descent)。* 設(shè)置迭代次數(shù)為1000,除此之外還有stepSize(迭代步伐大小),regParam(regularization正則化控制參數(shù)),miniBatchFraction(每次迭代參與計算的樣本比例),initialWeights(weight向量初始值)等參數(shù)可以進行設(shè)*/val splits = parsedData.filter { point => point.label != 2 }.randomSplit(Array(0.6, 0.4), seed = 11L)val training = splits(0).cache()val test = splits(1)val numIterations = 1000val model = SVMWithSGD.train(training, numIterations)//模型評估/*我們清除默認閾值,這樣會輸出原始的預測評分,即帶有確信度的結(jié)果。如果設(shè)置了閾值,則會把大于閾值的結(jié)果當成正預測,小于閾值的結(jié)果當成負預測。? 最后,我們構(gòu)建評估矩陣,把模型預測的準確性打印出來:*/model.clearThreshold()val scoreAndLabels = test.map { point =>val score = model.predict(point.features)(score, point.label)}scoreAndLabels.foreach(println)model.setThreshold(0.0)scoreAndLabels.foreach(println)val metrics = new BinaryClassificationMetrics(scoreAndLabels)val auROC = metrics.areaUnderROC()println("Area under ROC = " + auROC)
4、als:
(1)算法介紹:
??? 協(xié)同過濾常被用于推薦系統(tǒng)。這類技術(shù)目標在于填充“用戶-商品”聯(lián)系矩陣中的缺失項。Spark.ml目前支持基于模型的協(xié)同過濾,其中用戶和商品以少量的潛在因子來描述,用以預測缺失項。Spark.ml使用交替最小二乘(ALS)算法來學習這些潛在因子。
(2)顯式與隱式反饋
??? 基于矩陣分解的協(xié)同過濾的標準方法中,“用戶-商品”矩陣中的條目是用戶給予商品的顯式偏好,例如,用戶給電影評級。然而在現(xiàn)實世界中使用時,我們常常只能訪問隱式反饋(如意見、點擊、購買、喜歡以及分享等),在spark.ml中我們使用“隱式反饋數(shù)據(jù)集的協(xié)同過濾“來處理這類數(shù)據(jù)。本質(zhì)上來說它不是直接對評分矩陣進行建模,而是將數(shù)據(jù)當作數(shù)值來看待,這些數(shù)值代表用戶行為的觀察值(如點擊次數(shù),用戶觀看一部電影的持續(xù)時間)。這些數(shù)值被用來衡量用戶偏好觀察值的置信水平,而不是顯式地給商品一個評分。然后,模型用來尋找可以用來預測用戶對商品預期偏好的潛在因子。
(3)正則化參數(shù)
??? 我們調(diào)整正則化參數(shù)regParam來解決用戶在更新用戶因子時產(chǎn)生新評分或者商品更新商品因子時收到的新評分帶來的最小二乘問題。這個方法叫做“ALS-WR”它降低regParam對數(shù)據(jù)集規(guī)模的依賴,所以我們可以將從部分子集中學習到的最佳參數(shù)應用到整個數(shù)據(jù)集中時獲得同樣的性能。
參數(shù):
alpha:
類型:雙精度型。
含義:隱式偏好中的alpha參數(shù)(非負)。
checkpointInterval:
類型:整數(shù)型。
含義:設(shè)置檢查點間隔(>=1),或不設(shè)置檢查點(-1)。
implicitPrefs:
類型:布爾型。
含義:特征列名。
itemCol:
類型:字符串型。
含義:商品編號列名。
maxIter:
類型:整數(shù)型。
含義:迭代次數(shù)(>=0)。
nonnegative:
類型:布爾型。
含義:是否需要非負約束。
numItemBlocks:
類型:整數(shù)型。
含義:商品數(shù)目(正數(shù))。
numUserBlocks:
類型:整數(shù)型。
含義:用戶數(shù)目(正數(shù))。
predictionCol:
類型:字符串型。
含義:預測結(jié)果列名。
rank:
類型:整數(shù)型。
含義:分解矩陣的排名(正數(shù))。
ratingCol:
類型:字符串型。
含義:評分列名。
regParam:
類型:雙精度型。
含義:正則化參數(shù)(>=0)。
seed:
類型:長整型。
含義:隨機種子。
userCol:
類型:字符串型。
含義:用戶列名。
(4)實戰(zhàn):
?
val conf = new SparkConf().setAppName("als").setMaster("local[4]")val sc = new SparkContext(conf)//val root = als.getClass.getResource("/")val data = sc.textFile("C://Users//BIGDATA//Desktop//文件//BigData//Spark//7.SparkMLlib_2//resource//resource//als//test.data")val ratings = data.map(_.split(',') match { case Array(user, item, rate) =>Rating(user.toInt, item.toInt, rate.toDouble)})// Build the recommendation model using ALSval rank = 10val numIterations = 10val model = ALS.train(ratings, rank, numIterations, 0.01)// Evaluate the model on rating dataval usersProducts = ratings.map { case Rating(user, product, rate) =>(user, product)}val predictions =model.predict(usersProducts).map { case Rating(user, product, rate) =>((user, product), rate)}val ratesAndPreds = ratings.map { caseRating(user, product, 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)// Save and load modelmodel.save(sc, "C://tmp")val sameModel = MatrixFactorizationModel.load(sc, "C://tmp")
總結(jié)
以上是生活随笔為你收集整理的Spark MLlib回归算法------线性回归、逻辑回归、SVM和ALS的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ChatGPT大热 老黄抓住风口 NVI
- 下一篇: 个人买生育保险怎么买 个人如何买生育保险