吴恩达第二集笔记——局部加权回归和logistic回归

1.局部线性加权回归本质

就是在普通线性回归函数推导过程中的J(theta)每一项前面加一个权值,一般是如下的函数

所以想要预测的点(x的值)不同,回归函数就不一样,相当于根据预测点,离预测点较近的样本权值就大,离预测点远的样本权值就小。

 

2.线性回归和logistic回归比较

其实logistic回归的本质就是线性回归,解释如下:

回归函数模型:

è¿éåå¾çæè¿°

其中x0,x1......xn表示的是不同的影响因素,也就是不同的自变量,比如f(x)是预测房价的话,影响房价的可能是地段,面积等因素,就是不同的自变量。

sigmoid函数:

logistic回归模型的预测函数

也就是广义的线性回归函数

3.logistic回归模型推导

注1:P(y=1|X;θ)表示在X变量为某个值的条件下,θ为参数的情况下y=1的概率大小。

这里直接假设概率大小就为hθ(X),一方面是因为sigmoid函数刚好在0-1之间,并且比较符合要求,

最后一项中X^{_{J}^{(i)}}中可以把j忽视去理解。

 

 

用logistic回归解决的是分类问题,也就是将数据分成两类,而sigmoid函数图像如上所示,当X远远大于0或者小于0时,一定是1类或者0类,而在0附近时,可能是1类,可能是0类,这就有一个0-1的概率,我们可以假定当概率小于0.5,就归为0类,当概率大于等于0.5就归为1类。现在使用最小似然法,让已发生的样本的概率最大,来求出参数。所以假设hθ(X)为概率值。

Python代码演示

import numpy as np
import matplotlib.pyplot as plt
 
# 读取文本数据,返回数据集和目标值
def loadDataSet():
    dataMat = []
    labelMat = []
    fr = open('testSet.txt')
    for line in fr.readlines():
        lineArr = line.strip().split()#strip()指示移除首尾的空格,并不会改变字符串中间的值,比如有个字符串是'     -0.017612 14.053064 0    ',经过strip()后为'-0.017612 14.053064 0'
        # 将字符串按默认的空格切分成一个字符串列表
        # 该数据集中,添加了一列并初始化为1,便于后续的计算,但是在其他数据集中,一般没有必要添加
        dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])
        labelMat.append(int(lineArr[2]))
    return dataMat,labelMat
 
# 运算的核心函数Sigmoid
def sigmoid(inX):
    return 1.0 / (1+np.exp(-inX))
 
# 核心函数alpha*gradient更新回归系数
def gradAscent(dataMatIn, classLabels):
    # 为了便于计算,mat将两个列表数据转换为numpy的数组
    dataMatrix = np.mat(dataMatIn)# 每一组坐标存储到dataMatrix矩阵中,所以dataMatrix是一个3列多行的矩阵,其中第一行都是1,是因为常数项为1,这个可以参考梯度下降法
    labelMat = np.mat(classLabels).transpose() # transpose矩阵转置,每一组坐标对应的类存储到labelMat矩阵中,所以labelMat矩阵是1列多行
    m,n = np.shape(dataMatrix)#返回dataMatrix的行数和列数
    alpha = 0.001       # 设置步长
    maxCycles = 50000     # 设置循环次数
    weights = np.ones((n,1))    # 初始化每个特征的回归系数为1,weights为theta
    h = sigmoid(dataMatrix*weights)
    error = (labelMat - h) 
    print(alpha * dataMatrix.transpose() * error)
    #h = sigmoid(dataMatrix*weights)
    #error = (labelMat - h)
    #weights = weights + alpha * dataMatrix.transpose() * error
    #while not np.all(np.absolute(error)<=0.6):#这是另外一种判断方法,让所有样本误差都小于0.6,但是这种方法精度不高,由于有一些点的误差是迭代很多次也不能降到0.5以下的,所以建议直接填写迭代次数。
    for k in range(maxCycles):
        # 得到每一行的sigmoid值 (两个相乘得到z值)
        h = sigmoid(dataMatrix*weights)     # 矩阵相乘 sigmoid(sum(每个特征*每个系数)) 行*列,由于是矩阵相乘,所以在相乘时便求和了,就是(theta^T)*X
        # 用一直更新的回归系数求预测值,然后与真实值之间求误差,误差越来越小,则系数更新变化也越来越小,最后趋于稳定
        error = (labelMat - h)              # 每行分类与对应sigmoid相减 误差值越来越小了
        # 数据集转置*误差 每条样本*该样本的误差值
        weights = weights + alpha * dataMatrix.transpose() * error
    return weights

#画图像的函数,可以忽略
def plotBestFit(weights):
    dataMat,labelMat=loadDataSet()
    dataArr = np.array(dataMat)
    n = np.shape(dataArr)[0]
    xcord1 = []; ycord1 = []
    xcord2 = []; ycord2 = []
    for i in range(n):
        if int(labelMat[i])== 1:
            xcord1.append(dataArr[i,1])
            ycord1.append(dataArr[i,2])
        else:
            xcord2.append(dataArr[i,1])
            ycord2.append(dataArr[i,2])
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
    ax.scatter(xcord2, ycord2, s=30, c='green')
    x = np.arange(-3.0, 3.0, 0.1)
    y = (-weights[0]-weights[1]*x)/weights[2]   #由sigmoid=0这个分界点 使用唯一非常量Z 来构造函数
    ax.plot(x, y)
    plt.xlabel('X1')
    plt.ylabel('X2')
    plt.show()
 

 
dataArr,labelMat = loadDataSet()
weights = gradAscent(dataArr,labelMat)
print(weights)
plotBestFit(weights.getA())

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值