文章目录
- 逻辑斯蒂回归模型
- 逻辑斯蒂回归模型python案例
逻辑斯蒂回归模型
前面的例子都是在用线性模型解决回归任务,那么线性模型能否完成分类任务呢?相较于回归任务,分类任务的预测值是离散的,比如二分类问题,可以用0和1来表示两个类别。前面我们也提到了广义线性回归模型的联系函数可以是任意,我们能否构造一个让预测值变为离散值的联系函数g呢?
例如可以使用单位越阶函数,公式如下:
其中1表示分类结果为正例,0表示分类结果为反例,而g(z)取值为0.5时,类别可以进行任意判定。
由于单位越阶函数在临界点不连续,临界点出不可导,因此不能直接用作g函数,于是找到了近似的logistic函数,它在临界点连续且单调可微公式如下:
由于图形很像一个“S”型,所以又叫 sigmoid曲线(S型曲线)。
最终我们得到逻辑斯蒂回归模型,需要注意虽然名称叫做回归模型,但是它是解决分类任务,公式如下:
逻辑斯蒂回归模型python案例
案例根据y=0.5x+0.5,y=2.1x+6.5两个函数为基准,引入了较大的随机误差后,各生成了100个样本点。生成的样本有明显的线性边界,我们尝试使用逻辑回归模型,找出决策边界,并进行绘制。
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()