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 ?>

  • 相关阅读:
    Python 爬虫js加密破解(一) 爬取今日头条as cp 算法 解密
    Python 爬虫实例(2)—— 爬取今日头条
    Python 爬虫实例(1)—— 爬取百度图片
    python 操作redis之——HyperLogLog (八)
    python 操作redis之——有序集合(sorted set) (七)
    Python操作redis系列之 列表(list) (五)
    Python操作redis系列以 哈希(Hash)命令详解(四)
    Python操作redis字符串(String)详解 (三)
    How to Install MySQL on CentOS 7
    Linux SSH远程文件/目录 传输
  • 原文地址:https://www.cnblogs.com/minmsy/p/4972402.html
Copyright © 2011-2022 走看看