萌发预测双色球的想法来源于很久以前,小时候电视上看双色球开奖结果的时候,总会发现当解说员说“下一个中奖号码是···”的时候,中奖号码就跳出来了,所以我认为是可以认为控制的,至于可不可以预测,那就不知道了,反正试试吧。
首先我得收集双色球的中奖号码,通过历史中奖号码来预测下一组号码。
表结构设计:
中奖号码表:
字段名 |
名称 |
类型 |
备注 |
lottery_date |
日期 |
varchar |
主键 |
phase |
期号 |
varchar |
|
red_1 |
1号球 |
int |
|
red_2 |
2号球 |
int |
|
red_3 |
3号球 |
int |
|
red_4 |
4号球 |
int |
|
red_5 |
5号球 |
int |
|
red_6 |
6号球 |
int |
|
blue |
蓝色球 |
int |
|
lucky_blue |
幸运蓝球 |
int |
|
预测表:
字段名 |
名称 |
类型 |
备注 |
id |
ID |
int |
主键 |
phase |
期号 |
varchar |
|
red_1 |
1号球 |
int |
|
red_2 |
2号球 |
int |
|
red_3 |
3号球 |
int |
|
red_4 |
4号球 |
int |
|
red_5 |
5号球 |
int |
|
red_6 |
6号球 |
int |
|
blue |
蓝色球 |
int |
|
lucky_blue |
幸运蓝球 |
int |
|
误差表:
字段名 |
名称 |
类型 |
备注 |
id |
ID |
int |
主键 |
phase |
期号 |
varchar |
|
red_1 |
1号球 |
int |
|
red_2 |
2号球 |
int |
|
red_3 |
3号球 |
int |
|
red_4 |
4号球 |
int |
|
red_5 |
5号球 |
int |
|
red_6 |
6号球 |
int |
|
blue |
蓝色球 |
int |
|
lucky_blue |
幸运蓝球 |
int |
|
收集数据:用Java编写爬虫收集双色球中奖数据,顺便说下爬虫的使用时我在超级课程表面试的时候学会使用的,现在可以用到这个上面来实在是太幸运了。
Java代码爬虫部分
/** * this class will grab the information of each lottery * run this method you will grab the latest information of the lottery * * */ public class Spider { public static String getHtmlByUrl(String url) { String html = null; HttpClient httpClient = new DefaultHttpClient();// 创建httpClient对象 HttpGet httpget = new HttpGet(url);// 以get方式请求该URL try { HttpResponse responce = httpClient.execute(httpget);// 得到responce对象 int resStatu = responce.getStatusLine().getStatusCode();// 返回码 if (resStatu == HttpStatus.SC_OK) {// 200正常 其他就不对 // 获得相应实体 HttpEntity entity = responce.getEntity(); if (entity != null) { html = EntityUtils.toString(entity);// 获得html源代码 } } } catch (Exception e) { System.out.println("访问【" + url + "】出现异常!"); e.printStackTrace(); } finally { httpClient.getConnectionManager().shutdown(); } return html; } /** * @param args */ public static void main(String[] args) { DataStore dataStore = new DataStore(); Lottery lottery = new Lottery(); String html = getHtmlByUrl("http://baidu.lecai.com/lottery/draw/list/ssq.php"); if (html != null && !"".equals(html)) { Document doc = Jsoup.parse(html); Elements trs = doc.select("table").first().select("tbody").select("tr"); Elements tds = trs.get(4).select("td"); String phase = tds.get(0).text(); lottery.setPhase(phase); String date = tds.get(1).text(); date = date.substring(0, 10); lottery.setDate(date); Elements tds2 = tds.get(2).select("em"); int[] a = new int[tds2.size()]; for (int i = 0; i < tds2.size(); i++) { String text = tds2.get(i).text(); a[i] = Integer.parseInt(text); } lottery.setRed_1(a[0]); lottery.setRed_2(a[1]); lottery.setRed_3(a[2]); lottery.setRed_4(a[3]); lottery.setRed_5(a[4]); lottery.setRed_6(a[5]); lottery.setBlue(a[6]); if(a.length == 8){ lottery.setLucky_blue(a[a.length-1]); } dataStore.storeData(lottery); } } }
数据存储部分,使用了Hibernate:
public void storeData(Lottery lottery){ System.out.println(lottery.getDate()); System.out.println(lottery.getPhase()); System.out.println(lottery.getRed_1()); System.out.println(lottery.getRed_2()); System.out.println(lottery.getRed_3()); System.out.println(lottery.getRed_4()); System.out.println(lottery.getRed_5()); System.out.println(lottery.getRed_6()); System.out.println(lottery.getBlue()); System.out.println(lottery.getLucky_blue()); try{ session=HibernateUtils.getSession(); session.beginTransaction(); session.save(lottery); session.getTransaction().commit(); System.out.println("the date stored successfully"); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
缺点是如果网页结构改变的话,代码也需要重新修改。
目前我收集是从2014年10月19日到2015年4月7日的数据。
画出每个号码的走势图:使用Python。
import mysql.connector from matplotlib.pyplot import plot from matplotlib.pyplot import show conn = mysql.connector.connect(user='root', password='root', database='lottery_forecast', use_unicode=True) cursor = conn.cursor() cursor.execute('select * from tb_lottery') values = cursor.fetchall() phase = [] red1 = [] red2 = [] red3 = [] red4 = [] red5 = [] red6 = [] blue = [] for i in values: #print i[2:9] phase.append(i[1]) red1.append(i[2]) red2.append(i[3]) red3.append(i[4]) red4.append(i[5]) red5.append(i[6]) red6.append(i[7]) blue.append(i[8]) plot(red1,lw=1.0) plot(red2,lw=1.0) plot(red3,lw=1.0) plot(red4,lw=1.0) plot(red5,lw=1.0) plot(red6,lw=1.0) plot(blue,lw=2.0) show()
结果如下图:
细线:深蓝色:1号球,绿色:2号球,红色:3号球,淡蓝色:4号球,紫色:5号球,黄色:6号球。
大致看上去还有点规律样的···
预测:Python代码:把每个球的历史中奖号码传入。
import numpy as np import sys def prediction( num): N = len(num) b = num[-N:] b = b[::-1] A = np.zeros((N, N), int) for i in range(N): A[i,]=num num1=[] num1.append(num[N-1]) for j in range(N-1): num1.append(num[j]) num=num1 (x, residuals, rank, s) = np.linalg.lstsq(A,b) # print x, residuals, rank, s return np.dot(b,x)
2015年4月6日的计算结果是2015039期:1, 2, 12 , 22, 28, 29, 9,实际开奖结果:1, 13, 15, 26, 29, 30,12。中两个号码···
误差计算:Java代码
/** * when you did your prediction * and the real numbers come out * you can run this method to figure out the error * so you can make the next prediction according to this error * * */ public class ErrorCalculate { private static Session session; Lottery lottery = new Lottery(); Forecast forecast = new Forecast(); ForecastError error = new ForecastError(); public void errorCalculate(){ //query the latest lottery information List lotteryList = null; try{ session=HibernateUtils.getSession(); session.beginTransaction(); Query query = session.createQuery("from Lottery l where 1=1 order by l.date desc"); query.setFirstResult(0); query.setMaxResults(1); lotteryList = query.list(); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } for (int i = 0; i < lotteryList.size(); i++) { lottery = (Lottery) lotteryList.get(i); //show the lottery's phase to make sure that the two phases are the same System.out.println(lottery.getPhase()); } //query the latest forecasted information List forecastList = null; try{ session=HibernateUtils.getSession(); session.beginTransaction(); Query query = session.createQuery("from Forecast f where 1=1 order by f.phase desc"); query.setFirstResult(0); query.setMaxResults(1); forecastList = query.list(); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } for (int i = 0; i < forecastList.size(); i++) { forecast = (Forecast) forecastList.get(i); //show the forecast phase to make sure that the two phase are the same System.out.println(forecast.getPhase()); } //The error calculate must be made while the latest lottery's phase is the same to the latest forecast's phase if(lottery.getPhase().equals(forecast.getPhase())){ //calculate the error by the formula error = lottery - forecast error.setPhase(lottery.getPhase()); //use the lottery and the forecast phase as the phase of error error.setRed_1(lottery.getRed_1() - forecast.getRed_1()); error.setRed_2(lottery.getRed_2() - forecast.getRed_2()); error.setRed_3(lottery.getRed_3() - forecast.getRed_3()); error.setRed_4(lottery.getRed_4() - forecast.getRed_4()); error.setRed_5(lottery.getRed_5() - forecast.getRed_5()); error.setRed_6(lottery.getRed_6() - forecast.getRed_6()); error.setBlue(lottery.getBlue() - forecast.getBlue()); //error.setLucky_blue(lottery.getLucky_blue() - forecast.getLucky_blue()); System.out.println(error.getRed_1()); System.out.println(error.getRed_2()); System.out.println(error.getRed_3()); System.out.println(error.getRed_4()); System.out.println(error.getRed_5()); System.out.println(error.getRed_6()); System.out.println(error.getBlue()); //System.out.println(error.getLucky_blue()); //save the error into table error try{ session=HibernateUtils.getSession(); session.beginTransaction(); session.save(error); session.getTransaction().commit(); System.out.println("the error stored successfully"); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }else{ System.out.println("the phases of lottery and forecast are not same, please make the forecast or wait the next lottery comes out."); } }
2015年4月8日,再次运行Python预测算法,得到结果:1, 2, 13, 22, 28, 30, 9,怎么跟上次是差不多的啊,下次学着用其他方式试试。