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

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

作者: 阿海与蜗牛 | 来源:发表于2017-12-01 15:54 被阅读0次

    一、问题

    在爬取到双色球开奖的历史数据和开奖当日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最大的收获。知道自己不知道,明确了方向,才能更进一步。

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/poqwbxtx.html