Logistic回归----Matlab/Python(1)

  1. 单变量线性回归 (matlab)
  2. 多变量线性回归 (matlab)
  3. 基于Logistic回归和Sigmoid函数的分类 (matlab、python)
  4. 梯度上升法
  5. 改进的梯度上升法
  6. matlab、python实现一个实例

==================================================
1 单变量线性回归

回归与分类的区别: 定量输出为回归,定性输出为分类。
一般的机器学习任务:
输入数据 —–> 模型(hypothesis : h(x)) —–> 输出数据。
在监督学习中,前后都知道,只有模型是我们需要学习的。
我们期望找到一个 h(x) ,对于单变量 一般地: h(x)=θ0+θ1x θ 未知)
对于多变量: h(x)=θ0+θ1x1+....+θnxn (将会在第二节介绍)
目标
找到合适的 θ0 θ1 ,对于给定的样本使 h(x) 尽可能的接近于真是值 y
相应的提出:代价函数: 所有训练样本的误差累积和:

J(θ0,θ1)=12mmi=1(hθ(x)yi)2
注: 前面分目的2是为了 后面求偏导时候的方便。

至此,我们的目标就变为希望 J(θ0,θ1) 越小越好。

求解J的最小值—梯度下降法
基本思路:从确定的参数 θ 开始。不断更改该参数,直到达到最佳的值,或者可接受的范围内。
==================
梯度下降法:
repeat until vonvergence{
θj:=θj+αΔJ(θ0,θ1)
}
Δ 表示梯度
α 表示步长,如果步长太大,优化过程中会发生震荡。如果太小,优化过程国语缓慢。一般地。一般选择0.001 - 0.003
==================
注: 梯度下降一定会达到一个最优值,(不能确定是局部最优,还是全局最优)

两种常见的梯度下降方法:
批量梯度下降法 和 随机梯度下降法
区别: 前者是计算所有样本的误差之和来更新参数,后者每次只需要一个样本来更新参数。
当样本数量过大的时候,前者显然过于缓慢。
这里写图片描述

对于上面的线性回归模型: 批量下降算法
h(x)=θ0+θ1x
J(θ0,θ1)=12mmi=1(hθ(x)yi)2

ΔJθ0=1mmi=1(hθ(x)yi)

ΔJθ0=1mmi=1(hθ(x)yi)xi

随机梯度下降
这里写图片描述

注:同步更新两个参数。

简化算法: 矩阵表示形式
在上面的批量梯度下降算法中,每次更新一个参数都要循环m次。
通过矩阵形式可以简化:
h(x)=θ0+θ1x1=θ0x0+θ1x1
其中 x0=1
这里写图片描述
这里写图片描述
代码实现:
matlab:

function [theta,J] = B_gradientDescent(X,y,alpha,num_iters) 
    %  批量梯度下降法 
    %输入 X:训练数据矩阵 m*n (m个n维训练样本) y: 真实值 m*1   alpha: 步长 
    % num_iters: 迭代次数
    % 输出: theta  参数值  J 代价函数
    [m,n] = size(X);
    J = zeros(num_iters,1) % 存储代价函数
    theta = ones(n,1) %初始值
    for iter = 1:num_iters
        h = X*theta; 
        delta1 = y - h; % 误差 m*1
        delta = repmat(delta1,1,n).*X;  % 注意是点乘
        theta = theta - alpha/m*sum(delta)'  %sum 默认列相加 转置是为了维数一致
        J(V) = (h-y).^2;
        J = 0.5/m*sum(J(v));
    end 
function theta = R_gradientDescent(X,y,alpha)
    % 随机梯度下降 
    [m,n] = size(X);
    theta = ones(n,1) %初始值
    for i=1:m
        h = X(i,:)*theta;
        error = y(i)-h;
        theta = theta - alpha* error * X(i,:)';
    end

多变量线性回归
对于多变量与单变量的原理一样。 在实现中,我们要考虑一个实际问题: 特征归一化
1 均值归一化 (x-min)/(max-min)

funciton x_norm = meanNormalize(X)
    [m,n]=size(x);
    x_norm = zeros(m,n);
    temp0 = repmat(min(x),m,1);
    temp1 = repmat((max(x)-min(x)),m,1)
    x_norm = (x-temp0)./temp1;  

2 Z-score标准化方法 (x-mu)/(标准差)

funciton x_norm = featureNormalize(X)
    [m,n]=size(x);
    x_norm = zeros(m,n);
    mu = zeros(1,n);
    sigma = zeros(1,n);
    mu = mean(x);
    sigma = std(x);
    temp0 = repmat(mu,m,1);
    temp1 = repmat(sigma,m,1)
    x_norm = (x-mu)./temp1;     

多变量线性回归 可以用上面的梯队下降法进行求解,也可以采用Normal equation来求解:
这里写图片描述
该方法中:特征不需要归一化。

实例 房价预测
原始数据: 前两列 为特征,最后一列为房价。
这里写图片描述

clc,clear;
data = load('data.txt');
x = data(:,1:2);
y = data(:,3);
[m,n] = size(x);
x = featureNormalize(x); %归一化
x = [ones(m,1) x]; % 第一列加上1
% 梯度下降 
alpha = 0.001;
num_iters = 500;
[theta,J] = B_gradientDescent(X,y,alpha,num_iters);
% 画出代价函数
figure;
plot(J_history, '-b', 'LineWidth', 2);
xlabel('Number of iterations');
ylabel('Cost J');

% 预测
price = 0; 
x_new=[1650 3];
x_new = featureNormalize(x_new); %归一化
x_new = [ones(m,1) x_new]; % 第一列加上1
price = x_new * theta;
fprintf(['预测房价:\n $%f\n'], price);

基于Logistic回归和Sigmoid函数的分类
利用Logistic回归进行分类的主要思想是: 根据现有数据对分类边界线建立回归公式,以此进行分类。
我们期望的函数是: 能接受所有输入然后预测出类别。最常用的就是sigmoid函数(在两个类的情况下,函数输出0或1)

f(x)=11+ex

本函数特殊之处: f(x)=f(x)(1f(x)) 证明过程简单,这里不介绍。
实现Logistic回归分类器: 可以在每一个特征上都乘上一个回归系数,然后将所有结果相加,最后将总和输入Sigmoid函数,得到0-1之间的数值,大于0.5的分类为1,小于的分类为0。
那么我们的求解过程就变为最佳回归系数的求解(相当于权重)
对于Sigmoid函数的输入Z:

Z=w0x0+w1x1+....+wnxn

注: 上述公式可以用 Z=WTX 向量形式表示 这里的 x0 仍为1

梯度上升法: 找到某函数最大值。
梯度下降法: 找到某函数最小值。
两者唯一区别: 在参数优化过程中, 一个是 +,一个是 -

训练算法: 使用梯度上升法找到最佳参数。
原始数据:
这里写图片描述
前两列为 样例 最后一列为标签。

##Python代码
from numpy import *
def loadData():
    dataMat = []
    labelMat = []
    fr = open('testSet.txt')
    for i in fr.readlines():  # 按行读取 返回列表 list
        line = i.strip().split() # s.strip(rm) s为字符串,rm为要删除的字符序列。 split() 分割后 返回列表  (注a)
        dataMat.append([1.0, float(line[0]), float(line[1])]) # 输入数据矩阵
        labelMat.append(int(line[2]))
    return dataMat, labelMat

def sigmoid(z):
    return 1.0/(1+exp(-z))

def grandAscent(data, label):  # 输入样例和真实标签
    dataMat = mat(data)  # 变换为矩阵数据形式 array是变为数组
    labelMat = mat(label)
    m,n = shape(dataMat) # 相当于 Matlab 的size()
    alpha = 0.001
    iter_num =500
    weights = ones((n,1))  # 生成全为 1 的矩阵
    for i in iter_num:
         h =sigmoid(dataMat * weigths)  # 相当f(x)
         error = labelMat.transpose() - h
         weights = weights + alpha *  dataMat.transpose() * error
        return weights  

(a)这里写图片描述
(b)分析上面的Matlab与Python代码。虽然写法不同但效果相同:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值