人工智能天气决策树源代码.docx
《人工智能天气决策树源代码.docx》由会员分享,可在线阅读,更多相关《人工智能天气决策树源代码.docx(19页珍藏版)》请在冰豆网上搜索。
人工智能天气决策树源代码
昆明理工大学信息工程与自动化学院学生实验报告
(2011—2012学年第1学期)
课程名称:
人工智能开课实验室:
信自楼计算机机房4442011年12月16日
专业班级
0
学号
200
姓名
成绩
实验名称
天气决策树
指导教师
教师评语
该同学是否了解实验原理:
A.了解□B.基本了解□C.不了解□
该同学的实验能力:
A.强□B.中等□C.差□
该同学的实验是否达到要求:
A.达到□B.基本达到□C.未达到□
实验报告是否规范:
A.规范□B.基本规范□C.不规范□
实验过程是否详细记录:
A.详细□B.一般□C.没有□
教师签名:
2011年12月日
一、上机目的及内容
1.上机内容
根据下列给定的14个数据,运用InformationGain构造一个天气决策树。
例子编号
属性
分类
天况
温度
湿度
风况
1
晴
热
大
无
N
2
晴
热
大
有
N
3
多云
热
大
无
P
4
雨
中
大
无
P
5
雨
冷
正常
无
P
6
雨
冷
正常
有
N
7
多云
冷
正常
有
P
8
晴
中
大
无
N
9
晴
冷
正常
无
P
10
雨
中
正常
无
P
11
晴
中
正常
有
P
12
多云
中
大
有
P
13
多云
热
正常
无
P
14
雨
中
大
有
N
2.上机目的
(1)学习用InformationGain构造决策树的方法;
(2)在给定的例子上,构造出正确的决策树;
(3)理解并掌握构造决策树的技术要点。
二、实验原理及基本技术路线图(方框原理图或程序流程图)
(1)设计并实现程序,构造出正确的决策树;
(2)对所设计的算法采用大O符号进行时间复杂性和空间复杂性分析;
主函数流程图:
Attributevalue.cpp流程图
Basefun流程图:
Datapiont.cpp流程图:
Dataset主要流程图:
三、所用仪器、材料(设备名称、型号、规格等或使用软件)
1台PC及VISUALC++6.0软件
4、实验方法、步骤(或:
程序代码或操作过程)
工程源代码:
Main.cpp:
#include
#include
#include
#include
#include
#include
#include"AttributeValue.h"
#include"DataPoint.h"
#include"DataSet.h"
DataPointprocessLine(std:
:
stringconst&sLine)
{
std:
:
istringstreamisLine(sLine,std:
:
istringstream:
:
in);
std:
:
vectorattributes;
//TODO:
needtohandlebeginningandendingemptyspaces.
while(isLine.good())
{
std:
:
stringrawfield;
isLine>>rawfield;
attributes.push_back(AttributeValue(rawfield));
}
AttributeValuev=attributes.back();
attributes.pop_back();
booltype=v.GetType();
returnDataPoint(attributes,type);
}
voidmain()
{
std:
:
ifstreamifs("in.txt",std:
:
ifstream:
:
in);
DataSetinitDataset;
while(ifs.good())
{
//TODO:
needtohandleemptylines.
std:
:
stringsLine;
std:
:
getline(ifs,sLine);
initDataset.addDataPoint(processLine(sLine));
}
std:
:
listprocessQ;
std:
:
vectorfinishedDataSet;
processQ.push_back(initDataset);
while(processQ.size()>0)
{
std:
:
vectorsplittedDataSets;
DataSetdataset=processQ.front();
dataset.splitDataSet(splittedDataSets);
processQ.pop_front();
for(inti=0;i{
floatprob=splittedDataSets[i].getPositiveProb();
if(prob==0.0||prob==1.0)
{
finishedDataSet.push_back(splittedDataSets[i]);
}
else
{
processQ.push_back(splittedDataSets[i]);
}
}
}
std:
:
cout<<"Thedicisiontreeis:
"<:
endl;
for(inti=0;i{
finishedDataSet[i].display();
}
}
Attributevalue.cpp:
#include"AttributeValue.h"
#include"base.h"
AttributeValue:
:
AttributeValue(std:
:
stringconst&instring)
:
m_value(instring)
{
}
boolAttributeValue:
:
GetType()
{
if(m_value=="P")
{
returntrue;
}
elseif(m_value=="N")
{
returnfalse;
}
else
{
throwDataErrException();
}
}
Basefun.cpp:
#include
floatlog2(floatx)
{
return1.0/log10
(2)*log10(x);
}
floatcalEntropy(floatprob)
{
floatsum=0;
if(prob==0||prob==1)
{
return0;
}
sum-=prob*log2(prob);
sum-=(1-prob)*log2(1-prob);
returnsum;
}
Datapiont.cpp:
#include
#include"DataPoint.h"
DataPoint:
:
DataPoint(std:
:
vectorconst&attributes,booltype)
:
m_type(type)
{
for(inti=0;i{
m_attributes.push_back(attributes[i]);
}
}
voidDataPoint:
:
display()
{
for(inti=0;i{
std:
:
cout<<"\t"<}
if(true==m_type)
{
std:
:
cout<<"\tP";
}
else
{
std:
:
cout<<"\tN";
}
std:
:
cout<:
endl;
}
Dataset.cpp:
#include
#include
#include"base.h"
#include"DataSet.h"
voidSplitAttributeValue:
:
display()
{
std:
:
cout<<"\tSplitattributeID("<std:
:
cout<<"Splitattributevalue("<:
endl;
}
voidDataSet:
:
addDataPoint(DataPointconst&datapoint)
{
m_data.push_back(datapoint);
}
floatDataSet:
:
getPositiveProb()
{
floatnPositive=0;
for(inti=0;i{
if(m_data[i].isPositive())
{
nPositive++;
}
}
returnnPositive/m_data.size();
}
structStat
{
intnPos;
intnNeg;
intid;
};
voidDataSet:
:
splitDataSet(std:
:
vector&splittedSets)
{
//findallavailablesplittingattributes
intnAttributes=m_data[0].getNAttributes();
inti,j;
std:
:
vectorsplittingAttributeBV;
splittingAttributeBV.resize(nAttributes);
for(i=0;i{
splittingAttributeBV[i]=true;
}
for(i=0;i{
splittingAttributeBV[m_splitAttributes[i].getAttributeIndex()]=false;
}
std:
:
vectorsplittingAttributeIds;
for(i=0;i{
if(true==splittingAttributeBV[i])
{
splittingAttributeIds.push_back(i);
}
}
typedefstd:
:
mapAttributeValueStat;
typedefstd:
:
map:
:
iteratorAttributeValueStat_iterator;
typedefstd:
:
map:
:
const_iteratorAttributeValueStat_const_iterator;
//gothroughdataonce,andcollectneededstatisticstocalculateentropy
std:
:
vectorsplittingStats;
splittingStats.resize(splittingAttributeIds.size());
for(i=0;i{
for(j=0;j{
AttributeValueconst&v=m_data[i].getAttribute(splittingAttributeIds[j]);
AttributeValueStat_iteratorit=splittingStats[j].find(v);
if(splittingStats[j].end()==it)
{
Statstat;
if(m_data[i].isPositive())
{
stat.nPos=1;
stat.nNeg=0;
stat.id=0;
}
else
{
stat.nPos=0;
stat.nNeg=1;
stat.id=0;
}
splittingStats[j].insert(std:
:
pair(v,stat));
}
else
{
if(m_data[i].isPositive())
{
it->second.nPos++;
}
else
{
it->second.nNeg++;
}
}
}
}
//displaycollectedstatistics
for(j=0;j{
std:
:
cout<<"Attribute("<"<:
endl;
std:
:
cout<<"\tValue\tnPos\tnNeg"<:
endl;
for(AttributeValueStat_const_iteratorit=splittingStats[j].begin();
it!
=splittingStats[j].end();++it)
{
std:
:
cout<<"\t"<first.getValue()<<"\t"<second.nPos<<"\t"<second.nNeg<:
endl;
}
}
//findsplittingattribute
floatminEntropy=0.0;
intsplitAttributeId=-1;
for(j=0;j{
intn=m_data.size();
floatentropy=0.0;
for(AttributeValueStat_iteratorit=splittingStats[j].begin();
it!
=splittingStats[j].end();++it)
{
intnSamples=it->second.nPos+it->second.nNeg;
floatp=it->second.nPos;
p/=nSamples;
entropy+=calEntropy(p)*nSamples/n;
}
if(entropy{
minEntropy=entropy;
splitAttributeId=j;
}
}
std:
:
cout<<"Splitatattribute("<:
endl<:
endl;
//split
intattrId=splittingAttributeIds[splitAttributeId];
AttributeValueStatconst&attVStat=splittingStats[splitAttributeId];
splittedSets.clear();
intk=0;
for(AttributeValueStat_iteratorit=splittingStats[splitAttributeId].begin();
it!
=splittingStats[splitAttributeId].end();++it)
{
it->second.id=k++;
}
splittedSets.resize(k);
for(i=0;i{
for(j=0;j{
splittedSets[i].m_splitAttributes.push_back(m_splitAttributes[j]);
}
}
for(AttributeValueStat_iteratoritt=splittingStats[splitAttributeId].begin();
itt!
=splittingStats[splitAttributeId].end();++itt)
{
splittedSets[itt->second.id].m_splitAttributes.push_back(SplitAttributeValue(itt->first,attrId));
}
for(i=0;i{
AttributeValueconst&v=m_data[i].getAttribute(attrId);
AttributeValueStat_const_iteratorit=attVStat.find(v);
if(attVStat.end()!
=it)
{
splittedSets[it->second.id].addDataPoint(m_data[i]);
}
else
{
throwDataErrException();
}
}
}
voidDataSet:
:
display()
{
inti;
std:
:
cout<<"Dataset("<:
endl;
for(i=0;i{
m_splitAttributes[i].display();
}
std:
:
cout<<"Data:
"<:
endl;
for(i=0;i{
m_data[i].display();
}
std:
:
cout<:
endl;
}
五、实验过程原始记录(测试数据、图表、计算等)
6、实验结果、分析和结论(误差分析与数据处理、成果总结等。
其中,绘制曲线图时必须用计算纸或程序运行结果、改进、收获)
Attributevalue.cpp的作用是判断正反例,以便下面的的划分决策过程,basefun.cpp的作用则是计算熵,通过熵的比。
较才能够为下面的划分提供条件依据,而dataset.cpp就是具体的划分过程,首先找到可用的划分项目,再第一次划分之后再手机相关的数据来计算熵。
之后再显示出来,做这个实验的时候我遇到了很大的难度,感觉它的要求和自己的实际水平相差很大,所以参考了很多资料才得以完成这个程序,也感觉到了自己的能力还很不足,还需要加强的地方还有很多。