基于sciket-learn实现逻辑回归

逻辑回归虽然名称里有回归两个字,但是逻辑回归主要用来解决分类问题,并且只能解决二分类问题。(当然逻辑回归也可以解决回归问题;同时逻辑回归可以通过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去值。

猜你喜欢

转载自blog.csdn.net/sinat_33150417/article/details/83748624