Logistic回归定义

简单来说, 逻辑回归(Logistic Regression)是一种用于解决二分类(0 or 1)问题的机器学习方法,用于估计某种事物的可能性。比如某用户购买某商品的可能性,某病人患有某种疾病的可能性,以及某广告被用户点击的可能性等。 注意,这里用的是“可能性”,而非数学上的“概率”。logisitc回归的结果并非数学定义中的概率值,不可以直接当做概率值来用。该结果往往用于和其他特征值加权求和,而非直接相乘。通过给定的n组数据(训练集)来训练模型,并在训练结束后对给定的一组或多组数据(测试集)进行分类。其中每一组数据都是由p 个指标构成。

这里举一个例子来说明Logistic回归处理数据并对其进行二分类的过程。

我们给出一个人的 [身高,体重] 这两个指标,然后判断这个人是属于”胖“还是”瘦“这一类。对于这个问题,我们可以先测量n个人的身高、体重以及对应的指标”胖“,"瘦”,把胖和瘦分别用0和1来表示,把这n组数据输入模型进行训练。训练之后再把待分类的一个人的身高、体重输入模型中,看这个人是属于“胖”还是“瘦”。

如果数据是有两个指标,可以用平面的点来表示数据,其中一个指标为x轴,另一个为y轴;如果数据有三个指标,可以用空间中的点表示数据;如果是p维的话(p>3),就是p维空间中的点。

从本质上来说,逻辑回归训练后的模型是平面的一条直线(p=2),或是平面(p=3),超平面(p>3)。并且这条线或平面把空间中的散点分成两半,属于同一类的数据大多数分布在曲线或平面的同一侧。

如上图所示,其中点的个数是样本个数,两种颜色代表两种指标。这个直线可以看成经这些样本训练后得出的划分样本的直线。那么对于之后的样本的p1与p2的值,就可以根据这条直线来判断它属于哪一类了。

基于Logistic回归和Sigmoid函数的分类

首先,我们处理二分类问题。由于分成两类,我们便让其中一类标签为0,另一类为1。我们需要一个函数,对于输入的每一组数据,都能映射成0~1之间的数。并且如果函数值大于0.5,就判定属于1,否则属于0。而且函数中需要待定参数,通过利用样本训练,使得这个参数能够对训练集中的数据有很准确的预测。

这个函数就是Sigmoid函数,形式为。其函数曲线如下:

从上图可以看到sigmoid函数是一个s形的曲线,它的取值在[0, 1]之间,在远离0的地方函数的值会很快接近0或者1。它的这个特性对于解决二分类问题十分重要。

Sigmoid函数的输入记为z,z=x+b,其中向量x是分类器的输入数据,向量w也就是我们要找到的最佳系数,b为常数。代入Sigmoid函数中得到。

至此我们便可以输入数据代入z中再由Sigmoid函数映射到0~1之间,得到一个这样的数值之后就可以进行分类,大于0.5的分入1类,反之分入0类。

现在的问题就在于最佳回归系数是多少?即w和b。

基于最优化方法的最佳回归系数确定

确定最佳回归系数的最优化方法有梯度下降法与梯度上升法等。这里我们重点介绍梯度上升法。

梯度上升法

梯度上升法基于的思想是:要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻。如果梯度记为,则函数f(x,y)的梯度由下式表示:​

这个梯度意味着要沿x的方向移动∂ f ( x , y ) /∂ x,沿y的方向移动∂ f ( x , y ) /∂ y。其中,函数f(x,y)必须要在待计算的点上有定义并且可微。如下图:

 

上图展示的,梯度上升算法到达每个点后都会重新估计移动的方向。从 P0 开始,计算完该点的梯度,函数就根据梯度移动到下一点 P1。在 P1 点,梯度再次被重新计算,并沿着新的梯度方向移动到 P2 。如此循环迭代,直到满足停止条件。迭代过程中,梯度算子总是保证我们能选取到最佳的移动方向。

上图中的梯度上升算法沿梯度方向移动了一步。可以看到,梯度算子总是指向函数值增长最快的方向。这里所说的是移动方向,而未提到移动量的大小。该量值称为步长,记作 α 。用向量来表示的话,梯度上升算法的迭代公式如下:w:=w+α▽w​f(w)。

以下用一个跟简单的例子说明梯度上升的含义:

设函数f(x)=-x^2+4x,函数图如下。则f'(x)=-2x+4,令导数为0,可求出x=2即取得函数f(x)的极大值。极大值等于f(2)=4。

但是真实环境中的函数不会像上面这么简单,就算求出了函数的导数,也很难精确计算出函数的极值。此时我们就可以用迭代的方法来做。就像爬坡一样,一点一点逼近极值。这种寻找最佳拟合参数的方法,就是最优化算法。爬坡这个动作用数学公式表达即为:

其中,α为步长,也就是学习速率,控制更新的幅度。效果如下图所示:

比如从(0,0)开始,迭代路径就是1->2->3->4->…->n,直到求出的x为函数极大值的近似值,停止迭代。

下动图为模拟梯度下降法,将其反转后即为梯度上升法。

python代码实现梯度下降法:

数据集结构如下:

代码如下:

import matplotlib.pyplot as plt

from numpy import *

import math

#加载数据集

def loadDataSet():

'''数据集的前两个值分别为X1和X2,第三个值是数据对应的类别标签,为了方便计算,把X0的值设置成了1.0'''

dataMat = []

labelMat = []

fr = open('D:/系统默认/桌面/深度学习/testSet.txt') #打开logistics regression 数据集).txt文件

# 一定要输入正确的数据集文件所在的地址目录

for line in fr.readlines(): #逐行读取

lineArr = line.strip().split()

dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #因为线性回归化式为 H(x) = W0 + W1*X1 + W2*X2即为 (W0, W1, W2)*(1, X1, X2),

# 其中 (W0, W1, W2) 即为所求回归系数 W。 为了方便计算, 读出 X1, X2 后要在前面补上一个 1.0

labelMat.append(int(lineArr[2]))

return dataMat, labelMat

#分类器的分类(转换)函数

def sigmoid(inX):

return 1.0 / (1 + exp(-inX)) ##计算 sigmoid 函数

#梯度上升算法,用来计算出最佳回归系数

def gradAscent(dataMatIn, classLabels):

'''第一个参数是2维数组,每列代表每个不同特征,每行代表每个训练样本

第二个参数是类别标签,1*100的行向量,为便于计算,将其转换为列向量,即进行转置,并赋值给labelMat

'''

dataMatrix = mat(dataMatIn) # convert to NumPy matrix 获得输入数据并将其转换为Numpy矩阵数据类型

labelMat = mat(classLabels).transpose() # convert to NumPy matrix 获得输入数据并将其转换为Numpy矩阵数据类型

m, n = shape(dataMatrix) #shape函数是numpy.core.fromnumeric中的函数,它的功能是查看矩阵或者数组的维数

alpha = 0.001 #步长,向函数增长最快的方向的移动量,即学习率

maxCycles = 500 #迭代次数

weights = ones((n, 1)) #生成n行一列的元素为1的矩阵赋给weihts,即回归系数初始化为1

#循环 maxCycles次, 每次都沿梯度向真实值 labelMat 靠拢

for k in range(maxCycles): # heavy on matrix operations

h = sigmoid(dataMatrix * weights) # matrix multiplication 矩阵相乘 包含了300次的乘积

error = (labelMat - h) # vector subtraction 向量减法,计算真实类别与预测类别的差值,h是一个列向量,列向量的元素个数等于样本数,即为100

weights = weights + alpha * dataMatrix.transpose() * error # matrix multiplication 矩阵相乘,dataMatrix.transpose()* error 就是梯度f(w),按照该差值的方向调整回归系数

return weights

#输出运用梯度上升优化算法后得到的最理想的回归系数的值

def GetResult():

dataMat, labelMat = loadDataSet()

weights = gradAscent(dataMat, labelMat)

print(weights)

plotBestFit(weights)

#画出数据集和Logistic回归最佳拟合直线

def plotBestFit(weights):

#画点

dataMat, labelMat = loadDataSet()

dataArr = array(dataMat)

n = 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 = arange(-3.0, 3.0, 0.1)

y = (0.48 * x + 4.12414) / (0.616)

# y = (-weights[0]-weights[1]*x)/weights[2]

ax.plot(x, y)

plt.xlabel('X1')

plt.ylabel('X2')

plt.show() #显示

GetResult()

输出最佳回归系数如下:

画出决策边界:

可以看出分类效果还是不错的。

基于逻辑回归的鸢尾花分类预测 

下面我们通过训练鸢尾花数据集对Logistic回归模型进行简单的评估。(鸢尾花数据集介绍) 

因为我们只讨论二分类问题故只选择数据集中类别为0和1的样本。

1.导入相应包

## 基础函数库

import numpy as np

import pandas as pd

## 绘图函数库

import matplotlib.pyplot as plt

import seaborn as sns

2.读取数据集

## 我们利用 sklearn 中自带的 iris 数据作为数据载入,并利用Pandas转化为DataFrame格式

from sklearn.datasets import load_iris

data = load_iris() #得到数据特征

iris_target = data.target #得到数据对应的标签

iris_features = pd.DataFrame(data=data.data, columns=data.feature_names) #利用Pandas转化为DataFrame格式

3.利用逻辑回归模型在二分类上进行训练,计算最佳回归系数

## 为了正确评估模型性能,将数据划分为训练集和测试集,并在训练集上训练模型,在测试集上验证模型性能。

from sklearn.model_selection import train_test_split

## 选择其类别为0和1的样本 (不包括类别为2的样本)

iris_features_part = iris_features.iloc[:100]

iris_target_part = iris_target[:100]

## 测试集大小为20%, 80%/20%分

x_train, x_test, y_train, y_test = train_test_split(iris_features_part, iris_target_part, test_size = 0.2, random_state = 2020)

## 从sklearn中导入逻辑回归模型

from sklearn.linear_model import LogisticRegression

## 定义 逻辑回归模型

clf = LogisticRegression(random_state=0, solver='lbfgs')

# 在训练集上训练逻辑回归模型

clf.fit(x_train, y_train)

## 查看其对应的w

print('the weight of Logistic Regression:',clf.coef_)

## 查看其对应的w0

print('the intercept(w0) of Logistic Regression:',clf.intercept_)

输出最佳回归系数:

4.预测模型准确率

## 在训练集和测试集上分布利用训练好的模型进行预测

train_predict = clf.predict(x_train)

test_predict = clf.predict(x_test)

from sklearn import metrics

## 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果

print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))

print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))

## 查看混淆矩阵 (预测值A和真实值的各类情况统计矩阵)

confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)

print('The confusion matrix result:\n',confusion_matrix_result)

输出准确率与混淆矩阵:

可以看出准确率为1,这说明训练集与测试集中的数据均预测成功,Logistic回归模型对于该数据集的二分类效果良好。

Logistic回归模型的优缺点

优点:

(1)对率函数任意阶可导,具有很好的数学性质,许多现有的数值优化算法都可以用来求最优解,训练速度快;

(2)简单易理解,模型的可解释性非常好,从特征的权重可以看到不同的特征对最后结果的影响;

(3)适合二分类问题,不需要缩放输入特征;

(4)内存资源占用小,因为只需要存储各个维度的特征值;

(5)直接对分类可能性进行建模,无需事先假设数据分布,避免了假设分布不准确所带来的问题

(6)以概率的形式输出,而非知识0.1判定,对许多利用概率辅助决策的任务很有用

缺点:

(1)不能用逻辑回归去解决非线性问题,因为Logistic的决策面试线性的;

(2)对多重共线性数据较为敏感;

(3)很难处理数据不平衡的问题;

(4)准确率并不是很高,因为形式非常的简单(非常类似线性模型),很难去拟合数据的真实分布;

(5)逻辑回归本身无法筛选特征,有时会用gbdt来筛选特征,然后再上逻辑回归。

推荐文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。