决策树C4.5

 C4.5算法继承了ID3算法的优点,并在以下几方面对ID3算法进行了改进:

    1) 用信息增益率来选择属性,克服了用信息增益选择属性时偏向选择取值多的属性的不足;

    2) 在树构造过程中进行剪枝;

    3) 能够完成对连续属性的离散化处理;

    4) 能够对不完整数据进行处理。

C4.5算法优点:产生的分类规则易于理解,准确率较高。

缺点:在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导致算法的低效。此外,C4.5只适合于能够驻留于内存的数据集,当训练集大得无法在内存容纳时程序无法运行。


C4.5算法的优点是产生的分类规则易于理解,准确率较高。缺点就是在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导致算法的低效。此外,C4.5算法只适合于能够驻留于内存的数据集,当训练集大得无法在内存容纳时,程序无法运行。

1、C4.5算法的实现

假设用S代表当前样本集,当前候选属性集用A表示,则C4.5算法C4.5formtree(S,A)的伪代码如下。

    算法:Generate_decision_tree由给定的训练数据产生一棵决策树

    输入:训练样本samples;候选属性的集合attributelist

    输出:一棵决策树

(1)  创建根节点N

(2)  IF S都属于同一类C,则返回N为叶节点,标记为类C;

(3)  IFattributelist为空 OR S中所剩的样本数少于某给定值

则返回N为叶节点,标记N为S中出现最多的类;

(4)  FOReach  attributelist中的属性

计算信息增益率information gain ratio

(5)  N的测试属性test.attribute = attributelist具有最高信息增益率的属性;

(6)  IF测试属性为连续型

则找到该属性的分割阈值;

(7)  For each由节点N一个新的叶子节点{

If该叶子节点对应的样本子集S’为空

则分裂此叶子节点生成新叶节点,将其标记为S中出现最多的类

                  Else

                     在该叶子节点上执行C4.5formtree(S’,S’.attributelist),继续对它分裂;

                  }

(8)  计算每个节点的分类错误,进行剪枝。


#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include "malloc.h"
#include <stdlib.h>
const int MAX = 10;
int** iInput;
int i = 0;//列数
int j = 0;//行数
void build_tree(FILE *fp, int* iSamples, int* iAttribute,int ilevel);//输出规则
int choose_attribute(int* iSamples, int* iAttribute);//通过计算信息增益率选出test_attribute
double info(double dTrue,double dFalse);//计算期望信息
double entropy(double dTrue, double dFalse, double dAll);//求熵
double splitinfo(int* list,double dAll);
int check_samples(int *iSamples);//检查samples是否都在同一个类里
int check_ordinary(int *iSamples);//检查最普通的类
int check_attribute_null(int *iAttribute);//检查attribute是否为空
void get_attributes(int *iSamples,int *iAttributeValue,int iAttribute);
int _tmain(int argc, _TCHAR* argv[])
{
 FILE *fp;
 FILE *fp1;
 char iGet;
 int a = 0;
 int b = 0;//a,b是循环变量
 int* iSamples;
 int* iAttribute;
 fp = fopen("c:\\input.txt","r");
 if (NULL == fp)
 {
  printf("error\n");
  return 0;
 }
 iGet = getc(fp);
 
 while (('\n' != iGet)&&(EOF != iGet))
 {if (',' == iGet)
  {i++; }
  iGet = getc(fp); }
 i++;
 iAttribute = (int *)malloc(sizeof(int)*i);
 for (int k = 0; k<i; k++)
 {iAttribute[k] = (int)malloc(sizeof(int));
  iAttribute[k] = 1; }
 while (EOF != iGet)
 { if ('\n' == iGet)
  {j++; }
  iGet = getc(fp); }
 j++;
 iInput = (int **)malloc(sizeof(int*)*j);
 iSamples = (int *)malloc(sizeof(int)*j);
 for (a = 0;a < j;a++)
 { iInput[a] = (int *)malloc(sizeof(int)*i);
  iSamples[a] = (int)malloc(sizeof(int));
  iSamples[a] = a; }
 a = 0;
 fclose(fp);
 fp=fopen("c:\\input.txt","r");
 iGet = getc(fp);
 while(EOF != iGet)
 {  if ((',' != iGet)&&('\n' != iGet))
  { iInput[a][b] = iGet - 48;
   b++;  }
  if (b == i)
  { a++;
   b = 0;}
  iGet = getc(fp); }
 fp1 = fopen("d:\\output.txt","w");
 build_tree(fp1,iSamples,iAttribute,0);
 fclose(fp);
 return 0;}
void build_tree(FILE * fp, int* iSamples, int* iAttribute,int level)//
{ int iTest_Attribute = 0;
 int iAttributeValue[MAX];
 int k = 0;
 int l = 0;
 int m = 0;
 int *iSamples1;
 for (k = 0; k<MAX; k++)
 { iAttributeValue[k] = -1; }
 if (0 == check_samples(iSamples))
{fprintf(fp,"result: %d\n",iInput[iSamples[0]][i-1];
 return; }
 if (1 == check_attribute_null(iAttribute))
{fprintf(fp,"result: %d\n",check_ordinary(iSamples));
  return; }
 iTest_Attribute = choose_attribute(iSamples,iAttribute);
 iAttribute[iTest_Attribute] = -1;
get_attributes(iSamples,iAttributeValue,iTest_Attribute);
 k = 0;
 while ((-1 != iAttributeValue[k])&&(k < MAX))
 {  l = 0;
  m = 0;
  while ((-1 != iSamples[l])&&(l < j))
 {if(iInput[iSamples[l]][iTest_Attribute]== iAttributeValue[k])
   {  m++; }
   l++;  }
  iSamples1 = (int *)malloc(sizeof(int)*(m+1));
  l = 0;
  m = 0;
  while ((-1 != iSamples[l])&&(l < j))
  {if(iInput[iSamples[l]][iTest_Attribute]== iAttributeValue[k])
   { iSamples1[m] = iSamples[l];
    m++; }
   l++; }
  iSamples1[m] = -1;
  if (-1 == iSamples1[0])
{fprintf(fp,"result: %d\n",check_ordinary(iSamples));
   return; }
  fprintf(fp,"level%d: %d = %d\n",level,iTest_Attribute,iAttributeValue[k]);
  build_tree(fp,iSamples1,iAttribute,level+1);
  k++; }}
int choose_attribute(int* iSamples, int* iAttribute)
{ int iTestAttribute = -1;
 int k = 0;
 int l = 0;
 int m = 0;
 int n = 0;
 int iTrue = 0;
 int iFalse = 0;
 int iTrue1 = 0;
 int iFalse1 = 0;
 int iDepart[MAX];
 int iRecord[MAX];
 double dEntropy = 0.0;
 double dGainratio = 0.0;
 double test = 0.0;
 for (k = 0;k<MAX;k++)
 { iDepart[k] = -1;
  iRecord[k] = 0; }
 k = 0;
 while ((l!=2)&&(k<(i - 1)))
 { if (iAttribute[k] == -1)
  {  l++;  }
  k++; }
 if (l == 1)
 { for (k = 0;k<(k-1);k++)
  { if (iAttribute[k] == -1)
   {  return iAttribute[k]; }  } }
 for (k = 0;k < (i-1);k++)
 {  l = 0;
  iTrue = 0;
  iFalse = 0;
  if (iAttribute[k] != -1)
  { while ((-1 != iSamples[l])&&(l < j))
   {  if (0 == iInput[iSamples[l]][i-1])
    { iFalse++; }
    if (1 == iInput[iSamples[l]][i-1])
    { iTrue++; }
    l++;     }
  for (n = 0;n<l;n++)//计算该属性有多少不同的值并记录
   { m = 0;
    while((iDepart[m]!=-1)&&(m!=MAX))
{ if (iInput[iSamples[n]][iAttribute[k]] == iDepart[m])
     {break;  }
     m++;  }
    if (-1 == iDepart[m])
{ iDepart[m] = iInput[iSamples[n]][iAttribute[k]];  } }
   while ((iDepart[m] != -1)&&(m!=MAX))
   {  for (n = 0;n<l;n++)
 {if (iInput[iSamples[n]][iAttribute[k]] == iDepart[m])
     {if (1 == iInput[iSamples[n]][i-1])
      {  iTrue1++;   }
      if (0 == iInput[iSamples[n]][i-1])
      { iFalse1++;  }
      iRecord[m]++;  }  }
     dEntropy += entropy((double)iTrue1,(double)iFalse1,(double)l);
    iTrue1 = 0;
    iFalse1 = 0;
    m++; }
   double dSplitinfo = splitinfo(iRecord,(double)l);
   if (-1 == iTestAttribute)
   {iTestAttribute = k;
dGainratio= (info((double)iTrue,(double)iFalse)-dEntropy)/dSplitinfo;}
else{test=(info((double)iTrue,(double)iFalse)-dEntropy)/dSplitinfo;
if (dGainratio < test)
    { iTestAttribute = k;
     dGainratio = test; }}} }
 return iTestAttribute;}
double info(double dTrue,double dFalse)
{ double dInfo = 0.0;
 dInfo = ((dTrue/(dTrue+dFalse))*(log(dTrue/(dTrue+dFalse))/log(2.0))+(dFalse/(dTrue+dFalse))*(log(dFalse/(dTrue+dFalse))/log(2.0)))*(-1);
 return dInfo;}
double entropy(double dTrue, double dFalse, double dAll)
{ double dEntropy = 0.0;
 dEntropy = (dTrue + dFalse)*info(dTrue,dFalse)/dAll;
 return dEntropy;}
double splitinfo(int* list,double dAll)
{ int k = 0;
 double dSplitinfo = 0.0;
 while (0!=list[k])
{dSplitinfo-=((double)list[k]/(double)dAll)*(log((double)list[k]/(double)dAll));
  k++; }
 return dSplitinfo;}
int check_samples(int *iSamples)
{ int k = 0;
 int b = 0;
 while ((-1 != iSamples[k])&&(k < j-1))
 { if (iInput[k][i-1] != iInput[k+1][i-1])
  {b = 1;
   break; }
  k++; }
 return b;}
int check_ordinary(int *iSamples)
{ int k = 0;
 int iTrue = 0;
 int iFalse = 0;
 while ((-1 != iSamples[k])&&(k < i))
 { if (0 == iInput[iSamples[k]][i-1])
  {iFalse++; }
  else
  { iTrue++; }
  k++;}
 if (iTrue >= iFalse)
 { return 1;}
 else
 { return 0; }}
int check_attribute_null(int *iAttribute)
{ int k = 0;
 while (k < (i-1))
 {if (-1 != iAttribute[k])
  { return 0;}
  k++; }
 return 1;}
void get_attributes(int *iSamples,int *iAttributeValue,int iAttribute)
{int k = 0;
 int l = 0;
 while ((-1 != iSamples[k])&&(k < j))
 {l = 0;
  while (-1 != iAttributeValue[l])
 {if (iInput[iSamples[k]][iAttribute] == iAttributeValue[l])
   { break; }
   l++; }
  if (-1 == iAttributeValue[l])
{iAttributeValue[l] = iInput[iSamples[k]][iAttribute];
  }
  k++;}}

决策树资源下载页


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值