信息熵:变量的不确定性越大,熵越大。熵可用下面的公式描述:
-(p1*logp1+p2*logp2+...+pn*logpn)
pi表示事件i发生的概率
ID3:
GAIN(A)=INFO(D)-INFO_A(D)
节点A的信息增益为不加节点A时的信息量INFO(D)-加上A后的信息量INFO_A(D)
算法步骤:
1、树以代表训练样本的某个结点开始
2、如果样本都在同一类,则将该节点设置为叶子,并使用该类标号
3、否则,算法使用熵度量每个样本的分类结点,选择可以获得最大信息的节点
4、所有的属性都是分类的,连续值必须离散化
停止条件:该节点上所有的样本都属于一个类
没有剩余的属性
没有属性时,比如已经分到第三个属性,但是没有第四个属性,这时将样本分到最多的那类
C4.5与ID3区别在于属性度量方式的不同
优点:直观、便于理解、小规模数据有效
缺点:处理连续变量不好
类别较多时,错误增加比较快
可规模性一般 package dTree; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set; public class dataClass {
public static void main(String[] args) {
double [][]exerciseData = {{1,1,0,0},{1,3,1,1},{3,2,1,1},{2,2,1,1},{3,2,1,1},{2,3,0,1},{2,1,0,0},{3,2,0,1},{2,1,0,1},{1,1,1,0}};//每一列表示一个属性值,最后一列表示决策层 int[] index = gainResult(exerciseData);//输出的结果表示按照决策树规则所对应的属性参考顺序
for(int i = 0;i<index.length;i++){
System.out.print(" "+(index[i]+1));
} } private static int[] gainResult(double[][] exerciseData) {
int dataQuantity = exerciseData.length;
int attributeQuantity = exerciseData[0].length-1;
int []attribute = new int[attributeQuantity];
int []newAttribute = new int [attributeQuantity];
double [][]newExerciseData = exerciseData ;
double [][]maxgainIndexData = new double[dataQuantity][attributeQuantity];
for(int i = 0;i<attributeQuantity;i++){
attribute[i] = MaxgainIndex(newExerciseData);
for(int j = 0;j<maxgainIndexData.length;j++){
maxgainIndexData[j][i] = newExerciseData[j][attribute[i]];
}
newExerciseData = NewData(newExerciseData,attribute[i]);
}
boolean flag =true; for(int i = 0;i<maxgainIndexData[0].length;i++){//寻找第i列所对应的exerciseData for(int k = 0;k<exerciseData[0].length-1;k++){
flag = true;
for(int j = 0;j<exerciseData.length;j++){
if(maxgainIndexData[j][i]!=exerciseData[j][k]){
flag = false;
break;
}
}
if(flag==true){
newAttribute[i] = k;
}
}
}
return newAttribute;
} //矩阵转置
private static double[][] Transpose(double[][] exerciseData){ int rows = exerciseData.length;
int columns = exerciseData[0].length;
double [][]newData = new double [columns][rows];
for(int i = 0;i<columns;i++){
for(int j= 0;j<rows;j++){
newData[i][j] = exerciseData[j][i];
}
}
return newData;
} private static double[][] NewData(double[][] exerciseData,int maxIndex) {//删除exerciseData中maxindex列的数据,产生新数据
double [][]newExerciseData = new double[exerciseData.length][];
for(int i = 0;i<exerciseData.length;i++){
newExerciseData[i] = new double[exerciseData[i].length-1];
for(int j = 0;j<newExerciseData[i].length;j++){
if(j>=maxIndex){
newExerciseData[i][j] = exerciseData[i][j+1];
}else{
newExerciseData[i][j] = exerciseData[i][j];
}
}
}
return newExerciseData;
} private static int MaxgainIndex(double[][] exerciseData) {//获取exerciseData最大增益率所对应的一列
double []gainRatio = gainAll(exerciseData);
double maxGain = gainRatio[0];//最大增益率
int maxIndex = 0;//最大增益率所对应的索引值
for(int i=1;i<gainRatio.length-1;i++){
if(maxGain<gainRatio[i]){
maxGain = gainRatio[i];
maxIndex = i;
}
}
return maxIndex;
} public static double[] gainAll(double [][]Data){//得到Data中每一列的增益值
int col = Data.length;//数据个数
int vol = Data[0].length;//属性个数
double [][]count = new double[vol][];
double []info = new double[vol];
double Lcount[][] = new double[vol][];//第i个属性的第j个分类的比率
double Mcount[][] = new double[vol][];
List <List<Map1>>listM = new ArrayList<List<Map1>>();
List <List<Map1>>listM2 = new ArrayList<List<Map1>>();
double []gain;
//矩阵的属性统计
for (int i = 0;i<vol;i++){ //属性i的不重复的分类集(mapList加入了属性i以及对应的决策层的值)
List<Map> mapList = new ArrayList<Map>();
for(int j = 0;j<col;j++){
Map y = new HashMap();
y.put(Data[j][i],Data[j][vol-1]);
if(!mapList.contains(y)){
mapList.add(y);
}
} //属性i全部分类集(重复,listM2加入了i值以及决策层的值)
List<Map> AllmapList = new ArrayList<Map>();
for(int j = 0;j<col;j++){
Map y = new HashMap();
y.put(Data[j][i],Data[j][vol-1]);
AllmapList.add(y);
}
count[i] = new double[mapList.size()];
double sum = 0;
double num = 0;
List<Map1>LM = new ArrayList<Map1>();
for(int j=0;j<mapList.size();j++){
Iterator it =((Map)(mapList.get(j))).keySet().iterator();
num = (Double) it.next();
for(int k = 0;k<AllmapList.size();k++){
if(mapList.get(j).equals(AllmapList.get(k))){
count[i][j] = count[i][j]+1;
}
}
Map1 p = new Map1();
p.setKey(count[i][j]);
p.setValue(num);
LM.add(p);
}
listM2.add(LM);
} for( int k = 0;k<vol;k++){ List <Double>list = new ArrayList<Double>();
for(int i = 0;i<col;i++){
if(!list.contains(Data[i][k])){
list.add(Data[i][k]);
}
} Lcount[k] = new double[list.size()];
Mcount[k] = new double[list.size()];
for(int j = 0;j<col;j++){
int index = list.indexOf(Data[j][k]);
Lcount[k][index] = Lcount[k][index]+1;
Mcount[k][index] = Mcount[k][index]+1;
} double LastSum = 0;
for(int i = 0;i<Lcount[k].length;i++){
LastSum = LastSum+Lcount[k][i];
}
for(int j = 0;j<Lcount[k].length;j++){
Lcount[k][j] = Lcount[k][j]/LastSum;
}
List<Map1> LM = new ArrayList<Map1>();
for(int i = 0;i<Lcount[k].length;i++){
Map1 p = new Map1();
p.setKey(Mcount[k][i]);
p.setValue(list.get(i));
LM.add(p);
}
listM.add(LM);
} gain = new double[listM2.size()];
for(int i = 0; i<listM2.size()-1;i++){
List listi = new ArrayList();
listi = listM.get(i);
double sum = 0;
for(int j=0;j<listi.size();j++){
Map1 p = (Map1) listi.get(j);
double key = p.getKey();
double value = p.getValue(); for(int k = 0;k<listM2.get(i).size();k++){
Map1 p1 = (Map1) listM2.get(i).get(k); if(p1.value==value){
sum = sum+xlog2(p1.key/p.key);
} //System.out.println(sum);
}
gain[i]+=sum*Lcount[i][j];
sum = 0; } }
for(int i = 0;i<Lcount[Lcount.length-1].length;i++){
gain[listM2.size()-1] += -xlog2(Lcount[Lcount.length-1][i]);
}
for(int j = 0;j<gain.length-1;j++){
gain[j] = gain[gain.length-1]+gain[j];
}
double[]Scount = new double [Lcount.length-1];
for(int j= 0;j<Lcount.length-1;j++){
double sum = 0;
for(int k = 0;k<Lcount[j].length;k++){
sum += xlog2(Lcount[j][k]);
}
Scount[j] = -sum;
}
for(int j= 0;j<Scount.length;j++){
gain[j] = gain[j]/Scount[j];
} return gain;
}
public static boolean contain(Map mapList,double key,double value){
if(value==Double.parseDouble(mapList.get(key).toString())){
return true;
}else{
return false;
}
}
public static double xlog2(double x){
return x*(Math.log(x)/Math.log((double)2));
}
}

决策树算法(1)含java源代码的更多相关文章

  1. 决策树算法原理及JAVA实现(ID3)

    0 引言 决策树的目的在于构造一颗树像下面这样的树. 图1 图2 1. 如何构造呢? 1.1   参考资料.       本例以图2为例,并参考了以下资料. (1) http://www.cnblog ...

  2. ID3决策树算法原理及C++实现(其中代码转自别人的博客)

    分类是数据挖掘中十分重要的组成部分.分类作为一种无监督学习方式被广泛的使用. 之前关于"数据挖掘中十大经典算法"中,基于ID3核心思想的分类算法C4.5榜上有名.所以不难看出ID3 ...

  3. 4-Spark高级数据分析-第四章 用决策树算法预测森林植被

    预测是非常困难的,更别提预测未来. 4.1 回归简介 随着现代机器学习和数据科学的出现,我们依旧把从“某些值”预测“另外某个值”的思想称为回归.回归是预测一个数值型数量,比如大小.收入和温度,而分类则 ...

  4. 决策树算法——ID3

    决策树算法是一种有监督的分类学习算法.利用经验数据建立最优分类树,再用分类树预测未知数据. 例子:利用学生上课与作业状态预测考试成绩. 上述例子包含两个可以观测的属性:上课是否认真,作业是否认真,并以 ...

  5. 6个常用Java 源代码 保护工具(混淆、加密、底层)

    6个常用Java 源代码 保护工具(混淆.加密.底层) ProGuard Java源代码保护工具ProGuard的3.6与4.1版  下载地址:http://download.csdn.net/sou ...

  6. scikit-learn决策树算法类库使用小结

    之前对决策树的算法原理做了总结,包括决策树算法原理(上)和决策树算法原理(下).今天就从实践的角度来介绍决策树算法,主要是讲解使用scikit-learn来跑决策树算法,结果的可视化以及一些参数调参的 ...

  7. 分治法解决合并排序(c++和Java源代码)

    Java源代码 public class Mergesort1 { public static void merge(int[]a,int low,int mid,int high){//对两组已经排 ...

  8. java程序保护如何知识产权,特别提供一个java 开发的java 源代码级的混淆器

    java程序保护如何知识产权,特别提供一个java 开发的java 源代码级的混淆器 下载地址:http://yunpan.cn/QXhEcGNYLgwTD 运行方式:java -jar Encryp ...

  9. 《BI那点儿事》Microsoft 决策树算法

    Microsoft 决策树算法是由 Microsoft SQL Server Analysis Services 提供的分类和回归算法,用于对离散和连续属性进行预测性建模.对于离散属性,该算法根据数据 ...

随机推荐

  1. C++多重继承带来的问题

    首先上图,咱们看图说话!   橙色表示变量,使用private修饰. 如图,假设Person类的变量name只能通过input方法来输入. 那么继承自Person的Student及Teacher类中s ...

  2. HA(High available)--Heartbeat高可用性集群(双机热备)菜鸟入门级

    HA(High available)--Heartbeat高可用性集群(双机热备)   1.理解:两台服务器A和B ,当A提供服务,B闲置待命,当A服务宕机,会自动切换至B机器继续提供服务.当主机恢复 ...

  3. gerrit 解决中文乱码相关配置(转载)

    From:http://www.cnblogs.com/Jerryshome/archive/2012/04/19/2457170.html 计划在团队中采用code review,因为一直是用git ...

  4. 算法库:boost安装配置

    前提是电脑上已经装有VS. 1. 下载boost_1_60_0.zip并解压到所需位置 2. 双击bootstrap.bat生成b2.exe(新版)和bjam.exe(老版) 3. 双击b2.exe或 ...

  5. strong reference cycle in block

    However, because the reference is weak, the object that self points to could be deallocated while th ...

  6. linux 多个python版本的切换

    源码安装新的python版本,我的安装路径: /usr/self/Python3.5.2 修改软链接到你所安装的python版本中: 默认python命令是在/usr/bin/目录下 1 sudo m ...

  7. java泛型中的super和extend

    List<? extend Fruit> list=new ArrayList<>();  解释为:集合中元素是继承自Fruit,究竟是何种类型,编译器也无法判定. 如果要从集 ...

  8. json和字符串转换

    json对象转js字符串 JSON.stringify(json) js字符串转json对象 var json= $.parseJSON(str);

  9. 使用Autofac在MVC中实现IOC

    var builder = new ContainerBuilder(); //注册DispatchService类型到工厂中 builder.RegisterType<DispatchServ ...

  10. 窗口 超类化 子类化 HOOK

    body { font-family: Bitstream Vera Sans Mono; font-size: 11pt; line-height: 1.5; } html, body { colo ...