logistic回归+梯度下降算法

logisitic回归

假设现在有一些数据点,我们利用一条直线对这些点进行拟合(该线称为最佳拟合直线),这个拟合过程就称作为回归。我们希望接收所有的输出,然后预测出类别。在两个类别的情况下,输出0,1来代表,这种函数是单位阶跃函数。

sigmoid函数具有该性质:
这里写图片d描述
sigmoid函数公式是:

sigmoid(z)=11+exp(z) s i g m o i d ( z ) = 1 1 + e x p ( − z )

sigmoid函数的性质可以作为分类器,输入为z
z=w0x0+w1x1+...+wnxn z = w 0 ∗ x 0 + w 1 ∗ x 1 + . . . + w n ∗ x n

如果使用向量表示, 输入向量均为列向量:输入z:
z=w⃗ Tx⃗  z = w → T ⋅ x →

n为特征个数。比如下面的例子中,只有两个特征,可以在二维平面上画出并分类。

梯度下降算法

要寻求某个某个函数的最小值,最好的方法是沿着梯度的反方向,即沿着下降速率最快的方向。在Andrew Ng的斯坦佛课堂上,有动态图的演示,方便理解。这种方法,可能会找到局部最优解(local optimum),而不是全局最优解(global optimum)。
假设更新步长是alpha,那么根据梯度下降算法,回归系数可以由下面的式子进行更新:

w:=wαf(w) w := w − α ∗ ∇ f ( w )

在上述更新参数的式子中,是对模型的预测值求梯度,实际上并不需要这样做。可以通过数学推导,可以变化成一种更方便操作的形式。

python实战代码


"""""
Author:
    xinming
Modify:
    2018/02/21
"""
import numpy as np
import matplotlib.pyplot as plt
def load_data_set():
    fo = open('F:\pythonProject\MLIAcode\Ch05/testSet.txt')#注意\t变成了制表符。
    data_mat=[] ;label_mat=[]
    for line in fo.readlines():
        list = line.strip().split()
        data_mat.append([1,float(list[0]),float(list[1])])#w0*x0+w1*x1+w2*x2,x0设为1,w0设为常系数
        label_mat.append(int(list[2])) #需要强制转换数据类型,否则为字符
    return data_mat,label_mat
def sigmoid(x):
    return 1.0/(1+np.exp(-x))
def logistic_reg_grad_descent(data_mat,label_mat):
    data_matrix = np.mat(data_mat) #100行3列
    label_matrix=np.mat(label_mat).transpose() #是行向量故要转置
    m,n=np.shape(data_mat)  #n为特征个数,共有三个:x0,x1,x2
    #print(m,n)
    alpha = 0.001  #定义更新的步长
    weights = np.ones((n,1))#初始化参数为1 3行1列
    max_cycles = 500#书中直接把迭代次数赋值为500
    for k in range(max_cycles):
        h = sigmoid(data_matrix*weights)#hypothesis,预测值
        error=h-label_matrix #m行1列,m组数据
        weights=weights-alpha*data_matrix.transpose()*error #梯度下降的参数更新,可以由求导转化为这种乘积形式
    return weights
def plot_best_fit():
    data_mat,label_mat=load_data_set()
    wei = logistic_reg_grad_descent(data_mat,label_mat) #<class 'numpy.matrixlib.defmatrix.matrix'>
    print(type(wei))
    weights = wei.getA()#<class 'numpy.ndarray'> getA()函数将numpy矩阵转换为数组
    print(type(weights))
    print(weights)
    data_array = np.array(data_mat) #转换为numpy矩阵,方便操作
    n ,m= np.shape(data_array) #矩阵的行数
    x_cor1=[];y_cor1=[]
    x_cor2=[];y_cor2=[]
    for i in range(n):
        if label_mat[i]==1:
           x_cor1.append(data_array[i,1])
           y_cor1.append(data_array[i,2])
        else:
            x_cor2.append(data_array[i,1])
            y_cor2.append(data_array[i,2])
    fig  = plt.figure()
    ax=fig.add_subplot(111)#返回Axes类,并实例化为ax对象
    ax.scatter(x_cor1,y_cor1,c='red',marker='s')#类别为1的设置为红色方块
    ax.scatter(x_cor2,y_cor2,c='green')#类别为0的设置为绿色
    x=np.arange(-3,3,0.1)
    y=(-weights[0]-weights[1]*x)/weights[2]
    ax.plot(x,y)
    plt.show()

最后运行的效果如下:
这里写图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值