逻辑回归 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函数之后,得到:
显然,预测的都是正确的!看来我们的函数并没有特别大的漏洞!
二 . 决策边界
再回到上篇博客的数学推导部分,梳理一下整个过程:
我们采用数据集的大量训练得到了 向量,如果这个样本有 个维度的话,那么 就有 个元素(增加一个),将其与新传入的样本数据分别进行点乘 ,再将其结果传给 函数,得到我们需要的 概率 ,如果这个
换句话说,根据 函数本身的属性,如果 ,则返回1;反之,返回 0;
所以,到底取 和 的关键在于 的取值是否为
就是决策边界!
假设我们导入的样本数据中 只有两个特征,易得:。
在二维坐标系中,横轴代表,纵轴代表 ,故可以 为
代码实现一下:
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()
再把记忆的时间轴拉回到刚开始学习
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()
最后得到的为决策边界为:
显然,这里不再是一条直线了,当然,这个样本具有偶然性,当算法作用在三个类别上时,决策边界又会发生什么变化呢?
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()
得到的可视化决策边界为:
怎么样,是不是对这个算法的作用效果更加的清晰了!
三 . 逻辑回归中的多项式特征
现实应用带来得到数据复杂性并不会简单了用一个直线或者二次曲线作为决策边界就完事了,啥样的情况都有,那么带来的决策边界也是啥样的图形都可能会用上!
如果你能用直线把这两种颜色的样本点分开,请一定要在评论区留下你的联系方式,我得好好向您请教一下~~
类似于圆形可能更加的适合,,那么我们能否让逻辑回归算法学习到这样的一个决策边界呢?
思路依然是来自线性回归,在学习线性回归的时候,多项式回归是不是用来处理不规则曲线拟合的?
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)
结果为:
我们现在再来看一下准确率:
再来看一下此时的准确率:
!,竟然达到了95%,那么决策边界图又是啥样的呢?