五子棋智能算法——决策树数据处理(二)

编程入门 行业动态 更新时间:2024-10-07 02:24:33

五子棋智能算法——决策树<a href=https://www.elefans.com/category/jswz/34/1768995.html style=数据处理(二)"/>

五子棋智能算法——决策树数据处理(二)

  其实博弈树与决策树本质上是相同的 只是决策树追求的是信息嫡的下降 使可能性趋于一个最大值从而达到预测效果 而博弈树正如上篇博文所述追求的是选择从自身打分最高的一步棋 

要是看懂了上篇文章的博弈树()的思想这里决策树也就不难了 作为AI的入门算法决策树是异常重要的 这里我决定先去实现决策树 再进一步实现MFC五子棋博弈树算法 因为决策树这里使用一个经典的例子 数据集较为简单 不像五子棋数据较为复杂无法直接明白算法的内容 而是被冗杂的数据缠身 

下面我们需要知道信息嫡是什么? 

很简单就是我说明天太阳从东边出来 这个是小概率事件 也就是不可能 我们把这种事情称之为信息嫡很低的事情

但是我说明天我要去打篮球这个不确定的因素就很多了 要考虑天气 上课等等因素 这种事情叫做信息嫡很高

所以今天完成这样一个例子 输入一些天气建立决策树来预测明天我能不能去打篮球

具体看这篇博文 

其实怎样度量前人已经推导出来

//计算以2为底的对数double Log2(double x){if(x<=0)return 0.0;elsereturn (double)log10(x)/log10(2);}//计算信息嫡double I(double p1,double p2){return -(p1*Log2(p1)+p2*Log2(p2));}

代码实现也很简单

这样想一下上次的五子棋博弈树算法 这个就相当于我打分的函数

接下来看到信息嫡的公式我么需要统计数据算出权值 来计算信息嫡

//训练数据集结构struct TRAINING{int outLook;int temperature;int humidity;int windy;int play;struct TRAINING *next;};struct TRAINING trainingSet[TRAINING_NUMBER]={{SUNNY   ,85,85,FALSE,NOT_PLAY,NULL},{SUNNY   ,80,90,TRUE ,NOT_PLAY,NULL},{VOERCAST,83,78,FALSE,CAN_PLAY,NULL},{RAIN    ,70,96,FALSE,CAN_PLAY,NULL},{RAIN    ,68,80,FALSE,CAN_PLAY,NULL},{RAIN    ,65,70,TRUE ,NOT_PLAY,NULL},{VOERCAST,64,65,TRUE ,CAN_PLAY,NULL},{SUNNY   ,72,95,FALSE,NOT_PLAY,NULL},{SUNNY   ,69,70,FALSE,CAN_PLAY,NULL},{RAIN    ,75,80,FALSE,CAN_PLAY,NULL},{SUNNY   ,75,70,TRUE ,CAN_PLAY,NULL},{VOERCAST,72,90,TRUE ,CAN_PLAY,NULL},{VOERCAST,81,75,FALSE,CAN_PLAY,NULL},{RAIN    ,71,80,TRUE ,NOT_PLAY,NULL}};

我使用代码将这些数据使用链表储存来便于我们的操作 


struct TRAINING *CreateTrainingLink(struct TRAINING set[]){struct TRAINING *head,*p,*q;int i;p=(struct TRAINING *)malloc(sizeof(struct TRAINING));memset(p,0,sizeof(struct TRAINING));head=p;p->next=NULL;q=p;for(i=0;i<TRAINING_NUMBER;i++){p=(struct TRAINING *)malloc(sizeof(struct TRAINING));memset(p,0,sizeof(struct TRAINING));p->outLook=set[i].outLook;p->temperature=set[i].temperature;p->humidity=set[i].humidity;p->windy=set[i].windy;p->play=set[i].play;p->next=NULL;q->next=p;q=q->next;}return head;}

计算加权平均值 用于计算信息嫡

//计算加权平均值double InformationAttr(int attribute,struct TRAINING *head){struct TRAINING *p;struct TEMPER_HUMID_GAIN tGain[3];struct TEMPER_HUMID_GAIN mGain[2];int c=0;int i=0,j=0;int sunny=0,overcast=0,rain=0;int sPlay=0,oPlay=0,rPlay=0;int wind=0,windPlay=0;int noWind=0,noWindPlay=0;double p1=0,p2=0,p3=0;double i1=0,i2=0,i3=0;p=head->next;switch(attribute){case OUTLOOK:while(p){c++;if(p->outLook==SUNNY){sunny++;//晴天总数if(p->play==CAN_PLAY)sPlay++;//是晴天时且可以打球的天数}if(p->outLook==VOERCAST){overcast++;if(p->play==CAN_PLAY)oPlay++;}if(p->outLook==RAIN){rain++;if(p->play==CAN_PLAY)rPlay++;}p=p->next;}p1=(double)sunny/c;p2=(double)overcast/c;p3=(double)rain/c;if(sunny)i1=I((double)sPlay/sunny,(double)(sunny-sPlay)/sunny);if(overcast)i2=I((double)oPlay/overcast,(double)(overcast-oPlay)/overcast);if(rain)i3=I((double)rPlay/rain,(double)(rain-rPlay)/rain);return p1*i1+p2*i2+p3*i3;case TEMPERATURE:for(i=0;i<3;i++){tGain[i].c=0;tGain[i].playCount=0;if(i==0)tGain[i].value=HIGH_TEMPERATURE;else if(i==1)tGain[i].value=MID_TEMPERATURE;elsetGain[i].value=COLD_TEMPERATURE;}while(p){c++;if(p->temperature/10==HIGH_TEMPERATURE){tGain[0].c++;if(p->play==CAN_PLAY)tGain[0].playCount++;}else if(p->temperature/10==MID_TEMPERATURE){tGain[1].c++;if(p->play==CAN_PLAY)tGain[1].playCount++;}else if(p->temperature/10==COLD_TEMPERATURE){tGain[2].c++;if(p->play==CAN_PLAY)tGain[2].playCount++;}p=p->next;}p1=(double)tGain[0].c/c;p2=(double)tGain[1].c/c;p3=(double)tGain[2].c/c;if(tGain[0].c)i1=I((double)tGain[0].playCount/tGain[0].c,(double)(tGain[0].c-tGain[0].playCount)/tGain[0].c);if(tGain[1].c)i2=I((double)tGain[1].playCount/tGain[1].c,(double)(tGain[1].c-tGain[1].playCount)/tGain[1].c);if(tGain[2].c)i3=I((double)tGain[2].playCount/tGain[2].c,(double)(tGain[2].c-tGain[2].playCount)/tGain[2].c);return p1*i1+p2*i2+p3*i3;case HUMIDITY:for(i=0;i<2;i++){mGain[i].c=0;mGain[i].playCount=0;if(i==0)mGain[i].value=HIGH_HUMIDITY;elsemGain[i].value=NORMAL_HUMIDITY;}while(p){c++;if(p->humidity>=mGain[0].value){mGain[0].c++;if(p->play==CAN_PLAY)mGain[0].playCount++;}else if(p->humidity<mGain[1].value){mGain[1].c++;if(p->play==CAN_PLAY)mGain[1].playCount++;}p=p->next;}p1=(double)mGain[0].c/c;p2=(double)mGain[1].c/c;if(mGain[0].c)i1=I((double)mGain[0].playCount/mGain[0].c,(double)(mGain[0].c-mGain[0].playCount)/mGain[0].c);if(mGain[1].c)i2=I((double)mGain[1].playCount/mGain[1].c,(double)(mGain[1].c-mGain[1].playCount)/mGain[1].c);return p1*i1+p2*i2;case WINDY:while(p){c++;if(p->windy==TRUE){wind++;if(p->play==CAN_PLAY)windPlay++;}if(p->windy==FALSE){noWind++;if(p->play==CAN_PLAY)noWindPlay++;}p=p->next;}p1=(double)wind/c;p2=(double)noWind/c;if(wind)i1=I((double)windPlay/wind,(double)(wind-windPlay)/wind);if(noWind)i2=I((double)noWindPlay/noWind,(double)(noWind-noWindPlay)/noWind);return p1*i1+p2*i2;}return 0.0;}

 

接下来继续 这里我们继续引入一个概念信息增量 info gain

公式是这个

为了便于理解,我们还是以一个实际的例子来说明信息增益的概念。假设有下表样本

第一列为QQ,第二列为性别,第三列为活跃度,最后一列用户是否流失。我们要解决一个问题:性别和活跃度两个特征,哪个对用户流失影响更大?我们通过计算信息熵可以解决这个问题。

按照分组统计,我们可以得到如下信息:

其中Positive为正样本(已流失),Negative为负样本(未流失),下面的数值为不同划分下对应的人数。那么可得到三个熵:

整体熵:

性别熵:

性别信息增益:

同理计算活跃度熵:

活跃度信息增益:

活跃度的信息增益比性别的信息增益大,也就是说,活跃度对用户流失的影响比性别大。在做特征选择或者数据分析的时候,我们应该重点考察活跃度这个指标。

上面案例可以一目了然的看出信息增益偏向于选择取值较多的特征,但根据熵的公式可知,特征越多,熵越大,所以除A特征的熵正好抵消了特征变量的复杂程度,避免了过拟合的存在。

好了get了这个两个东西 下面我们来实现计算gain 

 

double Gain(int attribute,struct TRAINING *head){return Information(head)-InformationAttr(attribute,head);}

到这里我们使用c语言完成了对于建立决策树数据的基本处理

更多推荐

五子棋智能算法——决策树数据处理(二)

本文发布于:2024-02-16 18:04:49,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1690994.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据处理   算法   五子   智能   决策树

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!