根据分子运动预测双色球走势(三)-数据清洗和机器学习

一、问题

在爬取到双色球开奖的历史数据和开奖当日20-22点的气候数据之后,我们面临的问题是:

  1. 选择什么样的算法寻找天气数据和双色球开奖结果的关系(只选择蓝球)
  2. 为实现1的算法,需对数据做什么样的处理?
  3. 选择什么技术实现模型训练

首先,将问题简化。若只考虑天气(气温,露点,气压,风向,风速,天气情况)和双色球开奖结果蓝球(1-16)之间的关系。这就是一个多分类问题。模型的计算可选择两种方向:

  • Python 实现的 TensorFlow
  • Scala 实现的Spark MLlib

TensorFlow 是谷歌开源的Python 实现的包,TensorFlow项目领导Rajat Monga说到:“TensorFlow对于AlphaGo来说更多的是底层支撑技术,我们的作用是让AlphaGo运作更顺畅。而如何提升棋艺则是Deepmind团队的工作”。所以TensorFlow 是一个很好的选择。
Spark MLlib是基于Scala 实现的在Hadoop 的一站式大数据平台。所以Spark MLlib也是不错的选择。
由于一、二都是基于Scala 实现,所以我们选择方案二。

二、实现

1. 数据清洗

从双色球开奖的历史数据中,包含的列有
{ 期号,红球序列,蓝球,奖池金额,一等奖金额 }
数据格式:
(String, String, String, String,String)
样例数据:


image.png

对数据进行清洗,并实数化

def clean2ColorBall:Map[String,List[Int]] = {
    val data = Source.fromFile("/Users/hhl/mypro/SparkAppExamples/Hello.txt").getLines().filter(!_.contains("16115期"))
      .map(_.split(";")).map(x=>{
      val qh = x(0).substring(0,7)
      val date = x(1).replace("-","")
      val r1 = x(2).toInt
      val r2 = x(3).toInt
      val r3= x(4).toInt
      val r4 = x(5).toInt
      val r5 = x(6).toInt
      val r6 = x(7).toInt
      val b7 = x(8).toInt
      val saleroom = x(9).replace("元","").replace(",","").trim.toInt
      val jackpot = x(10).replace("元","").replace(",","").trim.toInt
       val res = List(r1,r2,r3,r4,r5,r6,b7,saleroom,jackpot)
      date -> res
    }).toMap
    data
  }
  1. feature 的选择和准备
    选择
    {气温,露点,气压,风向,风速,天气情况,奖池金额}
    作为Feature,按照下列逻辑做数据清洗,并转化为DataFrame,存储为Parquet.
def cleanWx(spark:SparkSession) = {
    val m = clean2ColorBall
    val data = Source.fromFile("/Users/hhl/mypro/SparkAppExamples/wx.txt").getLines()
      .map(_.split(";")).filter(_.size !=1)
      .map(x=>{
       // 气温,露点,湿度,气压,风向,风速,状况 6个feature
        val date = x(0)
      val time = x(1).replace("PM","").trim
      val qw = x(2).toDouble
      val ld = x(3).toDouble
      val sd = x(4).replace("%","").toDouble
        val qy = x(5).toDouble
        val fx = x(6)
        val fs = x(7).toDouble
        val zk = x(8)
        (date,time,qw,ld,sd,qy,fx,fs,zk)
    }).filter(_._6 != -1).toList
    // 归一化,实数化
    val fxList = data.map(_._7).distinct.zipWithIndex.toMap
    val zkList = data.map(_._9).distinct.zipWithIndex.toMap
    val res = data.map(x=>(x._1,x._2,x._3,x._4,x._5,x._6,
      fxList.getOrElse(x._7,-1).toDouble,x._8,zkList.getOrElse(x._9,-1).toDouble)).groupBy(_._1)
      .map(x=>x._2.sortBy(_._2).head).toList
    val res1 = res.sortBy(x=>(x._1,x._2)).map(x=>{
      val lq = m.getOrElse(x._1,List(-1,-1,-1,-1,-1,-1,-1))(6).toDouble
      val jc = m.getOrElse(x._1,List(-1,-1,-1,-1,-1,-1,-1))(7).toDouble
      val values = Array(x._3 + 100 ,x._4 + 100,x._5,x._6,x._7,x._8,x._9,jc) // naive beyes 不支持负值
      val featureVecotr =Vectors.dense(values.init)
      val lable = lq
      (lable,featureVecotr)
    })

    import spark.implicits._
    val df = spark.createDataset(res1).repartition(1).toDF("label","features")
    df.write.mode(SaveMode.Overwrite).parquet("/Users/hhl/mypro/SparkAppExamples/res.txt")
    //df.write.format("csv").mode(SaveMode.Overwrite).save("/Users/hhl/mypro/SparkAppExamples/res.txt")
  }
  1. 模型训练和结果预测
    选择朴素贝叶斯算法训练模型,并验证模型预测的准确度
 val data = spark.read.parquet("/Users/hhl/mypro/SparkAppExamples/res.txt")

    // Split the data into training and test sets (30% held out for testing)
    val Array(trainingData, testData) = data.randomSplit(Array(0.7, 0.3), seed = 1234L)

    // Train a NaiveBayes model.
    val model = new NaiveBayes()
      .fit(trainingData)

    // Select example rows to display.
    val predictions = model.transform(testData)
    predictions.show(100)

    // Select (prediction, true label) and compute test error
    val evaluator = new MulticlassClassificationEvaluator()
      .setLabelCol("label")
      .setPredictionCol("prediction")
      .setMetricName("accuracy")
    val accuracy = evaluator.evaluate(predictions)
    println("Test set accuracy = " + accuracy)
  1. 准确度
    对测试数据的预测结果:


    image.png

准确度:


image.png

只有 8%。。。。

四、总结

根据峰值运动预测双色球走势的流程基本上结束了。最终的结果如一盆冷水,透心凉。想通过技术手段赚大钱的愿望再次破灭了。不过,却有几点重要的经验:

  1. 如何编写一个并发的反反爬虫的Scala 爬虫
  2. 如何进行数据清洗
  3. 如何使用朴素贝叶斯训练模型

由此,又引起新的问题,为什么准确度这么低?如何提高准确度呢?这也许才是这个简单的Demo最大的收获。知道自己不知道,明确了方向,才能更进一步。

你可能感兴趣的:(根据分子运动预测双色球走势(三)-数据清洗和机器学习)