码迷,mamicode.com
首页 > 编程语言 > 详细

决策树ID3算法[分类算法]

时间:2015-11-17 18:56:17      阅读:336      评论:0      收藏:0      [点我收藏+]

标签:

ID3分类算法的编码实现

技术分享

 

技术分享

技术分享

技术分享

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

技术分享技术分享技术分享技术分享

决策树ID3算法[分类算法]

标签:

原文地址:http://www.cnblogs.com/minmsy/p/4972402.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!