文章目录

  • 逻辑斯蒂回归模型
  • 逻辑斯蒂回归模型python案例

逻辑斯蒂回归模型

前面的例子都是在用线性模型解决回归任务,那么线性模型能否完成分类任务呢?相较于回归任务,分类任务的预测值是离散的,比如二分类问题,可以用0和1来表示两个类别。前面我们也提到了广义线性回归模型的联系函数可以是任意,我们能否构造一个让预测值变为离散值的联系函数g呢?

例如可以使用单位越阶函数,公式如下:
分类检验回归的可靠性_机器学习
其中1表示分类结果为正例,0表示分类结果为反例,而g(z)取值为0.5时,类别可以进行任意判定。

由于单位越阶函数在临界点不连续,临界点出不可导,因此不能直接用作g函数,于是找到了近似的logistic函数,它在临界点连续且单调可微公式如下:
分类检验回归的可靠性_分类_02
由于图形很像一个“S”型,所以又叫 sigmoid曲线(S型曲线)。

分类检验回归的可靠性_分类检验回归的可靠性_03

最终我们得到逻辑斯蒂回归模型,需要注意虽然名称叫做回归模型,但是它是解决分类任务,公式如下:

分类检验回归的可靠性_回归_04

逻辑斯蒂回归模型python案例

案例根据y=0.5x+0.5,y=2.1x+6.5两个函数为基准,引入了较大的随机误差后,各生成了100个样本点。生成的样本有明显的线性边界,我们尝试使用逻辑回归模型,找出决策边界,并进行绘制。

分类检验回归的可靠性_分类检验回归的可靠性_05

import numpy as np
import pandas as pd
import random
import  matplotlib.pyplot as plt #类似 MATLAB 中绘图函数的相关函数
import seaborn as sns
# 导入逻辑回归模型函数
from sklearn.linear_model import LogisticRegression

np.random.seed(2)
count=100
data=[]
for i in range(count):
    x1=np.random.normal(0.00,0.55)
    res1=x1*0.1+0.5+np.random.normal(0.00,0.9)
    data.append([x1,res1,1])
    
    x2=np.random.normal(0.00,0.55)
    res2=x2*2.1+6.5+np.random.normal(0.00,0.9)
    data.append([x2,res2,0])

data =pd.DataFrame(data)
# print(data[data[2]==1])
x1_data=np.array(data[0])
x2_data=np.array(data[1])
plt.scatter(x1_data,x2_data,c=data[2])
plt.show()


# 调用逻辑回归模型
lr_clf = LogisticRegression()

# 用逻辑回归模型拟合构造的数据集 (其拟合方程为 y = w0 + w1 * x1 + w2 * x2)
lr_clf = lr_clf.fit(data.iloc[:,:2], data[2])

## 查看其对应模型的w1,w2
print('the weight of Logistic Regression:', lr_clf.coef_)

## 查看其对应模型的w0
print('the intercept(w0) of Logistic Regression:', lr_clf.intercept_)


plt.figure()
plt.scatter(x1_data,x2_data, c=data[2], s=50, cmap='viridis')
plt.title('Dataset')
nx, ny = 200, 100
# 获取feature中x轴和y轴上最小最大值
x_min, x_max = plt.xlim() # 设定坐标范围
y_min, y_max = plt.ylim()
# np.linspace:创建等差数列,np.meshgrid:网格坐标矩阵
# print(np.linspace(x_min, x_max, nx)) # 区间内创建200个等差数列的数

x_grid, y_grid = np.meshgrid(np.linspace(x_min, x_max, nx), np.linspace(y_min, y_max, ny))

# np.c_: 添加列

# 返回预测属于某标签的概率 
z_proba = lr_clf.predict_proba(np.c_[x_grid.ravel(), y_grid.ravel()])
z_proba = z_proba[:, 1].reshape(x_grid.shape)

'''
plt.contour(X, Y, Z, [levels], **kwargs)
plt就是matplotlib.pyplot
X, Y表示的是坐标位置(这里是可选的,但是如果不传入的话就是python根据传入的高度数组(Z)的大小自动生成的坐标),一般很多会使用二维数组,但是实际上一维数组也可以的
Z代表每个坐标对应的高度值,是一个二维数组,其中每个值表示的是每个坐标对应的高度 XYZ的实际数据构成可以参照上面的例子,在本地查看一下数据是长什么样
levels有两种传入形式。一种是传入一个整数,这个整数表示你想绘制的等高线的条数,但是显示结果可能并不是完全和传入的整数的条数一样,是大致差不多的条数(可能相差一两条)(为什么是大致条数呢?可能是python帮你默认生成的比较合适的几条等高线吧)。还有一种方式就是传入一个包含高度值的一维数组,这样python便会画出传入的高度值对应的等高线。
————————————————。


# plt.contour: 绘制轮廓
# 将 网格坐标矩阵中的点和概论绘制进图形,在概论等于0.5的位置绘制分割线,完成分类任务。
plt.contour(x_grid, y_grid, z_proba, [0.5], linewidths=2., colors='blue')
plt.show()