机器学习 - Mllib大法好

基本模型

标签的注入

注入单个标签

 //注入标签
  def labelDemo1() = {
    val vd = Vectors.dense(2, 0, 6)
    val pos = LabeledPoint(1, vd)
    println(pos.features) //内容数据---[2.0,0.0.6.0]
    println(pos.label) //既定标签--1.0
  }

注入批量标签

2.3 3.2 1
1.6 2.3 2
5.1 2.1 1
6.2 7.2 1
3.2 1.2 2
9.2 2.1 1

 def labelDemo2(sc: SparkContext) = {
    val data = sc.textFile("D:\\ml\\labeled.txt", 2)
    val datap = data.map { x =>
      val parts = x.split(" ")
      LabeledPoint(parts(2).toDouble, Vectors.dense(parts(0).toDouble, parts(1).toDouble))
    }
    datap.foreach { println } //查看标签数据-->(1.0,[2.3,3.2])
    datap.foreach { x => println(x.features) } //查看特征数据(自变量)-->[2.3,3.2]
    datap.foreach { x => println(x.label) } //查看标签信息(因变量)-->1.0
  }

向量索引的使用

1 2:1 3:2 6:3 7:4
2 1:1 2:2 3:3
1 1:1 2:3 3:3
1 1:3 2:1 3:3

 /**
   * SVM支持向量机-->监督学习模型
   * 1 2:1 3:2 6:3 7:4
   * 2 1:1 2:2 3:3
   */
  def labelDemo03(sc: SparkContext) = {
    //MLUtils.loadLibSVMFile数据集标记的index是从1开始
    //loadLibSVMFile方法将数据分解成一个稀疏向量进行下一步的操作
    val data = MLUtils.loadLibSVMFile(sc, "D:\\ml\\data.txt")
    //(1.0,(7,[1,2,5,6],[1.0,2.0,3.0,4.0]))->(標簽,(整体总向量,[向量下標],[對應的内容]))
    //向量索引順序:可以跳號,但必須從小到大排列
    data.foreach { println }
  }

矩阵的使用

本地矩阵Matrices的使用

def localDemo01() = {
    //Matrices.dense方法是矩阵重组的调用方法
    //第一个参数是新矩阵行数,第二个参数是新矩阵的列数,第三个参数为传入的数据值。
    val mx = Matrices.dense(2, 3, Array(1, 2, 3, 4, 5, 6))
    println(mx)
  }

行矩阵rowMatrix的使用

1 2 3
4 5 6
7 8 9
10 11 12
1 3 4

  def matrixDemo01(sc: SparkContext) = {
    val data = sc.textFile("D:\\ml\\rowMatrix.txt", 2)
    //转成Vector格式的数据
    val datap = data.map { _.split(" ").map(_.toDouble) }
    		.map { arr => Vectors.dense(arr) }
    datap.foreach { println }
    val rm = new RowMatrix(datap)
    println(rm.numCols())
    println(rm.numRows())
  }

带行索引的行矩阵

def matrixDemo02(sc: SparkContext) = {
    val data = sc.textFile("D:\\ml\\rowMatrix.txt", 3)
    var index = 0
    //按分区布置索引,分多少个分区就统计多少次,如2个分区就有2次index的计算,
    val datap = data.map { _.split(" ").map { _.toDouble } }
    .map { arr => Vectors.dense(arr) }.map { vt =>
      index += 1
      new IndexedRow(index, vt)
    }
    val rm = new IndexedRowMatrix(datap)
    rm.rows.foreach { println } //IndexedRow(3,[1.0,2.0,3.0])
    rm.rows.filter { x => x.index == 1 }.foreach { println }
  }

基本统计的运用

基本统计

1
2
3
4
5

扫描二维码关注公众号,回复: 4727922 查看本文章
def statisticsDemo01(sc: SparkContext) = {
    val data = sc.textFile("D:\\ml\\testSummary.txt", 2)
      .map { _.split("").map { _.toDouble } }.map { arr => Vectors.dense(arr) }
    val summ = Statistics.colStats(data)
    //向量-->
    //一元向量集合--List([1.0],[2.0],[3.0],[4.0],[5.0])
    data.foreach { println }
    println(summ.mean) //均值--[3.0]
    println(summ.variance) //方差--[2.5]
    println(summ.max) //最大值--[5.0]
    println(summ.min) //最小值--[1.0]
    println(summ.count) //计数--5
  }

皮尔逊相关系数的使用

皮尔逊相关系数的变化范围为-1到1
系数的值为1意味着X和Y可以很好的由直线方程来描述,所有的数据点都很好的落在一条直线上

testCorrX.txt

1 2 3 4 5 17
2 4 6 8 10

testCorrY.txt

2 4 7 9 10
11 33 66 88 99 22

 def statisticsPearson(sc: SparkContext) = {
    //注意切分用flatMap,且不能分区
    val xdata = sc.textFile("D:\\ml\\testCorrX.txt")
     .flatMap { _.split(" ").map { _.toDouble } }
    val ydata = sc.textFile("D:\\ml\\testCorrY.txt")
     .flatMap { _.split(" ").map { _.toDouble } }
    //计算两组的相关系数->先zip两个数据
    //可以将换行符识别成空格切分,数据量必须一样,排列方式可以不一样
    val correlation = Statistics.corr(xdata, ydata)
    println(correlation)//--0.11877692214047662
  }

最小二乘法

y=x1a1+x2a2+…+xnan+b

最小二乘法(又称最小平方法)是一种数学优化技术。

它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。最小二乘法还可用于曲线拟合。

其他一些优化问题也可通过最小化能量或最大化熵用最小二乘法来表达。

预测商品需求量

y=β1X1+β2X2+β0

某种商品的需求量(y,吨)、价格(x1,元/千克)和消费者收入(x2,元)观测值如下所示。

100|5 1000
75|7 600
80|6 1200
70|6 500

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.ml.feature.VectorAssembler
import org.apache.spark.ml.regression.LinearRegression

object range {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setMaster("local").setAppName("distance")
    val sc = new SparkContext(conf)
    val sqc = new SQLContext(sc)
    val data = sc.textFile("D:\\ml\\lritem.txt")
    val datap = data.map { x =>
      val parts = x.split("\\|")
      val features = parts(1).split(" ")
      (parts(0).toDouble, features(0).toDouble, features(1).toDouble)
    }
    //转成DF
    val df = sqc.createDataFrame(datap)
    //定义各列字段
    val dfData = df.toDF("Y", "X1", "X2")
    //定义features字段名,声明除了Y之外都是特征列
    val feaColum = Array("X1", "X2")
    //向量格式转换器,指定特征向量是哪几列,以及特征向量对应的别称,一般用"features"
    val assembler = 
      new VectorAssembler().setInputCols(feaColum).setOutputCol("features")
    //将DataFrame转成VectorAssemmbler格式
    val vecDF = assembler.transform(dfData)

    //建模,设定自变量和因变量
    //--setFitIntercept(true) 表示是否需要计算截距项
    //--setLabelCol("Y") 指定因变量起名
    //--setFeaturesCol()为特征列起名
    //--fit(数据)是训练生成模型
    val model = new LinearRegression().setFeaturesCol("features")
      .setLabelCol("Y").setFitIntercept(true).fit(vecDF)
    //获取方程系数
    //[-6.497089660950155,0.01631790530613281]
    println("方程系数:" + model.coefficients)
    //获取截距项系数
    //106.36879716406025
    println("截距项系数:" + model.intercept)
    //获取模型的R方值(拟合优度判定系数)
    //0.9107147177285084
    //越接近1,拟合越好,0.55以上的都可以接受
    println("R方值系数:" + model.summary.r2)

    //预测数据,测试的数据格式必须是VectorAssemmbler
    val predict = model.transform(vecDF)
    val res = predict.select("prediction")
    val testdata = sc.textFile("D:\\ml\\testItem.txt", 3)
    val testdatap = testdata.map { line =>
      val info = line.split(" ")
      (info(0).toDouble, info(1).toDouble)
    }
    val testDF = sqc.createDataFrame(testdatap).toDF("X1", "X2")
    val testV = assembler.transform(testDF)
    val testres = model.transform(testV)
    testres.show()

    //自定义测试数据
    val datatest = assembler.transform(sqc.createDataFrame(sc.makeRDD(List((8.0, 35))))
    							.toDF("X1", "X2"))
    //--将测试集做预测
    val testPredict = model.transform(datatest)

    testPredict.show()

  }

}

预测谋杀率

615, 3624, 2.1, 69.05, 0, 41.3, 20, 50708
65, 6315, 1.5, 69.31, 0, 66.7, 152, 566432
212, 4530, 1.8, 70.55, 0, 58.1, 15, 113417
110, 3378, 1.9, 70.66, 0, 39.9, 65, 51945
1198, 5114, 1.1, 71.71,0, 62.6, 20, 156361
541, 4884, 0.7, 72.06, 0, 63.9, 166, 103766

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.ml.feature.VectorAssembler
import org.apache.spark.ml.regression.LinearRegression

object kill {
  def main(args: Array[String]): Unit = {
    val conf=new SparkConf().setMaster("local").setAppName("kill")
    val sc= new SparkContext(conf)
    val sqc= new SQLContext(sc)
    val data = sc.textFile("D:\\killsample.txt")
    
    val datap=data.map { line => 
    val infos=line.split(",")
    (infos(0).toDouble,infos(1).toDouble,infos(2).toDouble,infos(3).toDouble,
        infos(4).toDouble,infos(5).toDouble,infos(6).toDouble,infos(7).toDouble)   
    }
    val df=sqc.createDataFrame(datap).toDF(
        "Population", "Income", "Illiteracy", "LifeExp", "Murder", "HSGrad", "Frost", "Area"
    )
    val colArray=Array(
        "Population", "Income", "Illiteracy", "LifeExp", "HSGrad", "Frost", "Area")
    val ass=new VectorAssembler().setInputCols(colArray).setOutputCol("features")
    val vecDF=ass.transform(df)
    
    //建立模型
    val lr1=new LinearRegression()
    val lr2=lr1.setFitIntercept(true).setLabelCol("Murder").setFeaturesCol("features")
    //正则化,防止过拟合
    val lr3=lr2.setMaxIter(10).setRegParam(0.3).setElasticNetParam(0.8)
    val lr=lr3
    val model=lr.fit(vecDF)
    println("方程系数:"+model.coefficients)
    println("截距系数:"+model.intercept)
    println("R方差系数:"+model.summary.r2)
    //println(s"Coefficients: ${model.coefficients} Intercept: ${model.intercept}")
    
    val dataT = sc.textFile("D:\\ml\\lrmurder-test.txt")
    val dataTp=dataT.map { line => 
    val infos=line.split(",")
    (infos(0).toDouble,infos(1).toDouble,infos(2).toDouble,infos(3).toDouble,
        infos(4).toDouble,infos(5).toDouble,infos(6).toDouble,infos(7).toDouble)   
    }
    val testDF=sqc.createDataFrame(dataTp).toDF("Population", "Income", "Illiteracy", "LifeExp","Murder", "HSGrad", "Frost", "Area")
    val testV=ass.transform(testDF)
    val testres=model.transform(testV)
   testres.createTempView("res")
   sqc.sql("select r1.*,r2.Murder act,abs(r1.Murder-r1.prediction) intercept from res r1,res r2 where r1.features=r2.features order by r1.features").show()
   
     
  }
}

梯度下降法

在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度

他的意义从几何意义上讲,就是函数变化最快的地方。具体来说,对于函数f(x,y),在点(x0,y0),沿着梯度向量的方向就是(∂f/∂x0, ∂f/∂y0)T的方向是f(x,y)增加最快的地方。或者说,沿着梯度向量的方向,更加容易找到函数的最大值。反过来说,沿着梯度向量相反的方向,也就是 -(∂f/∂x0, ∂f/∂y0)T的方向,梯度减少最快,也就是更加容易找到函数的最小值。

猜你喜欢

转载自blog.csdn.net/weixin_42712876/article/details/85468498