轉載自:https://vimsky.com/article/3403.html
Spark中ml和mllib的主要區別和聯系如下:
- ml和mllib都是Spark中的機器學習庫,目前常用的機器學習功能2個庫都能滿足需求。
- spark官方推薦使用ml, 因為ml功能更全面更靈活,未來會主要支持ml,mllib很有可能會被廢棄(據說可能是在spark3.0中deprecated)。
- ml主要操作的是DataFrame, 而mllib操作的是RDD,也就是說二者面向的數據集不一樣。相比於mllib在RDD提供的基礎操作,ml在DataFrame上的抽象級別更高,數據和操作耦合度更低。
- DataFrame和RDD什么關系?DataFrame是Dataset的子集,也就是Dataset[Row], 而DataSet是對RDD的封裝,對SQL之類的操作做了很多優化。
- 相比於mllib在RDD提供的基礎操作,ml在DataFrame上的抽象級別更高,數據和操作耦合度更低。
- ml中的操作可以使用pipeline, 跟sklearn一樣,可以把很多操作(算法/特征提取/特征轉換)以管道的形式串起來,然后讓數據在這個管道中流動。大家可以腦補一下Linux管道在做任務組合時有多么方便。
- ml中無論是什么模型,都提供了統一的算法操作接口,比如模型訓練都是
fit
;不像mllib中不同模型會有各種各樣的trainXXX
。 - mllib在spark2.0之后進入
維護狀態
, 這個狀態通常只修復BUG不增加新功能。
以上就是ml和mllib的主要異同點。下面是ml和mllib邏輯回歸的例子,可以對比看一下, 雖然都是模型訓練和預測,但是畫風很不一樣。
mllib中邏輯回歸的例子
sparse_data = [ LabeledPoint(0.0, SparseVector(2, {0: 0.0})), LabeledPoint(1.0, SparseVector(2, {1: 1.0})), LabeledPoint(0.0, SparseVector(2, {0: 1.0})), LabeledPoint(1.0, SparseVector(2, {1: 2.0})) ] lrm = LogisticRegressionWithSGD.train(sc.parallelize(sparse_data), iterations=10) lrm.predict(array([0.0, 1.0])) lrm.predict(array([1.0, 0.0])) lrm.predict(SparseVector(2, {1: 1.0})) lrm.predict(SparseVector(2, {0: 1.0})) import os, tempfile path = tempfile.mkdtemp() lrm.save(sc, path) sameModel = LogisticRegressionModel.load(sc, path) sameModel.predict(array([0.0, 1.0])) sameModel.predict(SparseVector(2, {0: 1.0})) from shutil import rmtree try: rmtree(path) except: pass multi_class_data = [ LabeledPoint(0.0, [0.0, 1.0, 0.0]), LabeledPoint(1.0, [1.0, 0.0, 0.0]), LabeledPoint(2.0, [0.0, 0.0, 1.0]) ] data = sc.parallelize(multi_class_data) mcm = LogisticRegressionWithLBFGS.train(data, iterations=10, numClasses=3) mcm.predict([0.0, 0.5, 0.0]) mcm.predict([0.8, 0.0, 0.0]) mcm.predict([0.0, 0.0, 0.3])
ml中的邏輯回歸的例子
from pyspark.sql import Row from pyspark.ml.linalg import Vectors bdf = sc.parallelize([ Row(label=1.0, weight=2.0, features=Vectors.dense(1.0)), Row(label=0.0, weight=2.0, features=Vectors.sparse(1, [], []))]).toDF() blor = LogisticRegression(maxIter=5, regParam=0.01, weightCol="weight") blorModel = blor.fit(bdf) blorModel.coefficients DenseVector([5.5 ]) blorModel.intercept -2.68 mdf = sc.parallelize([ Row(label=1.0, weight=2.0, features=Vectors.dense(1.0)), Row(label=0.0, weight=2.0, features=Vectors.sparse(1, [], [])), Row(label=2.0, weight=2.0, features=Vectors.dense(3.0))]).toDF() mlor = LogisticRegression(maxIter=5, regParam=0.01, weightCol="weight", family="multinomial") mlorModel = mlor.fit(mdf) print(mlorModel.coefficientMatrix) DenseMatrix([[-2.3 ], [ 0.2 ], [ 2.1 ]]) mlorModel.interceptVector DenseVector([2.0 , 0.8 , -2.8 ]) test0 = sc.parallelize([Row(features=Vectors.dense(-1.0))]).toDF() result = blorModel.transform(test0).head() result.prediction 0.0 result.probability DenseVector([0.99 , 0.00 ]) result.rawPrediction DenseVector([8.22 , -8.22 ]) test1 = sc.parallelize([Row(features=Vectors.sparse(1, [0], [1.0]))]).toDF() blorModel.transform(test1).head().prediction 1.0 blor.setParams("vector") Traceback (most recent call last): TypeError: Method setParams forces keyword arguments. lr_path = temp_path + "/lr" blor.save(lr_path) lr2 = LogisticRegression.load(lr_path) lr2.getMaxIter() 5 model_path = temp_path + "/lr_model" blorModel.save(model_path) model2 = LogisticRegressionModel.load(model_path) blorModel.coefficients[0] == model2.coefficients[0] True blorModel.intercept == model2.intercept True