机器学习之旅---logistic回归

一、logistic回归分析简介

    logistic回归是研究观察结果(因变量)为二分类或多分类时,与影响因素(自变量)之间关系的一种多变量分析方法,属于概率型非线性回归。

    利用logistic回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。这里“回归”是指通过最优化方法找到最佳拟合参数集,作为分类边界线的方程系数。通过分类边界线进行分类,具体说来就是将每个测试集上的特征向量乘以回归系数(即最佳拟合参数),再将结果求和,最后输入到logistic函数(也叫sigmoid函数),根据sigmoid函数值与阈值的关系,进行分类。也就是说logistic分类器是由一组权值系数组成,最关键的问题就是如何求得这组权值。

    在流行病学研究中,logistic回归常用于分析疾病与各种危险因素间的定量关系。这次将利用logistic回归预测病马的死亡率,病马样本有368个,每个样本有21个特征点,即21种危险因素。接下来,本文首先介绍利用梯度上升法及改进的随机梯度上升法寻找最佳回归系数,然后用matlab实现基于logistic回归的病马死亡率预测。

二、如何寻找最优化参数

1.logistic回归模型

     给定n个特征x=(x1,x2,…,xn),设条件概率P(y=1|x)为观测样本y相对于事件因素x发生的概率,用sigmoid函数表示为:

    

    那么在x条件下y不发生的概率为:

    

    假设现在有m个相互独立的观测事件y=(y1,y2,…,ym),则一个事件yi发生的概率为(yi= 1)

   

   那么现在就成了,已知总体事件Y是服从上述概率密度的连续型随机变量:

     

    由于logistic分类器是由一组权值系数组成的,最关键的问题就是如何获取这组权值。而f(x)中x是由权值向量与特征向量相乘的结果,即g(x)表示,其中特征向量是随机变量,只有向量w是参数,所以权值向量w可以通过极大似然函数估计获得,并且Y~f(x;w)

【回忆一下似然函数的性质】

1.似然函数是统计模型中参数的函数。给定输出x时,关于参数θ的似然函数L(θ|x)(在数值上)等于给定参数θ后变量X的概率:L(θ|x)=P(X=x|θ)

2.似然函数的重要性不是它的取值,而是当参数变化时概率密度函数到底是变大还是变小。对于同一个似然函数,如果存在一个参数值,使得它的函数值得到最大,那么这个值就是最为合理的参数值。

3.极大似然函数:似然函数取得最大值表示相应的参数能够使得统计模型最为合理

 

    那么对于上述m个观测事件,其联合概率密度函数,即似然函数为:

     现在,我们的目标是求出使这一似然函数的值最大的参数估,也就是求出参数w1,w2,…,wn,使得L(w)取得 最大值。对L(w)取对数:

     由于w有n+1个,根据n+1的对wi的偏导数方程求解w比较不靠谱。可以考虑使用牛顿-拉菲森迭代梯度上升方法求解。梯度上升算法和牛顿迭代相比,收敛速度慢,因为梯度上升算法是一阶收敛,而牛顿迭代属于二阶收敛。

2.梯度上升法

    梯度上升法基于的思想是要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻。函数f(x,y)的梯度可以如下表示,前提是函数f(x,y)必须在待计算的点上有定义并且可微。

        

    在梯度上升法中,待计算点沿梯度方向每移动一步,都是朝着函数值增长最快的方向。若移动的步长记作a,则梯度算法的迭代公式如下:

       

    迭代停止条件为:迭代次数达到某个指定的值或者算法达到某个可以允许的误差范围。现在继续对刚才的似然函数进行推到:

其中,

根据梯度上升算法有,

进一步得到,

接下来将根据上述推到,实现一个利用logistic回归得到分类边界的例子,由于不擅长python,我索性用matlab改写了。现在有100个样本点及对应分类标签,每个样本点有2个特征。【文本文件中有100行*3列数据,自己导入matlab,做成*.mat文件即可】

clc;
clear;

load x
load y
load label

[r,c] = size(x);
A = ones(1,r)';
A = [A x y];
L = label;
alpha = 0.001;
maxCycles = 500;
weights = ones(1,3)';

for k=1:1:maxCycles
    h = sigmoid(A*weights,r);
    error = (L - h);
    weights = weights + alpha * A' * error;
end

%%画图
for k = 1:1:r
    hold on
    if L(k,1) == 1
        plot(A(k,2),A(k,3),'r+');
    else
        plot(A(k,2),A(k,3),'b*');
    end
end

%%画分割线
hold on
dx = -3:3;
dy = (-weights(1)-weights(2)*dx)/weights(3);
plot(dx,dy,'k-','lineWidth',3);

function result = sigmoid(inX,r)
    result = [];
    for k = 1:1:r
        result(k,1) = 1.0 / (1 + exp(-inX(k,1)));
    end
end

分类边界:

注:为了方便计算,这里为每个样本点新增一列特征X0,都为1.0,否则分类边界将过零点,不准确了。

分界线的方程: w0 * x0 + w1 * x1 + w2 * x2 = 0

3.改进的梯度上升法

    梯度上升法在每次更新回归系数时都需要遍历整个数据集,该方法在处理100个左右数据集时效率尚可,但如果有10亿样本和成千上万的特征,那么这个方法的计算量就太大了。改进方法是一次仅用一个点来更新回归系数。它是一种在线学习算法【即:可以在新的样本到来时对分类器进行增量式更新。】,每一次处理的数据的操作被称为“批处理”

clc;
clear;

load x
load y
load label

[r,c] = size(x);
A = ones(1,r)';
A = [A x y];
L = label;
alpha = 0.01;
weights = ones(1,3)';

for k = 1:1:r
    h = sigmoid2(sum(A(k,:,:)*weights));
    error = L(k) - h;
    weights = weights + alpha * error * A(k,:,:)';
end

%%画图
for k = 1:1:r
    hold on
    if L(k,1) == 1
        plot(A(k,2),A(k,3),'r+');
    else
        plot(A(k,2),A(k,3),'b*');
    end
end

%%画分割线
hold on
figure(1);
dx = -3:3;
dy = (-weights(1)-weights(2)*dx)/weights(3);
plot(dx,dy,'k-','lineWidth',3);

%画各种迭代次数
figure(2);
weights = ones(1,3)';
for j=1:1:200
    for k = 1:1:r
        h = sigmoid2(sum(A(k,:,:)*weights));
        error = L(k) - h;
        weights = weights + alpha * error * A(k,:,:)';
    end
    hold on
    subplot(3,1,1);
    %axis([1 2000 -3 1]);
    plot(j,weights(1),'r.');
    hold on
    subplot(3,1,2);
    plot(j,weights(2),'b.');
    hold on
    subplot(3,1,3);
    plot(j,weights(3),'k.');
end

function result = sigmoid2(inX)
   result = 1.0 / (1 + exp(-inX));
end

分类边界:

从上图结果来看,分类器错分的样本点很多。原因是,梯度上升法的分类边界是在整个数据集上经过500次迭代得到的。目前改进的梯度上升法,没有迭代。

此外,一个判断优化算法优劣的可靠方法是看它是否收敛,也就是说参数是否达到了稳定值,是否还会不断变化。现在让随机梯度法在数据集上运行200次,得到下图:

200次迭代过程中,3个参数的收敛情况:从上到下分别对应w0,w1,w2【不知道书上的图是怎么画的,反正我这边是这样的】

产生上述波动的原因,是存在一些不能正确分类的样本点【数据集并非线性可分】,在每次迭代时会引发数据的变化。下面将通过随机梯度法,来避免波动,从而收敛到某个值,并加快收敛速度。

4.随机梯度上升法

改进有两个地方:

。alpha在每次迭代的时候都会调整,alpha的值是不断变小的,但永远不能减小到零,保证在多次迭代之后,新数据仍然有一定的影响。

。通过随机选取样本来更新回归系数,另外增加了一个迭代次数参数。

clc;
clear;

load x
load y
load label

[r,c] = size(x);
A = ones(1,r)';
A = [A x y];
L = label;
weights = ones(1,3)';

figure(1);
tmp = [];
for j = 1:1:200
    for k = 1:1:r
        alpha = 4/(j+k+1) + 0.01;
        index = floor(random('unif',1,r,1,1));
%         k = find(tmp == index);
%         if isempty(k)
%             tmp = [tmp index];
%         else
%             continue;
%         end
        h = sigmoid2(sum(A(index,:)*weights));
        error = L(index) - h;
        weights = weights + alpha * error * A(index,:)';
    end
    hold on
    subplot(3,1,1);
    %axis([1 2000 -3 1]);
    plot(j,weights(1),'r.');
    hold on
    subplot(3,1,2);
    plot(j,weights(2),'b.');
    hold on
    subplot(3,1,3);
    plot(j,weights(3),'k.');
end

%%画图
figure(2);
for k = 1:1:r
    hold on
    if L(k,1) == 1
        plot(A(k,2),A(k,3),'r+');
    else
        plot(A(k,2),A(k,3),'b*');
    end
end

%%画分割线
hold on
dx = -3:3;
dy = (-weights(1)-weights(2)*dx)/weights(3);
plot(dx,dy,'k-','lineWidth',3);
function result = sigmoid2(inX)
   result = 1.0 / (1 + exp(-inX));
end

这边我很质疑《机器学习python实战》书上的描述和截图,首先我根本没看见之前算法的周期性波动和高频,反而在随机算法中看到了。【他坐标轴axis改动过】

另外一个,就是每次随机选取样本后,要从样本里踢出的,我这么改了,收敛速度的确快了很多,但是,分类边界线错误没有改变很多。所以我不踢出了

分类边界线:

各个参数的迭代结果:【只有w0是收敛比较快的,w1,w2收敛了嘛?】

这种随机梯度算法相比第一种梯度上升法的计算量:第一种要500次循环,每次300次乘法,现在是200次循环,每次3次乘法1次加法,从矩阵的运算变成值的运算。运算量的确减少了。

三、病马预测实例

368个样本,21个特征点,选300个作为训练用,68个作为测试

书中扯到数据丢失的处理问题,我看了下文本数据,他都弄好了,不要我们自己处理了。

大概意思就是:特征点丢失,用0代替;类标签丢失,整条记录舍弃。所以只剩299个样本做训练,67个作为测试样本了。

现在将完整展示,如何通过logistic回归进行分类预测:

clc;
clear;

load train
load test

[r,c] = size(test);
T_data = train(:,1:21);
T_lab = train(:,22);

P_data = test(:,1:21);
P_lab = test(:,22);

%训练
weights = train_weights(T_data,T_lab,500);

%预测
% fuck = 0;
% for shit = 1:1:10
    err_count = 0;
    for k=1:1:r
        predict = my_classify(P_data,weights);
        if predict ~= P_lab(k)
            err_count = err_count + 1;
        end
    end
    err_rate = err_count / r;
    disp('the error rate of this test is :');
    err_rate
%     fuck = fuck + err_rate;
% end
% disp('the average error rate of 10 time test is:');
% fuck/10

function weights = train_weights(Data,Lab,iter)
    [r,c] = size(Data);
    weights = ones(1,c)';

    for j = 1:1:iter
        for k = 1:1:r
            alpha = 4/(j+k+1) + 0.01;
            ctime = datestr(now, 30);%取系统时间
            tseed = str2num(ctime((end - 5) : end)) ;%将时间字符转换为数字
            rand('seed', tseed) ;%设置种子,若不设置种子则可取到伪随机数
            index = randint(1,1,r) + 1;
            h = sigmoid2(sum(Data(index,:)*weights));
            error = Lab(index) - h;
            weights = weights + alpha * error * Data(index,:)';
        end
    end
end

function result = sigmoid2(inX)
   result = 1.0 / (1 + exp(-inX));
end

function result = my_classify(Data, weights)
    prob = sigmoid(sum(Data*weights));
    if prob > 0.5
        result = 1;
    else
        result = 0;
    end
end

function a = sigmoid(inX)
    a = 1.0 / (1 + exp(-inX));
end

比较蛋疼的问题是,每次跑matlab,随机数都一样。。。我已经把系统时间当seed了啊。。。

今天就写到这里吧。谁能解决matlab随机数问题的,可以留言。

时间: 2024-11-01 12:36:19

机器学习之旅---logistic回归的相关文章

logistic回归算法及其matlib实现

     一般来说,回归不用在分类问题上,因为回归是连续型模型,而且受噪声影响比较大.如果非要使用回归算法,可以使用logistic回归.      logistic回归本质上是线性回归,只是在特征到结果的映射中多加入了一层函数映射,即先把特征线性求和,然后使用函数g(z)作为假设函数来预测,g(z)可以将连续值映射到0和1上.      logistic回归的假设函数如下,线性回归假设函数只是\(\theta^Tx\). \[h_\theta(x)=g(\theta^Tx)=\frac{1}{

数据挖掘-Logistic回归数据预处理问题

问题描述 Logistic回归数据预处理问题 我在做一个新闻数据集的分类,用Logistic回归模型.(数据集来源:http://archive.ics.uci.edu/ml/datasets/Online+News+Popularity) 这个数据集中的数据类型比较杂,有离散的数据也有连续的,有些范围在1以内,有些可以达到几十万,请问对这样的数据可以采用一些什么样的方法预处理,使之适用于Logistic回归? 解决方案 分类数据之logistic回归Logistic 回归Logistic回归p

6、spss做logistic回归

前边我们用两篇笔记讨论了线性回归的内容.线性回归是很重要的一种回归方法,但是线性回归只适用于因变量为连续型变量的情况,那如果因变量为分类变量呢?比方说我们想预测某个病人会不会痊愈,顾客会不会购买产品,等等,这时候我们就要用到logistic回归分析了. Logistic回归主要分为三类,一种是因变量为二分类得logistic回归,这种回归叫做二项logistic回归,一种是因变量为无序多分类得logistic回归,比如倾向于选择哪种产品,这种回归叫做多项logistic回归.还有一种是因变量为有

TensorFlow训练Logistic回归

Logistic回归 在用线性模型进行回归训练时,有时需要根据这个线性模型进行分类,则要找到一个单调可微的用于分类的函数将线性回归模型的预测值关联起来.这时就要用到逻辑回归,之前看吴军博士的<数学之美>中说腾讯和谷歌广告都有使用logistics回归算法. 如下图,可以清晰看到线性回归和逻辑回归的关系,一个线性方程被逻辑方程归一化后就成了逻辑回归.. Logistic模型 对于二分类,输出y∈{0,1},假如线性回归模型为z=θTx,则要将z转成y,即y=g(z).于是最直接的方式是用单位阶跃

logistic回归

回归就是对已知公式的未知参数进行估计.比如已知公式是y=a∗x+by=a∗x+b,未知参数是a和b,利用多真实的(x,y)训练数据对a和b的取值去自动估计.估计的方法是在给定训练样本点和已知的公式后,对于一个或多个未知参数,机器会自动枚举参数的所有可能取值,直到找到那个最符合样本点分布的参数(或参数组合). logistic分布 设X是连续随机变量,X服从logistic分布是指X具有下列分布函数和密度函数: F(x)=P(x≤x)=11+e−(x−μ)/γ f(x)=F′(x)=e−(x−μ)

MachineLearning之Logistic回归

一.概述 假设现在有一些数据点,我们用一条直线对这些点进行拟合(该线称为最佳拟合直线),这个拟合过程就称为回归: 利用Logistic回归进行分类的主要思想是: 根据现有数据对分类边界线建立回归公式, 以此进行分类. 这里的"回归"一词源于最佳拟合, 表示要找到最佳拟合参数集, 其背后的数学分析将在下一部分介绍. 训练分类器时的做法就是寻找最佳拟合参数, 使用的是最优化算法. 二.基于Logistic回归和Sigmoid函数的分类  单位阶跃函数也称海维赛德阶跃函数(Heaviside

Logistic 回归

Logistic 回归:从入门到进阶(之一) --如何理解Logistic回归 我们在做统计分析之前,往往会做个散点图,以对数据有直观的了解.今天,我们就从散点图入手,来探究Logistic回归的奥秘. 如下,分别是连续型因变量和二分类因变量的散点图.很直观的,我们会想到用一条直线来代表左图中两个变量的关系.那么右图中,用一条什么样的线来代表呢? 如下,左图可以完美地拟合出一条直线:而右图如果绘制成S型曲线,意义就与左图有所不同了. 右图的纵轴已经换成了P值.所以右图曲线上的点,代表的就是在对应

谁在人肉搜索?——网络人肉搜索主体的Logistic回归模型分析

本文发表于<广告大观(理论版)>2010年02期,主要使用SPSS软件对一份包含5758个样本的数据进行Logistic回归分析,考察网络人肉搜索参与主体的人口统计特征.基本网络使用情况以及具体的网络参与行为对其参与人肉搜索的影响程度.研究发现23-27岁的男性低收入群体.经常参与网络口水战的人.在网络上爱说谎的人.网络发言是为了发泄情绪的人.网络发言为了引起别人注意的人.更愿意讨论陌生人的私人话题的人.在网络和现实中表现不一的人更容易参与人肉搜索.而且是否参与人肉搜索与网龄和每天上网时间相关

360“旅美”回归 借壳概念股迎风涨

7月18日,奇虎360正式从纽交所摘牌,结束五年多的美股之旅.这距离其宣布收到私有化要约正好一年零一个月的时间. 一旦大幅溢价登陆A股市场,360概念股将直接受益. 提前一月完成私有化 2015年6月17日,奇虎360宣布收到初步非约束性私有化要约,买方集团包括360董事长周鸿祎.中信证券.华兴资本和红杉资本,计划以每股ADS77美元现金收购:2016年6月28日,360在公布私有化最新进展时预计交易将在今年8月中旬完成,如今整整提前一个月落地. 虽然奇虎360在宣布私有化之后不免经历一番股价下