转载自:http://blog.sina.com.cn/s/blog_73621a3201017g7k.html
1.3、C4.5算法
- 用信息增益率来选择属性。ID3选择属性用的是子树的信息增益,这里可以用很多方法来定义信息,ID3使用的是熵(entropy,熵是一种不纯度度量准则),也就是熵的变化值,而C4.5用的是信息增益率。对,区别就在于一个是信息增益,一个是信息增益率。
- 在树构造过程中进行剪枝,在构造决策树的时候,那些挂着几个元素的节点,不考虑最好,不然容易导致overfitting。
- 对非离散数据也能处理。
- 能够对不完整数据进行处理
C4.5算法之信息增益率
1.3.2、C4.5算法构造决策树的过程
- Function
C4.5(R:包含连续属性的无类别属性集合,C:类别属性,S:训练集) -
- Begin
-
If S为空,返回一个值为Failure的单个节点; -
If S是由相同类别属性值的记录组成, -
返回一个带有该值的单个节点; -
If R为空,则返回一个单节点,其值为在S的记录中找出的频率最高的类别属性值; -
[注意未出现错误则意味着是不适合分类的记录]; -
For 所有的属性R(Ri) Do -
If 属性Ri为连续属性,则 -
Begin -
将Ri的最小值赋给A1: -
将Rm的最大值赋给Am; -
For j From 2 To m-1 Do Aj=A1+j*(A1Am)/m; -
将Ri点的基于{< =Aj,>Aj}的最大信息增益属性(Ri,S)赋给A; -
End; -
将R中属性之间具有最大信息增益的属性(D,S)赋给D; -
将属性D的值赋给{dj/j=1,2...m}; -
将分别由对应于D的值为dj的记录组成的S的子集赋给{sj/j=1,2...m}; -
返回一棵树,其根标记为D;树枝标记为d1,d2...dm; -
再分别构造以下树: -
C4.5(R-{D},C,S1),C4.5(R-{D},C,S2)...C4.5(R-{D},C,Sm); - End
C4.5
1.3.3、C4.5算法实现中的几个关键步骤
- double
C4_5::entropy(int *attrClassCount, int classNum, int allNum){ -
double iEntropy = 0.0; -
for(int i = 0; i < classNum; i++){ -
double temp = ((double)attrClassCount[i]) / allNum; -
if(temp != 0.0) -
iEntropy -= temp * (log(temp) / log(2.0)); -
} -
return iEntropy; - }
- double
C4_5::gainRatio(int classNum, vector<int *> attriCount, double pEntropy){ -
int* attriNum = new int[attriCount.size()]; -
int allNum = 0; -
-
for(int i = 0; i < (int)attriCount.size(); i++){ -
attriNum[i] = 0; -
for(int j = 0; j < classNum; j++){ -
attriNum[i] += attriCount[i][j]; -
allNum += attriCount[i][j]; -
} -
} -
double gain = 0.0; -
double splitInfo = 0.0; -
for(int i = 0; i < (int)attriCount.size(); i++){ -
gain -= ((double)attriNum[i]) / allNum * entropy(attriCount[i], classNum, attriNum[i]); -
splitInfo -= ((double)attriNum[i]) / allNum * (log(((double)attriNum[i])/allNum) / log(2.0)); -
} -
gain += pEntropy; -
delete[] attriNum; -
return (gain / splitInfo); - }
- int
C4_5::chooseAttribute(vector<int> attrIndex, vector<int *>* sampleCount){ -
int bestIndex = 0; -
double maxGainRatio = 0.0; -
int classNum = (int)(decisions[attrIndex[(int)attrIndex.size()-1]]).size();//number of class -
-
//computer the class entropy -
int* temp = new int[classNum]; -
int allNum = 0; -
for(int i = 0; i < classNum; i++){ -
temp[i] = sampleCount[(int)attrIndex.size()-1][i][i]; -
allNum += temp[i]; -
} -
double pEntropy = entropy(temp, classNum, allNum); -
delete[] temp; -
-
//computer gain ratio for every attribute -
for(int i = 0; i < (int)attrIndex.size()-1; i++){ -
double gainR = gainRatio(classNum, sampleCount[i], pEntropy); -
if(gainR > maxGainRatio){ -
bestIndex = i; -
maxGainRatio = gainR; -
} -
} -
return bestIndex; - }
1.4、决策树归纳的特点
- form
Wind:决策树使用于特征取值离散的情况,连续的特征一般也要处理成离散的(而很多文章没有表达出决策树的关键特征or概念)。实际应用中,决策树overfitting比较的严重,一般要做boosting。分类器的性能上不去,很主要的原因在于特征的鉴别性不足,而不是分类器的好坏,好的特征才有好的分类效果,分类器只是弱相关。 -
那如何提高 特征的鉴别性呢?一是设计特征时尽量引入domain knowledge,二是对提取出来的特征做选择、变换和再学习,这一点是机器学习算法不管的部分。