决策树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("\r\n",$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]."\t";
390         fwrite($fp,$temp);
391     }
392     fwrite($fp,"\r\n");
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 ?>

posted @ 2015-11-17 17:42  指间ゝ繁华初逝的格调  阅读(524)  评论(0编辑  收藏  举报