标签:
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 ?>
标签:
原文地址:http://www.cnblogs.com/minmsy/p/4972402.html