zoukankan      html  css  js  c++  java
  • 决策树ID3算法[分类算法]

    ID3分类算法的编码实现

      1 <?php
      2 /*
      3 *决策树ID3算法(分类算法的实现)
      4 */
      5 
      6 
      7 
      8 /*
      9 
     10 *求信息增益Grain(S1,S2)
     11 
     12 */
     13 
     14 //--------------------------------------------------------------------
     15 function Grain($train,$attriname,$flagsyes,$flagsno)
     16 {
     17     $attributename =  array(NULL);//用来存放属性$attriname不同的属性值
     18     array_splice($attributename,0,1);
     19     
     20     for($i=1;$i<count($train[0]);$i++)
     21     {
     22         if($attriname==$train[0][$i])
     23         {
     24             $num = $i;//记录$train第几个属性是$attriname
     25             for($j=1;$j<count($train);$j++)
     26             {
     27                 $flags = true;//用于判断将要存放的属性值是否已经存在
     28                 for($k=0;$k<count($attributename);$k++)
     29                 {
     30                     if($attributename[$k]==$train[$j][$i])//即将存入的属性值已经存在
     31                     {
     32                         $flags = false;
     33                         break;
     34                     }        
     35                 }
     36                 if($flags)//新的属性值不存在,$attributename存入新的属性值
     37                 {
     38                     array_push($attributename,$train[$j][$i]);
     39                 }
     40             }
     41             break;
     42         }
     43     }
     44     
     45     for($i=0;$i<count($attributename);$i++)
     46     {
     47         $count[$i][0] = $attributename[$i];//属性名称
     48         $count[$i][1] = 0;//用来统计$attributename[$i] $flagsyes的个数
     49         $count[$i][2] = 0;//用来统计$attributename[$i] $flagsno的个数    
     50     }
     51     
     52     for($i=1;$i<count($train);$i++)
     53     {
     54         for($j=0;$j<count($attributename);$j++)
     55         {
     56             //print_r($train[$i][count($train[$i])-1]."<br>");
     57             if(($train[$i][$num]==$attributename[$j])&&($train[$i][count($train[$i])-1]==$flagsyes))
     58             {
     59                 $count[$j][1]++;
     60             }else if(($train[$i][$num]==$attributename[$j])&&($train[$i][count($train[$i])-1]==$flagsno)){
     61                 $count[$j][2]++;
     62             }
     63         }
     64     }
     65     
     66     $num_yes = 0;//类别为$flagsyes的个数
     67     $num_no = 0;//类别为$flagsno的个数
     68     for($i=1;$i<count($train);$i++)
     69     {
     70         if($train[$i][count($train[$i])-1]==$flagsyes)
     71         {
     72             $num_yes++;
     73         }else {
     74             $num_no++;
     75         }
     76     }
     77 
     78     //分类所需要的 信息量
     79     $I=0;
     80     $s[0] = $num_yes;
     81     $s[1] = $num_no ;
     82     for($i=0;$i<2;$i++)
     83     {
     84         if($s[$i]!=0)$I += -$s[$i] / ($num_yes+$num_no) * log($s[$i]/($num_yes+$num_no)) / log(2);
     85     }
     86     
     87     $EA = 0 ;
     88     for($i=0;$i<count($count);$i++)
     89     {
     90         $si = 0;
     91         for($j=1;$j<count($count[$i]);$j++)
     92         {
     93             if($count[$i][$j]!=0)$si += -$count[$i][$j] / ($count[$i][1]+$count[$i][2]) * log($count[$i][$j]/($count[$i][1]+$count[$i][2])) / log(2);
     94         }
     95         $EA += ($count[$i][1]+$count[$i][2])/($num_yes+$num_no) * $si;
     96     }
     97     
     98     //信息增益Gain
     99     $Gain = $I - $EA;
    100     return $Gain;
    101 }
    102 //--------------------------------------------------------------------
    103 
    104 /*
    105 
    106 *求几个属性信息增益最大的那一个
    107 
    108 */
    109 
    110 //--------------------------------------------------------------------
    111 function Attributelist($train,$flagsyes,$flagsno)
    112 {
    113     $array_attribute_grain = array(array(NULL,NULL));//存放属性值以及属性值对应的信息增益
    114     for($i=1;$i<count($train[0])-1;$i++)
    115     {
    116         $array_attribute_grain[$i-1][0] = $train[0][$i];
    117         $array_attribute_grain[$i-1][1] = Grain($train,$train[0][$i],$flagsyes,$flagsno);
    118     }
    119     
    120     for($i=1;$i<count($array_attribute_grain);$i++)
    121     {
    122         if($array_attribute_grain[$i][1]>$array_attribute_grain[0][1])
    123         {
    124             $array_attribute_grain[0][0] = $array_attribute_grain[$i][0];
    125             $array_attribute_grain[0][1] = $array_attribute_grain[$i][1];    
    126         }
    127         
    128     }
    129 /*    
    130     echo "<pre>";
    131     print_r($array_attribute_grain[0]);
    132     echo "<pre>";
    133 */
    134     return $array_attribute_grain[0];
    135 }
    136 //--------------------------------------------------------------------
    137 
    138 /*
    139 
    140 *构建ID3决策树(数组存储)
    141 
    142 */
    143 
    144 //--------------------------------------------------------------------
    145 function DecisionTree($train,$flagsyes,$flagsno,&$array_tree)
    146 {
    147     $flags = true;
    148 /*
    149 *if所有样本均为同一类别C,返回N作为一个椰子结点并标志为C类别
    150 */
    151     $num_yes = 0;//用于统计同一$flagsyes类别的数目
    152     $num_no = 0;//用于统计同一$flagsno类别的数目
    153     for($i=1;$i<count($train);$i++)
    154     {
    155         if($train[$i][count($train[$i])-1]==$flagsyes) $num_yes++;
    156         else if($train[$i][count($train[$i])-1]==$flagsno) $num_no++;
    157     }
    158 
    159     
    160     if($num_yes==(count($train)-1))//所有样本均为同一类别
    161     {
    162         array_push($array_tree,array($flagsyes));
    163         $count++;
    164         $flags = false;
    165     }else if($num_no==(count($train)-1)){
    166         array_push($array_tree,array($flagsno));
    167         $count++;
    168         $flags = false;
    169     }
    170     
    171 
    172 /*
    173 
    174 *else if attribute /为空,则返回n作为一个叶子节点,并标记为该节点所含样本中类别最多的类别
    175     
    176 */
    177     if($flags)
    178     {
    179         $num_attribute = count($train)-2;
    180         if($num_attribute==0)
    181         {
    182             if($num_yes>$num_no)
    183             {
    184                 array_push($array_tree,array($flagsyes));
    185                 $count++;
    186                 $flags = false;
    187             }else {
    188                  array_push($array_tree,array($flagsno));
    189                  $count++;
    190                  $flags = false;
    191             }
    192             
    193         }
    194     }
    195 /*
    196 
    197 *从样本中选择分类能力最好的的属性
    198  
    199 */
    200     if($flags)
    201     {
    202         $attribute = Attributelist($train,$flagsyes,$flagsno);
    203 
    204         $attribute_name = array(NULL);
    205         array_splice($attribute_name,0,1);
    206         for($i=1;$i<count($train[0])-1;$i++)
    207         {
    208             if($train[0][$i]==$attribute[0])
    209             {
    210                 $num = $i;
    211                 break;
    212             }
    213         }
    214         for($i=1;$i<count($train);$i++)
    215         {
    216             $flags2 = true;
    217             for($j=0;$j<count($attribute_name);$j++)
    218             {
    219                 if($train[$i][$num]==$attribute_name[$j])
    220                 {
    221                     $flags2 = false;
    222                     break;
    223                 }    
    224             }
    225             if($flags2)array_push($attribute_name,$train[$i][$num]);
    226         }
    227         //print_r($attribute_name);
    228         $array_new = array(NULL);
    229         array_splice($array_new,0,1);
    230         for($i=0;$i<count($attribute_name);$i++)
    231         {
    232             $arraybranch = array(array());
    233             array_splice($arraybranch,0,1);
    234             $arraytemp = array(NULL);
    235             array_splice($arraytemp,0,1);
    236             array_push($arraybranch,$train[0]);
    237             for($j=1;$j<count($train);$j++)
    238             {
    239                 if($train[$j][$num]==$attribute_name[$i])
    240                 {
    241                     array_push($arraybranch,$train[$j]);
    242                 }
    243             }
    244             for($j=0;$j<count($arraybranch);$j++)
    245             {
    246                 array_splice($arraybranch[$j],$num,1);
    247             }
    248             array_push($array_new,$arraybranch);    
    249             $num_branch_yes = 0;
    250             $num_branch_no =0;
    251             for($j=1;$j<count($arraybranch);$j++)
    252             {
    253                 if($arraybranch[$j][count($arraybranch[$j])-1]==$flagsyes) $num_branch_yes++;
    254                 else $num_branch_no++;
    255             }
    256             if($num_branch_yes==count($arraybranch)-1)array_push($array_tree,array($attribute[0],$attribute_name[$i],$flagsyes));
    257             else if($num_branch_no==count($arraybranch)-1)array_push($array_tree,array($attribute[0],$attribute_name[$i],$flagsno));
    258             else {
    259                 $temp = Attributelist($arraybranch,$flagsyes,$flagsno);
    260                 array_push($array_tree,array($attribute[0],$attribute_name[$i],$temp[0]));
    261                 DecisionTree($arraybranch,$flagsyes,$flagsno,$array_tree,$count);
    262             }
    263             
    264         }    
    265     }
    266 /*
    267     echo "<pre>";
    268     print_r($array_tree);
    269     echo "<pre>";
    270     //print_r("<br>".$count);
    271 */
    272     return $array_tree;
    273     
    274 }
    275 //--------------------------------------------------------------------
    276 
    277 /*
    278 
    279 *判断一个测试样本的类别
    280 
    281 */
    282 //--------------------------------------------------------------------
    283 function ID3_Judge($test,$co,$decisiontree,$flagsyes,$flagsno)
    284 {
    285     //找寻根节点
    286     $boot = $decisiontree[0][0];
    287     for($i=1;$i<count($test[0])-1;$i++)
    288     {
    289         if($boot==$test[0][$i])
    290         {
    291             $num = $i;
    292             break;
    293         }
    294     }
    295     for($i=0;$i<count($decisiontree);$i++)
    296     {
    297         if(($decisiontree[$i][0]==$boot)&&($decisiontree[$i][1]==$test[$co][$num]))
    298         {
    299             if($decisiontree[$i][2]==$flagsyes)
    300             {
    301                 $result =  $flagsyes;
    302             }else if($decisiontree[$i][2]==$flagsno){
    303                 $result =  $flagsno;
    304             }else{
    305                 $attributename = $decisiontree[$i][2];
    306                 $mid = $i;
    307             }
    308         }
    309     }
    310     while($attributename!=NULL)
    311     {
    312         $boot = $attributename;
    313         for($i=1;$i<count($test[0])-1;$i++)
    314         {
    315             if($boot==$test[0][$i])
    316             {
    317                 $num = $i;
    318                 break;
    319             }
    320         }
    321         
    322         for($i=$mid;$i<count($decisiontree);$i++)
    323         {
    324             if(($decisiontree[$i][0]==$boot)&&($decisiontree[$i][1]==$test[$co][$num]))
    325             {
    326                 if($decisiontree[$i][2]==$flagsyes)
    327                 {
    328                     $attributename = NULL;
    329                     $result =  $flagsyes;
    330                 }else if($decisiontree[$i][2]==$flagsno){
    331                     $attributename = NULL;
    332                     $result =  $flagsno;
    333                 }else{
    334                     $attributename = $decisiontree[$i][2];
    335                     $mid = $i;
    336                 }
    337             }
    338         }
    339     }
    340     return $result;
    341 }
    342 //--------------------------------------------------------------------
    343 
    344 /*
    345 *把.txt中的内容读到数组中保存
    346 *$filename:文件名称
    347 */
    348 
    349 //--------------------------------------------------------------------
    350 function gerFileContent($filename)
    351 {
    352     $array = array(NULL);
    353     $content = file_get_contents($filename);
    354     $result = explode("
    ",$content);
    355     
    356     for($j=0;$j<count($result);$j++)
    357     {
    358         $con = explode(" ",$result[$j]);
    359         array_push($array,$con);
    360     }
    361     array_splice($array,0,1);
    362     return $array;
    363 }
    364 //--------------------------------------------------------------------
    365 $train = gerFileContent("train.txt");
    366 $test = gerFileContent("test.txt");
    367 
    368 $array_tree = array(array(NULL,NULL,NULL));
    369 array_splice($array_tree,0,1);
    370 $decisiontree = DecisionTree($train,Y,N,$array_tree);
    371 
    372 for($i=1;$i<count($test);$i++)
    373 {
    374     $test[$i][count($test[0])-1] = ID3_Judge($test,$i,$decisiontree,Y,N);
    375 }
    376 
    377 /*
    378 
    379 *将数组中的内容读到.txt中
    380 
    381 */
    382 //--------------------------------------------------------------------
    383 $fp= fopen('result.txt','wb');
    384 for($i=0;$i<count($test);$i++)
    385 {
    386     $temp = NULL;
    387     for($j=0;$j<count($test[$i]);$j++)
    388     {
    389         $temp =  $test[$i][$j]."	";
    390         fwrite($fp,$temp);
    391     }
    392     fwrite($fp,"
    ");
    393 }
    394 fclose($fp);
    395 //--------------------------------------------------------------------
    396 
    397 /*
    398 *打印输出决策树
    399 */
    400 //--------------------------------------------------------------------
    401 echo "<pre>";
    402 print_r($decisiontree);
    403 echo "<pre>";
    404 //--------------------------------------------------------------------
    405 
    406 /*
    407 *打印输出
    408 */
    409 //--------------------------------------------------------------------
    410 echo "<pre>";
    411 print_r($test);
    412 echo "</pre>";
    413 //--------------------------------------------------------------------
    414 ?>

  • 相关阅读:
    vmware中3中网络模式的区别
    常用 Git 命令清单 转
    inotify监控目录变化重启服务器tornado项目
    sed处理url编码解码=== web日志的url处理
    LVM 'Can’t open /dev/sdb1 exclusively. Mounted filesystem?' Problem
    Vimium使用快捷键总结
    sed 引入shell变量
    shell 除法 小数点
    selinux 导致无法启动httpd
    linux查看ssh用户登录日志与操作日志
  • 原文地址:https://www.cnblogs.com/minmsy/p/4972402.html
Copyright © 2011-2022 走看看