您的位置:首页 > 其它

科学预测世界杯-采用机器学习方法

2014-06-27 23:04 239 查看
最近不管是在哪,世界杯永远是大家闲聊的话题。而随着互联网的发展,购买足彩越发便利和火爆了,体彩不像福彩,我们可以根据各个球队的情况做一些猜测。但作为一名看世界杯只记的住场边广告的伪球迷,也想凑热闹买一把,怎么才能保证在前面几次比赛的基础上,比较科学靠谱的预测比赛结果呢?做为一名略懂机器学习的伪球迷,当然要发挥学科的优势来凑凑热闹预测一下。

机器学习算法很多,我们分别实现了用SVM,神经网络,和KNN来预测。要用这些分类器首先要有训练和测试的数据,比赛进行到今天,我们已经积累了很多比赛的数据了,所以应用学习分类器是合理的。那我们应该怎么得到这些数据呢?

1.量化世界杯比赛结果和影响因素

比赛结果比较好量化,比如美国-德国,3代表美国赢,2代表打平,1代表美国输。

影响因素怎么选呢?一名伪球迷对各个队的历史,球员,教练是很难了解周全的,另外天气,球员心理状态,身体状态等等因素也是很难控制的,所以我们无法量化这些因素,而且这些信息也是很难获取的。于是一个比较合理而且简单的数据-赔率可以选用为量化了这些影响因素的综合数据。这个合不合理呢?我们知道一般赔率高的肯定胜率低,赔率低的胜率高,而赔率是怎么计算的呢?可以看这篇文章http://www.guokr.com/article/20199/了解。所以赔率和比赛胜负是相关的,通过赔率,我们可以做出比较好的判断。

2.准备训练测试数据

赔率和输赢这些数据很容易获取,比如在http://zx.500.com/jczq/kaijiang.php?playid=2&d=2014-06-26这里就可以得到平均欧赔和输赢。于是根据第一步整理好数据,训练的标签就是输赢量化后的结果,特征就是平均欧赔。而一般买彩票前平均欧赔都会提前公布的,这就是我们测试数据的特征,根据这些特征得到的预测标签就是比赛的结果。比如我们根据前几天的情况预测今天的结果。

31.295.0511.13
31.434.248.08
11.833.334.75
32.183.113.55
32.583.132.79
12.692.972.88
11.424.178.36
31.823.244.93
31.345.058.85
31.285.3511.12
32.373.123.13
12.423.252.92
24.193.321.94
32.013.433.71
21.863.474.32
21.325.199.26
31.354.858.91
15.393.801.64
11.564.275.54
112.926.391.21
22.273.283.19
33.583.552.02
32.043.383.65
15.523.951.60
14.573.491.81
11.524.046.59
34.203.511.87
11.305.459.20
31.138.3619.99
24.453.771.75
12.423.213.00
32.123.293.55
12.623.312.66
21.128.5319.89
32.553.382.69
17.514.911.39
33.783.481.97
13.463.572.05
24.323.801.78
12.533.312.76
25.213.961.63
17.224.371.44
32.123.453.45
18.493.991.45


上面是6-12到6-25的数据。根据这些过去的数据来训练模型

9.600000000000002.860000000000001.64000000000000

2.150000000000003.650000000000003.11000000000000

4.700000000000003.580000000000001.75000000000000

3.590000000000003.420000000000002.04000000000000

1.600000000000003.890000000000005.52000000000000

2.060000000000003.300000000000003.66000000000000

2.080000000000003.300000000000003.57000000000000

2.550000000000003.050000000000002.92000000000000



上面是今天(6.27,6.28,6.29)的赔率。根据这些现在的数据来预测这三天的情况。

3.测试分类器

首先我们采用的SVM分类器,利用LIBSVM工具箱可以很容易实现,当然为了使模型更加合理,在训练过程加了交叉验证,即在过去的数据里去拿一部分来训练一个模型,另一些数据来测试这个模型,然后取出使这个模型正确率最高的一些参数。在交叉验证过程大部分正确率都在50%左右,这说明赔率确实提供了一些信息,应该一般随机猜正确的概率是1/3(33.3%).

下面是这个过程的代码,要运行保证计算机上装好libsvm了。

%数据提取
load('worldcuptry.mat','worldcuptry');
load('test.mat','test');
train_histograms=worldcuptry(:,(2:4));
test_histograms=test(:,(2:4));
train_label=worldcuptry(:,1);
test_label=test(:,1);
%选定训练集和测试集
train_data=double(train_histograms);
test_data=double(test_histograms);

%选择最佳的SVM参数c&g

%首先进行粗略选择:c&g的变化范围是2^(-10),2^(-9),...,2^(10)
[bestacc,bestc,bestg]=SVMcgForClass(train_label,train_histograms,-10,10,-10,10);

%打印粗略选择结果
disp('打印粗略选择结果');
str=sprintf('BestCrossValidationAccuracy=%g%%Bestc=%gBestg=%g',bestacc,bestc,bestg);
disp(str);

%根据粗略选择的结果图再进行精细选择:c的变化范围是2^(-2),2^(-1.5),...,2^(4),g的变化范围是2^(-4),2^(-3.5),...,2^(4),
[bestacc,bestc,bestg]=SVMcgForClass(train_label,train_histograms,-2,4,-4,4,3,0.5,0.5,0.9);

%打印精细选择结果
disp('打印精细选择结果');
str=sprintf('BestCrossValidationAccuracy=%g%%Bestc=%gBestg=%g',bestacc,bestc,bestg);
disp(str);

%利用最佳的参数进行SVM网络训练
option=['-c',num2str(bestc),'-g',num2str(bestg)];

%SVM网络训练
model=svmtrain(train_label,train_data,option);

%SVM网络预测
[predict_label,accuracy,prob_estimates1]=svmpredict(test_label,test_data,model,'-b0');


最后得到的结果是

1

3

2

3

1

3

3

1

。说明我们成功预测了6.27的前三场比赛结果。






G组
美国0
德国1
G组
葡萄牙2

加纳1

H组
阿尔及利亚1
俄罗斯1

H组
韩国0
比利时1


其次我们采用另外一种策略KNN来看看结果

load('worldcuptry.mat','worldcuptry');
load('test.mat','test');
train_histograms=worldcuptry(:,(2:4));
test_histograms=test(:,(2:4));
train_label=worldcuptry(:,1);
test_label=test(:,1);
%选定训练集和测试集
train_data=double(train_histograms);
test_data=double(test_histograms);
mdl=ClassificationKNN.fit(train_data,train_label,'NumNeighbors',1);%训练生成一个模型-1NN
predict_label=predict(mdl,test_data);


结果为:

1

2

1

3

1

3

3

3

和SVM相差不大。

最后我们用神经网络来看看结果

clc;
clearall;
closeall;
load('worldcuptry.mat','worldcuptry');
load('test.mat','test');
train_histograms=worldcuptry(:,(2:4));
test_histograms=test(:,(2:4));
train_label=worldcuptry(:,1);
test_label=test(:,1);
%选定训练集和测试集
train_data=double(train_histograms);
test_data=double(test_histograms);
ann_train_label=zeros(3,length(train_label));
fori=1:length(train_label)
iftrain_label(i)==3
ann_train_label(3,i)=1;
elseiftrain_label(i)==2
ann_train_label(2,i)=1;
elseiftrain_label(i)==1
ann_train_label(1,i)=1;
end
end
ann_test_label=zeros(3,length(test_label));
fori=1:length(test_label)
iftest_label(i)==3
ann_test_label(3,i)=1;
elseiftest_label(i)==2
ann_test_label(2,i)=1;
elseiftest_label(i)==1
ann_test_label(1,i)=1;
end
end
%======BP神经网络创建,训练和测试==========================%
net=network_train(train_data',ann_train_label);
predict_label=network_test(test_data',net);

functionnet=network_train(charvec1,label)
%从1到tn间随机排序(在[0,1]之间产生b个随机数),将数据顺序打乱
[~,b]=size(charvec1);
k=rand(1,b);
[~,n]=sort(k);
%随机提取b个样本为训练样本,个样本为预测样本
input=charvec1;
output=label;
input_train=input(:,n(1:b));
output_train=output(:,n(1:b));
%BP网络训练
%%初始化网络结构
net=newff(input_train,output_train,3);
net.trainParam.epochs=60;
net.trainParam.lr=0.1;
net.trainParam.goal=0.001;
%net.trainFcn='trainrp';
%网络训练
net=train(net,input_train,output_train);
save('network.mat','net')
end

functionout=network_test(charvec,net)
input_test=charvec;
[a,b]=size(charvec);
%BP网络预测
an=sim(net,input_test);
fori=1:b
an1(i)=find(an(:,i)==max(an(:,i)));
end
end


结果为:13213333

预测6.27全对!!!!

今天过了,让我们预测下6.28,6.29的情况

SVM的结果:

1

3

3

1

KNN的结果:

1

3

3

3

ANN的结果:

3

3

3

3

明天见分晓。

更新:

6.30及之后情况

KNN

2

3

1

3

1

2

1

SVM:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐