昆明理工大学天气决策树.docx
《昆明理工大学天气决策树.docx》由会员分享,可在线阅读,更多相关《昆明理工大学天气决策树.docx(18页珍藏版)》请在冰豆网上搜索。
昆明理工大学天气决策树
昆明理工大学信息工程与自动化学院学生实验报告
(—学年第1学期)
课程名称:
人工智能开课实验室:
信自楼504年12月24日
年级、专业、班
学号
姓名
成绩
实验项目名称
天气决策树
指导教师
吴霖
教师评语
该同学是否了解实验原理:
A.了解□B.基本了解□C.不了解□
该同学的实验能力:
A.强□B.中等□C.差□
该同学的实验是否达到要求:
A.达到□B.基本达到□C.未达到□
实验报告是否规范:
A.规范□B.基本规范□C.不规范□
实验过程是否详细记录:
A.详细□B.一般□C.没有□
教师签名:
年月日
一、上机目的及内容
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符号进行时间复杂性和空间复杂性分析;
实验考虑到几个属性:
天况——晴、雨、多云;温度——热、中、冷;湿度——大、正常;风况——有、无;然后根据每个属性来算出信息增益,接下来我们根据信息增益最大的来进行划分。
根据问题设计算法,建立数据结构,设计需要用的类,然后通过编程实现问题求解。
了解和求解最大信息增益和最小熵选择平均熵最小的属性作为根节点,用同样的方法选择其他节点直至形成整个决策树。
dataset就是具体的划分过程,首先找到可用的划分项目,再第一次划分之后再相关的数据来计算熵。
Main函数流程图Dataset函数主要流程图Basefun函数流程图
Attributevalue函数流程图
Datapiont函数流程图
三、所用仪器、材料(设备名称、型号、规格等或使用软件)
1台PC及VISUALC++软件
四、实验方法、步骤(或:
程序代码或操作过程)
源代码:
main函数:
#include
#include
#include
#include
#include
#include
#include""
#include""
#include""
DataPointprocessLine(std:
:
stringconst&sLine)
{
std:
:
istringstreamisLine(sLine,std:
:
istringstream:
:
in);
std:
:
vectorattributes;
while(())
{
std:
:
stringrawfield;
isLine>>rawfield;
(AttributeValue(rawfield));
}
AttributeValuev=();
();
booltype=();
returnDataPoint(attributes,type);
}
voidmain()
{
std:
:
ifstreamifs("",std:
:
ifstream:
:
in);
DataSetinitDataset;
while(())
{
std:
:
stringsLine;
std:
:
getline(ifs,sLine);
(processLine(sLine));
}
std:
:
listprocessQ;
std:
:
vectorfinishedDataSet;
(initDataset);
while(()>0)
{
std:
:
vectorsplittedDataSets;
DataSetdataset=();
(splittedDataSets);
();
for(inti=0;i<();++i)
{
floatprob=splittedDataSets[i].getPositiveProb();
if(prob==||prob==
{
(splittedDataSets[i]);
}
else
{
(splittedDataSets[i]);
}
}
}
std:
:
cout<<"Thedicisiontreeis:
"<:
endl;
for(inti=0;i<();++i)
{
finishedDataSet[i].display();
}
}
DataSet函数:
#include
#include
#include""
#include""
voidSplitAttributeValue:
:
display()
{
std:
:
cout<<"\tSplitattributeID("<std:
:
cout<<"Splitattributevalue("<<()<<")"<:
endl;
}
voidDataSet:
:
addDataPoint(DataPointconst&datapoint)
{
(datapoint);
}
floatDataSet:
:
getPositiveProb()
{
floatnPositive=0;
for(inti=0;i<();++i)
{
if(m_data[i].isPositive())
{
nPositive++;
}
}
returnnPositive/();
}
structStat
{
intnPos;
intnNeg;
intid;
};
voidDataSet:
:
splitDataSet(std:
:
vector&splittedSets)
{
etNAttributes();
inti,j;
std:
:
vectorsplittingAttributeBV;
(nAttributes);
for(i=0;i{
splittingAttributeBV[i]=true;
}
for(i=0;i<();++i)
{
splittingAttributeBV[m_splitAttributes[i].getAttributeIndex()]=false;
}
std:
:
vectorsplittingAttributeIds;
for(i=0;i{
if(true==splittingAttributeBV[i])
{
(i);
}
}
typedefstd:
:
mapAttributeValueStat;
typedefstd:
:
map:
:
iteratorAttributeValueStat_iterator;
typedefstd:
:
map:
:
const_iteratorAttributeValueStat_const_iterator;
etAttribute(splittingAttributeIds[j]);
AttributeValueStat_iteratorit=splittingStats[j].find(v);
if(splittingStats[j].end()==it)
{
Statstat;
if(m_data[i].isPositive())
{
=1;
=0;
=0;
}
else
{
=0;
=1;
=0;
}
splittingStats[j].insert(std:
:
pair(v,stat));
}
else
{
if(m_data[i].isPositive())
{
it->++;
}
else
{
it->++;
}
}
}
}
egin();
it!
=splittingStats[j].end();++it)
{
std:
:
cout<<"\t"<()<<"\t"<<<"\t"<<:
endl;
}
}
egin();
it!
=splittingStats[j].end();++it)
{
intnSamples=it->+it->;
floatp=it->;
p/=nSamples;
entropy+=calEntropy(p)*nSamples/n;
}
if(entropy{
minEntropy=entropy;
splitAttributeId=j;
}
}
std:
:
cout<<"Splitatattribute("<:
endl<:
endl;
egin();
it!
=splittingStats[splitAttributeId].end();++it)
{
it->=k++;
}
(k);
for(i=0;i{
for(j=0;j<();++j)
{
splittedSets[i].(m_splitAttributes[j]);
}
}
for(AttributeValueStat_iteratoritt=splittingStats[splitAttributeId].begin();
itt!
=splittingStats[splitAttributeId].end();++itt)
{
splittedSets[itt->].(SplitAttributeValue(itt->first,attrId));
}
for(i=0;i<();++i)
{
AttributeValueconst&v=m_data[i].getAttribute(attrId);
AttributeValueStat_const_iteratorit=(v);
if(()!
=it)
{
splittedSets[it->].addDataPoint(m_data[i]);
}
else
{
throwDataErrException();
}
}
}
voidDataSet:
:
display()
{
inti;
std:
:
cout<<"Dataset("<:
endl;
for(i=0;i<();++i)
{
m_splitAttributes[i].display();
}
std:
:
cout<<"Data:
"<:
endl;
for(i=0;i<();++i)
{
m_data[i].display();
}
std:
:
cout<:
endl;
}
DataPoint函数:
#include<>
floatlog2(floatx)
{
return/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;
}
Basefun函数:
#include<>
floatlog2(floatx)
{
return/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;
}
AttributeValue函数:
#include""
#include""
AttributeValue:
:
AttributeValue(std:
:
stringconst&instring)
:
m_value(instring)
{
}
boolAttributeValue:
:
GetType()
{
if(m_value=="P")
{
returntrue;
}
elseif(m_value=="N")
{
returnfalse;
}
else
{
throwDataErrException();
}
}
AttributeValue头文件:
#ifndefATTRIBUTE_VALUE_H_
#defineATTRIBUTE_VALUE_H_
#include
classAttributeValue
{
public:
AttributeValue(std:
:
stringconst&instring);
boolGetType();
std:
:
stringconst&getValue()const
{
returnm_value;
}
private:
std:
:
stringm_value;
};
structAttributeValueCmp
{
booloperator()(AttributeValueconst&lhs,AttributeValueconst&rhs)const
{
return()<();
}
};
#endif
Base头文件:
classDataErrException:
publicstd:
:
exception
{
};
floatcalEntropy(floatprob);
DataPoint头文件:
#ifndefDATA_POINT_H_
#defineDATA_POINT_H_
#include
#include""
classDataPoint
{
public:
DataPoint(std:
:
vectorconst&attributes,booltype);
boolisPositive()
{
returnm_type;
}
intgetNAttributes()
{
return();
}
AttributeValueconst&getAttribute(intindex)
{
returnm_attributes[index];
}
voiddisplay();
private:
std:
:
vectorm_attributes;
boolm_type;
};
#endif
DataSet头文件:
#include
#include
#include""
classSplitAttributeValue
{
public:
SplitAttributeValue(AttributeValuev,intid)
:
m_v(v)
m_attributeIndex(id)
{
}
intgetAttributeIndex()
{
returnm_attributeIndex;
}
voiddisplay();
private:
intm_attributeIndex;
AttributeValuem_v;
};
classDataSet
{
public:
voidaddDataPoint(DataPointconst&datapoint);
floatgetPositiveProb();
voidsplitDataSet(std:
:
vector&splittedSets);
voiddisplay();
private:
std:
:
vectorm_splitAttributes;
std:
:
vectorm_data;
};
五、实验过程原始记录(测试数据、图表、计算等)
六、实验结果、分析和结论(误差分析与数据处理、成果总结等。
其中,绘制曲线图时必须用计算纸或程序运行结果、改进、收获)
Attributevalue的作用是判断正反例,以便下面的的划分决策过程,basefun的作用则是计算熵,通过熵的比。
dataset就是具体的划分过程,首先找到可用的划分项目,再第一次划分之后再手机相关的数据来计算熵。
通过该实验,我了解了如何采用InformationGain构建天气决策树,以及了解什么是熵,如何计算熵等等。
同时也意识到自己基础知识的欠缺,今后的学习中会更加注重基础知识的掌握和巩固,争取熟练运用所学的知识。
注:
教师必须按照上述各项内容严格要求,认真批改和评定学生成绩。