机器学习入门之逻辑回归——全网最详细(下)

it2026-08-31  4

紧接着上次机器学习博客的内容!戳这里可以从头看!

逻辑回归 Logistic Regression

一. 小测试二 . 决策边界三 . 逻辑回归中的多项式特征

一. 小测试

上次博客的结尾,我们根据前面的分析给出了逻辑回归算法中最主要得到代码,那么下面我们用上期博客留下来的代码测试一下这个算法的可行性,还是以鸢尾花数据集为例:

既然是测试嘛,数据就不要那么庞大了,简单一点就好!

import numpy as np import matplotlib.pyplot as plt from sklearn import datasets iris = datasets.load_iris() X = iris.data y = iris.target X = X[y<2,:2] #在X的每一行中,我们只需要选取对于y = 0或者y =1的行 y = y[y<2] plt.scatter(X[y==0,0],X[y==0,1],color='red') plt.scatter(X[y==1,0],X[y==1,1],color='blue') plt.show()

得到的图像为:

from model_selection import train_test_split X_train,X_test,y_train,y_test=train_test_split(X,y,seed=666) from LogisticRegression import LogisticRegression log_reg = LogisticRegression() log_reg.fit(X_train,y_train) log_reg.score(X_test,y_test) #测试一下分类结果怎样?

上面这些代码都是机器学习里面的老套路了,就不赘述了!

log_reg.predict_proba(X_test) #看一下返回的概率怎么样!

而 y_test 中真实的值又是怎样的呢?Look: 将log_reg.predict_proba(X_test) 的结果经过predict函数之后,得到: 显然,预测的都是正确的!看来我们的函数并没有特别大的漏洞!

二 . 决策边界

再回到上篇博客的数学推导部分,梳理一下整个过程: p ^ = σ ( θ T ⋅ x b ) = 1 1 + e − θ T ⋅ x b \hat{p}=\sigma\left(\theta^{T} \cdot x_{b}\right)=\frac{1}{1+e^{-\theta^{T} \cdot x_{b}}} p^=σ(θTxb)=1+eθTxb1 我们采用数据集的大量训练得到了 θ \theta θ向量,如果这个样本有 n n n 个维度的话,那么 θ \theta θ 就有 n + 1 n+1 n+1 个元素(增加一个 θ 0 \theta_{0} θ0),将其与新传入的样本数据分别进行点乘 ,再将其结果传给 S i g m o i d Sigmoid Sigmoid 函数,得到我们需要的 概率 p ^ \hat{p} p^ ,如果这个 p ^ \hat{p} p^ 大于0.5,则返回1,如果其小于0.5,则返回0。

换句话说,根据 S i g m o i d Sigmoid Sigmoid 函数本身的属性,如果 θ T ⋅ x b ⩾ 0 \theta^{T} \cdot x_{b} \geqslant0 θTxb0,则返回1;反之,返回 0; 所以,到底取 0 0 0 1 1 1 的关键在于 θ T ⋅ x b \theta^{T} \cdot x_{b} θTxb 的取值是否为 0 0 0 !

θ T ⋅ x b = 0 \theta^{T} \cdot x_{b}=0 θTxb=0就是决策边界!

假设我们导入的样本数据中 X X X 只有两个特征,易得: θ 0 + θ 1 x 1 + θ 2 x 2 = 0 \theta_{0}+\theta_{1} x_{1}+\theta_{2} x_{2}=0 θ0+θ1x1+θ2x2=0

在二维坐标系中,横轴代表 x 1 x_{1} x1,纵轴代表 x 2 x_{2} x2,故可以 x 2 x_{2} x2 y y y 轴,便能得到这样的 “决策边界” 直线!

x 2 = − θ 0 − θ 1 x 1 θ 2 x_{2}=\frac{-\theta_{0}-\theta_{1} x_{1}}{\theta_{2}} x2=θ2θ0θ1x1

代码实现一下:

def x2(x1): return (-log_reg.coef_[0]*x1 - log_reg.intercept_)/log_reg.coef_[1] x1_plot = np.linspace(4,8,1000) x2_plot = x2(x1_plot) plt.scatter(X[y==0,0],X[y==0,1],color='red') plt.scatter(X[y==1,0],X[y==1,1],color='blue') plt.plot(x1_plot,x2_plot) plt.show()

如下图所示: 但往往事实并不是那么的简单和完美,正常情况下,样本的特征远远不止2种,所以决策边界也就不再是直线了:

对于不规则的决策边界,假设平面中有无数可以细分的点,运用之前的算法去预测每个点的具体分类结果,最后绘制出来的不同颜色的点大致构成了其决策边界,算法如下:

def plot_decision_boundary(model,axis): x0,x1=np.meshgrid( np.linspace(axis[0],axis[1],int((axis[1]-axis[0])*100)).reshape(-1,1), np.linspace(axis[2],axis[3],int((axis[3]-axis[2])*100)).reshape(-1,1) ) X_new=np.c_[x0.ravel(),x1.ravel()] y_predict=model.predict(X_new) zz=y_predict.reshape(x0.shape) from matplotlib.colors import ListedColormap custom_cmap=ListedColormap(['#EF9A9A','#FFF59D','#90CAF9']) plt.contourf(x0,x1,zz,linewidth=5,cmap=custom_cmap)

用上面已有的例子测试一下:

plot_decision_boundary(log_reg,axis=[4, 7.5, 1.5, 4.5]) plt.scatter(X[y==0,0],X[y==0,1],color='red') plt.scatter(X[y==1,0],X[y==1,1],color='blue') plt.show()

再把记忆的时间轴拉回到刚开始学习 K N N KNN KNN 算法的时候,也存在类似的决策边界,我们也用上面已有的数据来测试一样,这里的 plot_decision_boundary 是否也能使用呢?

from sklearn.neighbors import KNeighborsClassifier ##创建分类器 knn_clf = KNeighborsClassifier() knn_clf.fit(X_train,y_train) knn_clf.score(X_test,y_test) #准确率为100% plot_decision_boundary(knn_clf,axis=[4, 7.5, 1.5, 4.5]) plt.scatter(X[y==0,0],X[y==0,1],color='red') plt.scatter(X[y==1,0],X[y==1,1],color='blue') plt.show()

最后得到的为决策边界为: 显然,这里不再是一条直线了,当然,这个样本具有偶然性,当 K N N KNN KNN算法作用在三个类别上时,决策边界又会发生什么变化呢?

knn_clf_all = KNeighborsClassifier(n_neighbors=50) #这里的n_neighbors取50 提高准确率! knn_clf_all.fit(iris.data[:,:2],iris.target) plot_decision_boundary(knn_clf_all,axis=[4, 8, 1.5, 4.5]) plt.scatter(iris.data[iris.target==0,0],iris.data[iris.target==0,1]) plt.scatter(iris.data[iris.target==1,0],iris.data[iris.target==1,1]) plt.scatter(iris.data[iris.target==2,0],iris.data[iris.target==2,1]) plt.scatter(X[y==1,0],X[y==1,1],color='blue') plt.show()

得到的可视化决策边界为: 怎么样,是不是对这个算法的作用效果更加的清晰了!

三 . 逻辑回归中的多项式特征

现实应用带来得到数据复杂性并不会简单了用一个直线或者二次曲线作为决策边界就完事了,啥样的情况都有,那么带来的决策边界也是啥样的图形都可能会用上! 如果你能用直线把这两种颜色的样本点分开,请一定要在评论区留下你的联系方式,我得好好向您请教一下~~

类似于圆形可能更加的适合, x 1 2 + x 2 2 − r 2 = 0 x_{1}^{2}+x_{2}^{2}-r^{2}=0 x12+x22r2=0,那么我们能否让逻辑回归算法学习到这样的一个决策边界呢?

思路依然是来自线性回归,在学习线性回归的时候,多项式回归是不是用来处理不规则曲线拟合的?

import numpy as np import matplotlib.pyplot as plt np.random.seed(666) #生成我们需要的数据样本 X = np.random.normal(0,1,size=(200,2)) y = np.array(X[:,0]**2 + X[:,1]**2 < 1.5,dtype = 'int') plt.scatter(X[y==0,0],X[y==0,1]) plt.scatter(X[y==1,0],X[y==1,1]) plt.show()

得到的散点图如下: 显然,其决策边界很像是一个圆形或者是椭圆形,现在用原先的方法看看效果:

from LogisticRegression import LogisticRegression log_reg = LogisticRegression() log_reg.fit(X,y)

来看一下准确率: 准确率只有 60% 左右,再来看看绘制的决策边界:

def plot_decision_boundary(model,axis): #还是使用这个函数 x0,x1=np.meshgrid( np.linspace(axis[0],axis[1],int((axis[1]-axis[0])*100)).reshape(-1,1), np.linspace(axis[2],axis[3],int((axis[3]-axis[2])*100)).reshape(-1,1) ) X_new=np.c_[x0.ravel(),x1.ravel()] y_predict=model.predict(X_new) zz=y_predict.reshape(x0.shape) from matplotlib.colors import ListedColormap custom_cmap=ListedColormap(['#EF9A9A','#FFF59D','#90CAF9']) plt.contourf(x0,x1,zz,linewidth=5,cmap=custom_cmap) plot_decision_boundary(log_reg,axis=[-4,4,-4,4]) plt.scatter(X[y==0,0],X[y==0,1]) plt.scatter(X[y==1,0],X[y==1,1]) plt.show()

显然,这决策边界画的 啥也不是!我们来引入 多现实特征拟合:

from sklearn.pipeline import Pipeline from sklearn.preprocessing import PolynomialFeatures from sklearn.preprocessing import StandardScaler def PolynomialLogisticRegression(degree): return Pipeline([ ('poly',PolynomialFeatures(degree=degree)), ('std_scaler',StandardScaler()), ('log_reg',LogisticRegression()) #不是sklearn中的 ,自己实现的 ])

实例化:

poly_log_reg = PolynomialLogisticRegression(degree=2) poly_log_reg.fit(X,y)

结果为:

我们现在再来看一下准确率: 再来看一下此时的准确率: A m a z i n g Amazing Amazing !,竟然达到了95%,那么决策边界图又是啥样的呢? 正好和我们的期望相符!

最新回复(0)