统计学习方法6_1.逻辑斯蒂回归(logistics回归)

1.逻辑斯蒂回归、逻辑斯蒂分布、对数几率

首先,逻辑斯蒂回归的公式为:
P ( Y = 1 ∣ X ) = e x p ( w ⋅ x ) 1 + e x p ( w ⋅ x ) P(Y=1|X)=\frac{exp(w·x)}{1+exp(w·x)} P(Y=1X)=1+exp(wx)exp(wx)
P ( Y = 0 ∣ X ) = 1 1 + e x p ( w ⋅ x ) P(Y=0|X)=\frac{1}{1+exp(w·x)} P(Y=0X)=1+exp(wx)1

对于输入x,代入上述公式,我们可求出P(Y=1|x)的概率, 0 < = P ( Y = 1 ∣ x ) < = 1 0<=P(Y=1|x)<=1 0<=P(Y=1x)<=1
P ( Y = 1 ∣ x ) P(Y=1|x) P(Y=1x)的公式来源于逻辑斯蒂分布
统计学习方法6_1.逻辑斯蒂回归(logistics回归)_第1张图片统计学习方法6_1.逻辑斯蒂回归(logistics回归)_第2张图片
由此分布可以看出, P ( Y = 1 ∣ x ) P(Y=1|x) P(Y=1x)的公式来与此分布相同,因此其对应的图像与F(x)图像相同。
同时对应的对数几率为 l o g i t ( p ) = l o g P ( Y = 1 ∣ x ) 1 − P ( Y = 1 ∣ x ) = w ⋅ x logit(p)=log\frac{P(Y=1|x)}{1-P(Y=1|x)}=w·x logit(p)=log1P(Y=1x)P(Y=1x)=wx w ⋅ x w·x wx对应的为整个实数域,即通过logit变换可将p对应于整个实数域,即将【0,1】与 w ⋅ x w·x wx一一对应起来,取上述logit的反函数即为 P ( Y = 1 ∣ X ) = e x p ( w ⋅ x ) 1 + e x p ( w ⋅ x ) P(Y=1|X)=\frac{exp(w·x)}{1+exp(w·x)} P(Y=1X)=1+exp(wx)exp(wx)

2.参数求解

而此时的我们可利用极大似然估计对上述参数进行求解,首先似然函数如下图所示
统计学习方法6_1.逻辑斯蒂回归(logistics回归)_第3张图片然后我们需要做的就是极大化上述的 L ( w ) L(w) L(w),具体的求解方法可以用梯度下降法、牛顿法等。(疑问:而此时logistics回归为什么不直接采用梯度为0求解?)——link 虽然有时候能够通过直接令梯度为0求得,但通过梯度上升也能够得到差不多最优的结果。最重要的是有的时候不能通过直接令梯度等0直接求出结果,但总能通过梯度上升求出。(极大化——梯度上升/极小化——梯度下降)
具体的 l ( w ) = ∑ i = 1 N [ y i ( w ⋅ x i ) − l o g ( 1 + e x p ( w ⋅ x i ) ) ] l(w)=\sum_{i=1}^{N}{[y_i(w·x_i)-log(1+exp(w·x_i))]} l(w)=i=1N[yi(wxi)log(1+exp(wxi))] w i w_i wi梯度为:
∂ l ∂ w j = ∑ i = 1 N ( y i − e x p ( w ⋅ x i ) 1 + e x p ( w ⋅ x i ) ) x i j \frac{\partial l}{\partial w_j} =\sum_{i=1}^{N}(y_i-\frac{exp(w·x_i)}{1+exp(w·x_i)})x_i^j wjl=i=1N(yi1+exp(wxi)exp(wxi))xij
然后梯度上升的公式为:
w j = w j + α ∑ i = 1 N ( y i − e x p ( w ⋅ x i ) 1 + e x p ( w ⋅ x i ) ) x i j w_j = w_j+\alpha \sum_{i=1}^{N}(y_i-\frac{exp(w·x_i)}{1+exp(w·x_i)})x_i^j wj=wj+αi=1N(yi1+exp(wxi)exp(wxi))xij
对应到向量的运算为:
w = w + α ∑ i = 1 N ( y i − e x p ( w ⋅ x i ) 1 + e x p ( w ⋅ x i ) ) x i \textbf{w} =\textbf{w}+\alpha \sum_{i=1}^{N}(y_i-\frac{exp(\textbf{w}·x_i)}{1+exp(\textbf{w}·x_i)})x_i w=w+αi=1N(yi1+exp(wxi)exp(wxi))xi
上述为批量梯度下降的公式,具体到随机梯度下降上:
w = w + α ( y i − e x p ( w ⋅ x i ) 1 + e x p ( w ⋅ x i ) ) x i \textbf{w}=\textbf{w}+\alpha (y_i-\frac{exp(\textbf{w}·x_i)}{1+exp(\textbf{w}·x_i)})x_i w=w+α(yi1+exp(wxi)exp(wxi))xi

总结:

以上,就是这次对逻辑斯蒂回归的大致介绍,我们首先介绍了逻辑斯蒂回归对应的公式,然后介绍了他与逻辑斯蒂分布以及对数几率之间的关系;然后介绍模型的参数求解,使用极大似然估计方法求解,先写出似然函数,然后可以利用梯度下降/牛顿法等用于求解无约束优化问题的这类方法来对参数进行求解。最后,将会附上一个minist数据集对应的手写逻辑斯蒂回归方法实现的分类。

附:逻辑斯蒂回归实现(minist数据集)

参考:https://www.pkudodo.com/2018/12/03/1-6/#comment-454

import numpy as np
import datetime
'''
minist 数据集
50000 训练集
10000 测试集(实际使用200)
训练结果:
time_cost 295
currencies  0.902
'''

def load_data(fileName):#加载数据
    '''
    :param fileName:minist训练集/测试集文件
    :return: 对应的特征值X和标签值Y
    '''
    fr = open(fileName, 'r')
    dataX = [];dataY = []
    for line in fr.readlines():
        lineArr = []
        curline = line.strip().split(',')
        if(curline[0]=='0'):# 二分类问题 转换为区分0和非0数字
            dataY.append(1)  # 标签
        else:
            dataY.append(0)
       	#dataX.append([int(num) for num in curline[1:]])  # 特征
        dataX.append([int(num)/255 for num in curline[1:]])  # 特征
        '''
        /255是进行归一化
        如果不进行归一化 则将如下代码
        if(curline[0]=='0'):# 二分类问题 转换为区分0和非0数字
            dataY.append(1)  # 标签
        else:
            dataY.append(0)
        改为:
           if(curline[0]=='0'):# 二分类问题 转换为区分0和非0数字
            dataY.append(0)  # 标签
        else:
            dataY.append(1)
        则正确率会很低
       但进行归一化之后,就不会有上述问题
        '''
    # print(dataX)
    return dataX, dataY
def logistics_Regression(trainX,trainY,iter=200):
    '''
    对模型进行训练
    :param trainX: 训练集特征x
    :param trainY:训练集标签y
    :param iter:迭代次数
    :return:返回学习到的参数w
    '''
    # 将w·x+b变为w·x
    for i in range(len(trainX)):
        trainX[i].append(1)
    #将列表转换为数组 便于运算
    trainX = np.array(trainX)
    # 权值数组大小
    w = np.zeros(trainX.shape[1])
    #步长
    h = 0.001
    for i in range(iter):#迭代次数
        for j in range(trainX.shape[0]):
            # np.dot 点乘 矩阵相乘 a × b 、b×c ==> a × c
            # * np.multiply() 对应元素相乘
            wx = np.dot(w,trainX[j])
            w += h*(trainY[j]*trainX[j] - trainX[j]*np.exp(wx)/(1+np.exp(wx)))
        if i%20==0:
            print('{:.2%}...'.format(i/200))
    return w
def predict(w,X):
    '''
    进行结果预测
    :param w: 训练好的参数
    :param X: 待预测的样本特征
    :return: 预测结果
    '''
    p = np.exp(np.dot(w,X))/(1+np.exp(np.dot(w,X)))
    if(p>=0.5):
        return 1
    else:
        return 0
def test(testX,testY,w):
    '''
    进行测试集的相关测试
    :param testX:测试集特征
    :param testY: 测试集标签
    :param w: 参数
    :return: 正确率
    '''
    for i in range(len(testX)):
       testX[i].append(1)
    count = 0
    for i in range(len(testX)):
        if testY[i] == predict(w,testX[i]):#进行测试
            count+=1
    return float(count/len(testX))

if __name__ == "__main__":
    print("start read data...")
    trainX, trainY = load_data("./mnist_train/mnist_train.csv")
    testX, testY = load_data("./mnist_test/mnist_test.csv")  # 进行测试
    # (60000,784) (60000,1)
    # testX = np.mat(testX)
    start = datetime.datetime.now()
    print("start train the model...")
    w = logistics_Regression(trainX, trainY)
    print("start test...")
    acc = test(testX,testY,w)
    end = datetime.datetime.now()
    print("time_cost", (end - start).seconds)
    print("currencies ", acc)

你可能感兴趣的:(统计学习方法,机器学习)