数据1
100|5 1000
75|7 600
80|6 1200
70|6 500
50|8 30
65|7 400
90|5 1300
100|4 1100
110|3 1300
60|9 300
数据2
65 7 400
90 5 1300
100 4 1100
110 3 1300
60 9 300
代码
package cn.tedu.lritem
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
/**
- 通过Spark的MLlib库,建立回归模型(用于预测),底层使用最小二乘法来建模
*/
object Driver {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local").setAppName("lritem")
val sc=new SparkContext(conf)
//--创建SparkSql对象,可以将RDD转变为DataFrame
val sqc=new SQLContext(sc)
val data=sc.textFile("c://data/ml/lritem.txt")
//--第一步:RDD[String:line]->RDD[(Double,Double,Double):(X1,X2,Y)]
val r1=data.map{line=>
val info=line.split("\\|")
val Y=info(0).toDouble
val X1=info(1).split(" ")(0).toDouble
val X2=info(1).split(" ")(1).toDouble
(X1,X2,Y)
}
//--第二步:RDD[(X1,X2,Y)]->DataFrame数据表类型(X1,X2,Y),并指定列名
val df=sqc.createDataFrame(r1).toDF("X1","X2","Y")
//--第三步:为了满足建模需求,DataFrame(X1,X2,Y)->DataFrame(Vector(X1,X2),Y)
//--setInputCols:指定哪些列是自变量列
//--setOutputCol:为所有的自变量分配一个别名
val ass=new VectorAssembler().setInputCols(Array("X1","X2"))
.setOutputCol("features")
val dfVectors=ass.transform(df)
//--第四步:建模
//--setFeaturesCol:指定自变量列
//--setLabelCol:指定因变量列
//--setFitIntercept(true),表示计算截距项系数
//--fit:代入数据集建模
val model=new LinearRegression().setFeaturesCol("features")
.setLabelCol("Y")
.setFitIntercept(true)
.fit(dfVectors)
//--获取模型方程中 自变量的系数
val coef=model.coefficients
//--获取截距项系数
val intercept=model.intercept
//--获取模型的多元R方值,用于评估模型对样本数据拟合的优良性
//--R方值最大值=1,越靠近1,表示拟合越好
//--在生成环境,在0.55以上都可以接受
//--如果R方值很低,比如0.2,则表明模型选取不合理,需要更换模型
val R2=model.summary.r2
//--第五步:通过模型预测数据
//--transform:模型的预测方法,下面的代码表示将原来的样本集回代到模型做预测
val prediction=model.transform(dfVectors)
//--第六步:预测testitem.txt中的Y值
//--RDD[String:line]->RDD[(X1,X2,0)]->DataFrame("X1","X2","Y")->
//--DataFrame(Vector("X1","X2"),"Y")->model预测
val testData=sc.textFile("c://data/ml/testitem.txt")
val testRDD=testData.map { line =>
val info=line.split(" ")
val X1=info(0).toDouble
val X2=info(1).toDouble
(X1,X2,0)
}
val testDF=sqc.createDataFrame(testRDD).toDF("X1","X2","Y")
val testDFVectors=ass.transform(testDF)
val testPrediction=model.transform(testDFVectors)
testPrediction.show
}
}
向量标签
数据
2 3 7 1
1 3 5 2
3 4 7 1
8 9 2 1
代码
package cn.tedu.vector
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
/**
- 向量标签类型
*/
object Driver02 {
def main(args: Array[String]): Unit = {
val v1=Vectors.dense(1,3,4)
//--创建向量标签类型 ①参:标签值(因变量Y) ②参:向量(所有自变量所组成的向量)
val lb1=LabeledPoint(3.4,v1)
println(lb1.label)//获取向量标签的标签值
println(lb1.features)//获取向量标签的向量
//--处理vector.txt RDD[String:line]->RDD[LabeledPoint]
val conf=new SparkConf().setMaster("local").setAppName("label")
val sc=new SparkContext(conf)
val data=sc.textFile("c://data/ml/vector.txt")
val r1=data.map { line =>
val info=line.split(" ")
//--获取自变量数组
val xArr=info.dropRight(1).map { num => num.toDouble }
//--获取因变量
val y=info.last.toDouble
LabeledPoint(y,Vectors.dense(xArr))
}
r1.foreach{println}
}
}
向量类型创建
数据
2 3 7 1
1 3 5 2
3 4 7 1
8 9 2 1
代码
package cn.tedu.vector
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
/**
- 学习Spark MLlib的向量类型
*/
object Driver01 {
def main(args: Array[String]): Unit = {
//--创建向量,要求传入Double类型数据
val v1=Vectors.dense(2.1, 3.5,4.4)
//--也可以传入整型类型,底层会隐式转换为Double
val v2=Vectors.dense(1,3,4,7)
//--重点掌握,通过传入Array[Double] 来创建向量
val v3=Vectors.dense(Array[Double](2.3,4.7,5.5))
//--处理vector.txt文件 RDD[String:line]->RDD[Vector]
val conf=new SparkConf().setMaster("local").setAppName("vector")
val sc=new SparkContext(conf)
val data=sc.textFile("c://data/ml/vector.txt")
val r1=data.map { line =>
val arr=line.split(" ").map {num =>num.toDouble }
Vectors.dense(arr)
}
r1.foreach{println}
}
}
向量指标
package cn.tedu.vector
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.stat.Statistics
/**
- 学习统计工具类,可以计算一组数据的各项基本指标,比如max.min.avg等
*/
object Driver03 {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster(“local”).setAppName(“statistic”)
val sc=new SparkContext(conf)
val r1=sc.makeRDD(List(1,2,3,4,5))
//--RDD[Int]->RDD[Vector]->然后使用工具类统计
val r2=r1.map { num => Vectors.dense(num) }
//--代入RDD,并将结果返回
val result=Statistics.colStats(r2)
println(result.max)
println(result.min)
println(result.mean)//均值
println(result.variance)//方差
println(result.count)//元素个数
println(result.numNonzeros)//返回数据集中不为0的个数
println(result.normL1)//返回曼哈顿距离
println(result.normL2)//返回欧式距离
}
}
向量之距离
package cn.tedu.vector
object Driver04 {
def main(args: Array[String]): Unit = {
val a1=Array(1,5,2,3)
val a2=Array(10,2,1,6)
//--计算两点之间欧式距离
val a1a2=a1 zip a2
//--返回两点之间的欧式距离
val r1=Math.sqrt(a1a2.map{x=>(x._1-x._2)*(x._1-x._2)}.sum)
//--返回两点之间的曼哈顿距离
val r2=a1a2.map{x=>Math.abs(x._1-x._2)}.sum
//--返回两点的切比雪夫距离
val r3=a1a2.map{x=>Math.abs(x._1-x._2)}.max
}
}
向量余弦之夹角
package cn.tedu.vectorcos
object Driver {
def main(args: Array[String]): Unit = {
val a1=Array(1,2,5)
val a2=Array(3,1,6)
val a3=Array(20,1,2)
//--计算a1和a2 a1和a3 向量之间的夹角余弦
//--掌握拉链方法的使用,将两个对象之间,对应位置的数据拉在一起。
val a1a2=a1 zip a2
val a1a2Fenzi=a1a2.map{x=>x._1*x._2}.sum
val a1Fenmu=Math.sqrt(a1.map { x => x*x }.sum)
val a2Fenmu=Math.sqrt(a2.map { x => x*x }.sum)
val a1a2Cos=a1a2Fenzi/(a1Fenmu*a2Fenmu)
val a1a3=a1 zip a3
val a1a3Fenzi=a1a3.map{x=>x._1*x._2}.sum
val a3Fenmu=Math.sqrt(a3.map { x => x*x }.sum)
val a1a3Cos=a1a3Fenzi/(a1Fenmu*a3Fenmu)
println(a1a2Cos)
println(a1a3Cos)
}
}