机器学习(周志华) 参考答案 第四章 决策树 4.5

时间:2023-02-12 23:45:02

机器学习(周志华) 参考答案 第四章 决策树 4.5

机器学习(周志华西瓜书) 参考答案 总目录

机器学习(周志华) 参考答案 第四章 决策树


5.试编程实现基于对率回归进行划分选择的决策树算法,并为表4.3中数据生成一棵决策树。

    这个题,真不知道如何下手,只能往简单想了

用对率回归来选择最优划分,第三章对率回归是用在连续数据上的,我也不知道能不能扩展到离散数据,反正百度了一下也没什么反应。
这道题我用的方法是值使用两个连续的属性,对每个属性分别做对率回归,找到每个属性的最优划分,然后划分完后看划分后的错误,错的最少的就是最优的划分。

这是对西瓜3.0连续数据的划分,离散变量要划分到0训练错误层数真多
机器学习(周志华) 参考答案 第四章 决策树 4.5

程序主体也稍微修改下,就是对数据的读入,以及需要手动设置的属性参数上(pu,pt,pf)。
TreeGenerate递归不用该,只需把entropy_paraselect改成logre_paraselect。

程序主体需要改动的地方

x = xlsread('C:\Users\icefire\Desktop\ml\西瓜3.xlsx', 'sheet1', 'A7:Q8');
y = xlsread('C:\Users\icefire\Desktop\ml\西瓜3.xlsx', 'sheet1', 'A9:Q9');

pf=[1 2];
pu=[1 1];
pt=[3 3];

代码是对3章的对率回归稍微修改,主体还是没变的,这里不再贴TreeGenerate代码了,详情请看4.3

%对率回归用不着pf和pu
%{
对率回归选择(只能处理连续变量)
    curset:当前样本集合
    pf:当前属性的编号
    pu:当前属性是连续还是离散的0-离散 1-连续
输出
    n:最优属性
    threshold:连续属性返回阀值
%}
function [n, threshold] = logre_paraselect(curset,pf,pu)
global x y; 

    curx = x(:,curset);
    cury = y(curset);
    cury=cury-1;    %对率回归处理0,1
    [km, kn] = size(curx);
    err=kn;
    %每次只对一个属性做对率回归,求出最佳划分
    for j=1:km
        %对率回归代码 稍微改动
        old_l=0;    %记录上次计算的l
        n=0;    %计算迭代次数
        b=[0;1];  %初始参数 (自定义)
           while(1)
           cur_l=0;
           bx=zeros(kn,1);
           tx=[curx(j,:) ;ones(1,kn)];
           %计算当前参数下的l
           for i=1:kn
                bx(i) = b.'*tx(:,i);
                cur_l = cur_l + ((-cury(i)*bx(i)) )+log(1+exp(bx(i)));
           end

           %迭代终止条件
           if abs(cur_l-old_l)<0.001  
               break;
           end

           %更新参数(牛顿迭代法)以及保存当前l
           n=n+1;
           old_l = cur_l;
           p1=zeros(kn,1);
           dl=0;
           d2l=0;

           for i=1:kn
                p1(i) = 1 - 1/(1+exp(bx(i)));
                dl = dl - tx(:,i)*(cury(i)-p1(i));
                d2l = d2l + tx(:,i) * tx(:,i).'*p1(i)*(1-p1(i)); end b = b - d2l\dl; end %对每个划分计算分类错误率 选择错误率低的作为最优属性 wx+b最接近0的两个x的均值作为阀值 min_res=1000; smin_res=1000; cur_threshold=0; err0=0; for i=1:kn res = tx(1,i)*b(1)+b(2); if((res>=0)~=cury(i)) err0 = err0 +1; end if(abs(res)<abs(min_res)) cur_threshold2=cur_threshold; cur_threshold=tx(1,i); smin_res = min_res; min_res = res; elseif (abs(res)<abs(smin_res)) cur_threshold2=tx(1,i); smin_res =res; end end if(err0 < err) n=j; threshold=(cur_threshold+cur_threshold2)/2; end end end