Logistic回归
创始人
2024-03-25 18:54:57
0

通常,Logistic回归用于二分类问题,例如预测明天是否会下雨。当然它也可以用于多分类问题.

Logistic回归是分类方法,它利用的是Sigmoid函数阈值在[0,1]这个特性。Logistic回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。其实,Logistic本质上是一个基于条件概率的判别模型(Discriminative Model)。

所以要想了解Logistic回归,我们必须先看一看Sigmoid函数 ,我们也可以称它为Logistic函数。它的公式如下:

整合成一个公式,就变成了如下公式

 

θ是参数列向量(要求解的),x是样本列向量(给定的数据集).这样我们的数据集([x0,x1,...,xn]),不管是大于1或者小于0,都可以映射到[0,1]区间进行分类。hθ(x)给出了输出为1的概率

那么问题来了!如何得到合适的参数向量θ?

式即为在已知样本x和参数θ的情况下,样本x属于正样本(y=1)和负样本(y=0)的条件概率。理想状态下,根据上述公式,求出各个点的概率均为1,也就是完全分类都正确。但是考虑到实际情况,样本点的概率越接近于1,其分类效果越好。比如一个样本属于正样本的概率为0.51,那么我们就可以说明这个样本属于正样本。另一个样本属于正样本的概率为0.99,那么我们也可以说明这个样本属于正样本。但是显然,第二个样本概率更高,更具说服力。我们可以把上述两个概率公式合二为一:

为了简化问题,我们对整个表达式求对数

 这个损失函数,是对于一个样本而言的。给定一个样本,我们就可以通过这个损失函数求出,样本所属类别的概率,而这个概率越大越好,所以也就是求解这个损失函数的最大值。既然概率出来了,那么最大似然估计也该出场了。假定样本与样本之间相互独立,那么整个样本集生成的概率即为所有样本生成概率的乘积,便可得到如下公式

 其中,m为样本的总数,y(i)表示第i个样本的类别,x(i)表示第i个样本,需要注意的是θ是多维向量,x(i)也是多维向量。

综上所述,满足J(θ)的最大的θ值即是我们需要求解的模型。

怎么求解使J(θ)最大的θ值呢?因为是求最大值,所以我们需要使用梯度上升算法。如果面对的问题是求解使J(θ)最小的θ值,那么我们就需要使用梯度下降算法。

def Gradient_Ascent_test():def f_prime(x_old):  # f(x)的导数return -2 * x_old + 4x_old = -1  # 初始值,给一个小于x_new的值x_new = 0  # 梯度上升算法初始值,即从(0,0)开始alpha = 0.01  # 步长,也就是学习速率,控制更新的幅度presision = 0.00000001  # 精度,也就是更新阈值while abs(x_new - x_old) > presision:x_old = x_newx_new = x_old + alpha * f_prime(x_old)  # 上面提到的公式print(x_new)  # 打印最终求解的极值近似值if __name__ == '__main__':Gradient_Ascent_test()

目标函数

 

 

 代码

-0.017612   14.053064  0
-1.395634  4.662541   1
-0.752157  6.538620   0
-1.322371  7.152853   0
0.423363   11.054677  0
0.406704   7.067335   1
0.667394   12.741452  0
-2.460150  6.866805   1
0.569411   9.548755   0
-0.026632  10.427743  0
0.850433   6.920334   1
1.347183   13.175500  0
1.176813   3.167020   1
-1.781871  9.097953   0
-0.566606  5.749003   1
0.931635   1.589505   1
-0.024205  6.151823   1
-0.036453  2.690988   1
-0.196949  0.444165   1
1.014459   5.754399   1
1.985298   3.230619   1
-1.693453  -0.557540  1
-0.576525  11.778922  0
-0.346811  -1.678730  1
-2.124484  2.672471   1
1.217916   9.597015   0
-0.733928  9.098687   0
-3.642001  -1.618087  1
0.315985   3.523953   1
1.416614   9.619232   0
-0.386323  3.989286   1
0.556921   8.294984   1
1.224863   11.587360  0
-1.347803  -2.406051  1
1.196604   4.951851   1
0.275221   9.543647   0
0.470575   9.332488   0
-1.889567  9.542662   0
-1.527893  12.150579  0
-1.185247  11.309318  0
-0.445678  3.297303   1

 数据可视化

import matplotlib.pyplot as plt
import numpy as np"""
函数说明:加载数据Parameters:无
Returns:dataMat - 数据列表labelMat - 标签列表
"""def loadDataSet():dataMat = []  # 创建数据列表labelMat = []  # 创建标签列表fr = open('testSet.txt')  # 打开文件for line in fr.readlines():  # 逐行读取lineArr = line.strip().split()  # 去回车,放入列表dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])  # 添加数据labelMat.append(int(lineArr[2]))  # 添加标签fr.close()  # 关闭文件return dataMat, labelMat  # 返回"""
函数说明:绘制数据集Parameters:无
Returns:无
"""def plotDataSet():dataMat, labelMat = loadDataSet()  # 加载数据集dataArr = np.array(dataMat)  # 转换成numpy的array数组n = np.shape(dataMat)[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])  # 1为正样本else:xcord2.append(dataArr[i, 1]);ycord2.append(dataArr[i, 2])  # 0为负样本fig = plt.figure()ax = fig.add_subplot(111)  # 添加subplotax.scatter(xcord1, ycord1, s=20, c='red', marker='s', alpha=.5)  # 绘制正样本ax.scatter(xcord2, ycord2, s=20, c='green', alpha=.5)  # 绘制负样本plt.title('DataSet')  # 绘制titleplt.xlabel('x');plt.ylabel('y')  # 绘制labelplt.show()  # 显示if __name__ == '__main__':plotDataSet()

 

# -*- coding:UTF-8 -*-
import numpy as npdef loadDataSet():dataMat = []  # 创建数据列表labelMat = []  # 创建标签列表fr = open('testSet.txt')  # 打开文件for line in fr.readlines():  # 逐行读取lineArr = line.strip().split()  # 去回车,放入列表dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])  # 添加数据labelMat.append(int(lineArr[2]))  # 添加标签fr.close()  # 关闭文件return dataMat, labelMat  # 返回def sigmoid(inX):return 1.0 / (1 + np.exp(-inX))"""
函数说明:梯度上升算法Parameters:dataMatIn - 数据集classLabels - 数据标签
Returns:weights.getA() - 求得的权重数组(最优参数)
"""def gradAscent(dataMatIn, classLabels):dataMatrix = np.mat(dataMatIn)  # 转换成numpy的matlabelMat = np.mat(classLabels).transpose()  # 转换成numpy的mat,并进行转置m, n = np.shape(dataMatrix)  # 返回dataMatrix的大小。m为行数,n为列数。alpha = 0.001  # 移动步长,也就是学习速率,控制更新的幅度。maxCycles = 500  # 最大迭代次数weights = np.ones((n, 1))for k in range(maxCycles):h = sigmoid(dataMatrix * weights)  # 梯度上升矢量化公式error = labelMat - hweights = weights + alpha * dataMatrix.transpose() * errorreturn weights.getA()  # 将矩阵转换为数组,返回权重数组if __name__ == '__main__':dataMat, labelMat = loadDataSet()print(gradAscent(dataMat, labelMat))

 

import matplotlib.pyplot as plt
import numpy as np
def loadDataSet():dataMat = []  # 创建数据列表labelMat = []  # 创建标签列表fr = open('testSet.txt')  # 打开文件for line in fr.readlines():  # 逐行读取lineArr = line.strip().split()  # 去回车,放入列表dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])  # 添加数据labelMat.append(int(lineArr[2]))  # 添加标签fr.close()  # 关闭文件return dataMat, labelMat  # 返回def sigmoid(inX):return 1.0 / (1 + np.exp(-inX))def gradAscent(dataMatIn, classLabels):dataMatrix = np.mat(dataMatIn)  # 转换成numpy的matlabelMat = np.mat(classLabels).transpose()  # 转换成numpy的mat,并进行转置m, n = np.shape(dataMatrix)  # 返回dataMatrix的大小。m为行数,n为列数。alpha = 0.001  # 移动步长,也就是学习速率,控制更新的幅度。maxCycles = 500  # 最大迭代次数weights = np.ones((n, 1))for k in range(maxCycles):h = sigmoid(dataMatrix * weights)  # 梯度上升矢量化公式error = labelMat - hweights = weights + alpha * dataMatrix.transpose() * errorreturn weights.getA()  # 将矩阵转换为数组,返回权重数组def plotBestFit(weights):dataMat, labelMat = loadDataSet()  # 加载数据集dataArr = np.array(dataMat)  # 转换成numpy的array数组n = np.shape(dataMat)[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])  # 1为正样本else:xcord2.append(dataArr[i, 1]);ycord2.append(dataArr[i, 2])  # 0为负样本fig = plt.figure()ax = fig.add_subplot(111)  # 添加subplotax.scatter(xcord1, ycord1, s=20, c='red', marker='s', alpha=.5)  # 绘制正样本ax.scatter(xcord2, ycord2, s=20, c='green', alpha=.5)  # 绘制负样本x = np.arange(-3.0, 3.0, 0.1)y = (-weights[0] - weights[1] * x) / weights[2]ax.plot(x, y)plt.title('BestFit')  # 绘制titleplt.xlabel('X1');plt.ylabel('X2')  # 绘制labelplt.show()if __name__ == '__main__':dataMat, labelMat = loadDataSet()weights = gradAscent(dataMat, labelMat)plotBestFit(weights)

机器学习实战教程(六):Logistic回归基础篇之梯度上升算法 (cuijiahua.com) 

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...