归纳学习
按照学习的一种分类方法,可以将学习分为演绎学习和归纳学习。
演绎学习是指从某些基础的抽象的概念开始推到出的具体的知识。例如在数学中从给定的公理和定理出发,推到出能说明具体实例的知识。
与之对应的归纳学习是从多个具体的事实出发,发现能很好地说明这些事实的知识的学习。例如图像识别和语音听取等任务中,将学习数据集作为具体的示例数据而给出,获得图像识别和语音识别的知识。从具体的示例出发,提取出能够说明这些示例的知识的学习,归类为归纳学习。
归纳学习----股票价格预测
设谋公司的公司名是X公司。X公司的股票在某个股票市场上市,其股票随着时间而不断变化。这里,考虑X公司的股票在今后会上升还是下跌的预测问题。
股票变动可以看成企业是否得人心的投票结果,当然,该企业的企业股价是由世界经济状况、社会形式等非常复杂的因素决定的。股票市场全体的动向、相关企业的股价变动等,都可能会对特定的企业的股价产生影响。
这里将问题简单化,设X公司的股价是由和X公司相关的A公司~J公司的股价变化决定的。也就是说,假设前一天A公司~J公司的某种变化模式导致了X公司当日股价上升,其他模式导致股价下降。现在可以考虑收集过去具体的股份变动事例,通过归纳学习来提取相应的模式,获取对X公司的股价进行预测的知识。
需要的数据:过去一些年A~J公司的股价是上升还是下降的数据,X公司在过去一些年的股价是上升还是下降。
通过过去一系列像这些关系的数据进行归纳学习。
在本例中,某个数据和所对应的结果的值形成了样本对。这意味这,本例的学习是数据监督学习的范畴。
知识的表示方法
知识的表示方法就是通过某种规则的表示来表达股票动向的知识。机器学习中对于规则的表示方法有很多种,例如模式匹配方法、基于逻辑表达的方法,以及基于if-then形式的生成规则的方法等。尤其是作为深度学习基础的神经网络,也可以获得规则。这里采用简单的基于模式匹配的方法进行处理。
各公司股价的上升和下降的变动便可以使用1或0来表示。这里,我们把1代表股价上升,0代表股价下降。
本例所期待的知识表示是,给定A~J公司前一天的股价动向,返回X公司股价动向预测。此时。此时,A~J公司的股价动向模式用某种方法表示出来,与这个模式相一致时预测X公司的股价会上升,与这个模式不一致时预测X 公司的股价会下降。
对于模式的表示方法,采用A~J公司前一天股价的动向的10个符号来表示。为表示上升和下降采用1/0符号,两中符号都匹配时引入“2”作为通配符。一般而言,通配符是指和所有的符号都一致。
在调查模式与股价动向是否匹配时,对于符号1和0分别匹配,模式中的符号2与股价动向的1/0的两方都匹配。在图中,该模式的中间部分,第5个和第6个是符号2.
像这样引入符号2可以更灵活地对知识进行表示。
有了以上的准备工作,在本例中基于机器学习对X公司的股价动向进行预测时,只要求得关于预测知识的模式就可以了。因此,下面讨论求取模式的方法。
求取模式的方法
这里简单地采用基于生成和测试(generate and text)的方法求得模式。生成和测试的方法时指采用某种方法生成关于问题的候补解,将之与问题的条件对照起来选取良好的解。将这个方法和本例结合起来考虑,就是说通过某种方法生成关于解的候补模式,将之与学习数据集对照,执行选取更好的解的操作。
学习数据集含有100个学习数据,作为候选解的模式在其中有几个是正确的,基于正确率可以进行评价,如果某个模式在这100个例子的所有学习数据都能正确处理,评价分数是100分。反之,如果全部不正确,就是0分。 如果一半例子正确,评价分数就是50分。
此时,要注意学习数据集中存在正样本和负样本。正样本的数据都是正确解,负样本的数据都是不正确解。在本例中,正样本是X公司的股价预测为上升的数据,意味着在学习数据集内教师数据是1的学习数据。负样本是教师数据为0的学习数据,也就是将X公司的股价预测为下降的数据。
最后,考虑生成候选解模式的方法。用过随机方法生成作为解的候选模式。(通过随机产生0,1,2进行排列)
总结程序过程
1.读入学习数据集(学习数据和教师数据的组合)
2.以适当次数重复:
····2.1基于随机数生成解的候选模式
····2.2对于所有的学习数据重复以下操作:
········2.2.1利用解的候选模式,对于一个学习数据计算关于X公司的股价预测值(上升还是下降)
········2.2.2将预测值和对应的教师数据相比较,如果一致,得分加1
····2.3如果解的候选模式的评价值(总得分)是过去所有模式中的最高得分,就更新最高得分。
CODE
/********************************************************************/
/* learnstock.c */
/* 单纯归纳学习的例题程序 */
/* 模式学习器 */
/* 读取100个学习数据 */
/* 给出合适的10位二进制答案 */
/********************************************************************/
/*与visual studio 的呼唤性保证*/
#define _CRTSECURE_NO_WARNINGS
/*Include 头文件*/
#include <stdio.h>
#include <stdlib.h>
/* 符号常量定义 */
#define OK 1
#define NG 0
#define SETSIZE 100 /* 学习数据集的大小 */
#define CNO 10 /* 学习数据的位数(10) */
#define GENMAX 10000 /* 生成候选解的次数 */
#define SEED 32767 /* 随机数的种子 */
/* 函数原型声明 */
void readdata(int data[SETSIZE][CNO], int teacher[SETSIZE]) ; /* 读入学习数据集 */
int rand012() ; /* 返回0、1、2的随机函数 */
int calcscore(int data[SETSIZE][CNO], int teacher[SETSIZE], int answer[CNO]); /* 计算候选解模式的得分(0 ~ SETSIZE )*/
int main(){
int i,j;
int score = 0; /* 得分(0 ~ SETSIZE)*/
int answer[CNO]; /* 候选解*/
int data[SETSIZE][CNO]; /*学习数据集*/
int teacher[SETSIZE]; /*教师数据集*/
int bestscore = 0; /*得分的最优值*/
int bsetanswer[CNO]; /*搜索过程中的最优解*/
srand(SEED); /*随机数的初始化*/
readdata(data, teacher) ; /*读入学习数据集*/
for(i = 0; i < GENMAX; i++){
/* 生成候选解 */
for(j = 0; j < CNO; j++){
answer[j] = rand012();
}
/* 检测 */
score = calcscore(data, teacher, answer);
/*最优得分的更新*/
if(score > bestscore){
for (j = 0; j < CNO; j++)
bsetanswer[j] = answer[j];
bestscore = score;
for(j = 0; j < CNO; j++)
printf("%1d", bsetanswer[j]);
printf(":score=%d\n", bestscore);
}
}
/*输出最优解*/
printf("\nz最优解\n");
for(j = 0; j < CNO; j++)
printf(":score=%d\n", bestscore);
return 0;
}
/*************************************************************/
/* calcscore()函数 */
/*候选模式的得分(0~SETSIZE)的计算 */
/*************************************************************/
int calcscore(int data[SETSIZE][CNO], int teacher[SETSIZE], int answer[CNO]){
int score = 0; /*得分(0~SETSIZE)*/
int point ; /*相一致的位数(0~CNO)*/
int i,j;
for(i = 0; i<SETSIZE; i++){
/* 计算一致程度 */
point = 0;
for(j =0; j < SETSIZE; j++){
if(answer[j] == 2) ++point; /* 通配符 */
else if(answer[j] == data[i][j]) ++point; /* 相一致 */
}
if ( (point == CNO) && (teacher[i] == 1) ){
++score;
}
else if( (point != CNO) && (teacher[i] == 0) ){
++score;
}
}
return score;
}
/**********************************************************/
/* readdata()函数 */
/* 读入学习数据集 */
/**********************************************************/
void readdata(int data[SETSIZE][CNO], int teacher[SETSIZE]){
int i, j ;
for(i = 0; i<SETSIZE; i++){
for(j = 0; j<CNO; j++){
scanf("%d", &data[i][j]);
}
scanf("%d", &teacher[i]);
}
}
/*********************************************/
/* rand012()函数 */
/*返回0、1、2的随机函数 */
/********************************************/
int rand012(){
int rnd;
/* 去除随机数的最大值 */
while( (rnd=rand()) == RAND_MAX);
/* 计算随机数 */
return (double)rnd/RAND_MAX*3;
}