逻辑回归虽然名称里有回归两个字,但是逻辑回归主要用来解决分类问题,并且只能解决二分类问题。(当然逻辑回归也可以解决回归问题;同时逻辑回归可以通过OvO、OvR等方法实现多分类,但本质还是二分类。)
逻辑回归与线性回归不同的是,线性回归得出的是一个具体的预测值,预测房价的模型得出的就是房价,预测成绩的模型得出的就是成绩,而逻辑回归得出的是概率,通过概率大于小于来进行分类。下面是逻辑回归的公式:
接下来通过代码,来具体看看逻辑回归是怎么一回事。
先导入基本类库,生成模拟数据集,并且增加噪声
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])<1.5, dtype='int')
for _ in range(20):
y[np.random.randint(200)] = 1
可视化数据
plt.scatter(X[y==0,0], X[y==0,1])
plt.scatter(X[y==1,0], X[y==1,1])
plt.show()
划分测试集和预测集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)
生成sciket-learn为我们封装好的逻辑回归构造器进行fit操作
from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
查看分类结果
log_reg.score(X_train, y_train)
log_reg.score(X_test, y_test)
可视化(这个可视化函数不是重点,知道意思即可)
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.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
def PolynomialLogisticRegression(degree):
return Pipeline([
('poly', PolynomialFeatures(degree=degree)),
('std_scaler', StandardScaler()),
('log_reg', LogisticRegression())
])
在这里给degree传入2进行训练
poly_log_reg = PolynomialLogisticRegression(degree=2)
poly_log_reg.fit(X_train, y_train)
查看结果并可视化
poly_log_reg.score(X_train, y_train)
poly_log_reg.score(X_test, y_test)
plot_decision_boundary(poly_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()
可以看出现在拟合的已经很不错了
在使用sciket-learn封装好的类库,degree传入较大的值,查看分类结果。
poly_log_reg2 = PolynomialLogisticRegression(degree=50)
poly_log_reg2.fit(X_train, y_train)
poly_log_reg2.score(X_train, y_train)
poly_log_reg2.score(X_test, y_test)
因为在生成预测数据集的时候,便已经知道了是条二次曲线,所以degree=2时的拟合结果及泛化能力都是最好的,但是实际业务中,往往需要综合很多因素才能得出最佳的degree去值。