萌发预测双色球的想法来源于很久以前,小时候电视上看双色球开奖结果的时候,总会发现当解说员说“下一个中奖号码是···”的时候,中奖号码就跳出来了,所以我认为是可以认为控制的,至于可不可以预测,那就不知道了,反正试试吧。
首先我得收集双色球的中奖号码,通过历史中奖号码来预测下一组号码。
表结构设计:
中奖号码表:
字段名 |
名称 |
类型 |
备注 |
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,怎么跟上次是差不多的啊,下次学着用其他方式试试。