1. 逻辑回归的原理

逻辑回归名字里带着回归,并不是回归,而是用回归的形式解决分类的算法。
逻辑回归的输出:ℎ(w)= w_0+w_1x_1+w_2x_2+…= w^Tx
这个输出跟线性回归很类似。

而后看下Sigmoid 函数

画下这个函数的图像
代码示例

import numpy as npfrom matplotlib import pyplot as pltdef sigmod(t):    return 1/(1+np.exp(-t))x = np.linspace(-10, 10, 500)y = sigmod(x)plt.figure(figsize=(8,4),dpi=80)plt.plot(x, y)plt.show()


能够看到自变量取值为任意实数,值域[0,1],这就等同于概率值

将逻辑回归的输出带入到sigmod函数中。

而后失去逻辑回归的预测函数,这样就实现了由值到概率的转换,假设一个阈值为0.5,默认也是取0.5,大于0.5概率归于1,小于0.5概率的归为0,这就实现了一个二分类的问题。

那么就有

整合下失去

3.逻辑回归的损失函数

  • 推导形式一
    由预测函数推导

没有其余特地的,仍然是似然函数开始

接着取对数

l()取最大值是咱们最心愿,但通常优化的习惯是取最小值,所以这里取-l(), 整顿后,可得如下

代入失去

这个就是逻辑回归的损失函数。

求导

  • 推导形式二
    逻辑回归解决的是二分类问题,设y是咱们目标值(1, 0),p则是预测概率值,
    若y的实在值为1,则预测的p越大,损失越小,预测的p越小,损失越大
    若y的实在值为0,而预测的p越大,损失越大,预测的p越小,损失越小
    那么我能够设定损失函数为

咱们下y=1和y=0时,损失函数的图像
代码示例

from matplotlib import pyplot as pltfrom matplotlib import font_managerimport numpy as npfont = font_manager.FontProperties(fname="/usr/share/fonts/wps-office/msyhbd.ttf", size=12)def log(t):    return np.log(t)p = np.arange(0.1, 1, 0.1)y1 = -log(p)y2 = -log(1-p)plt.plot(p, y1, label='y=1')plt.plot(p, y2, label='y=0')plt.legend(prop=font, loc='best')plt.show()

失去

对损失函数进行下整合失去

而后失去损失函数

与第一个形式推导后果雷同。

4.鸢尾花示例

# coding:utf-8import numpy as npimport pandas as pdfrom sklearn import datasetsfrom sklearn.linear_model import LogisticRegressionfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom matplotlib import pyplot as pltfrom matplotlib import font_managerfont = font_manager.FontProperties(fname="/usr/share/fonts/wps-office/msyhbd.ttf", size=15)def logist_fun():    # 加载数据集    iris = datasets.load_iris()    x = iris.data  # 特征值    y = iris.target # 目标值    # 目标值有三个,这里只取0和1,做二分类演示    data = pd.DataFrame(x)    data['y'] = y    data = data[data['y'] !=2 ]    print(data)    x = data.loc[:,[0, 1, 2, 3]]    y = data.loc[:, 'y']    print(x)    # 宰割数据集    x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=102)    # 标准化    stand = StandardScaler()    x_train = stand.fit_transform(x_train)    x_test = stand.transform(x_test)    # 建设模型    lr = LogisticRegression(C=1.0)    lr.fit(x_train, y_train)    y_predict = lr.predict(x_test)    score = lr.score(x_test, y_test)    print("准确率{}".format(score))    return y_predict, y_testdef draw_fun(y_predict, y_test):    x = range(1,len(y_predict)+1)    plt.figure(figsize=(25, 5), dpi=80)    plt.scatter(x, y_test, label="实在值",color='blue', linewidths=20)    plt.scatter(x, y_predict,label='预测值', color='red', linewidths=3)    x_tick = list(x)    y_tick = list(range(0,3))    plt.legend(prop=font, loc='upper left')    plt.xticks(list(x), x_tick)    plt.yticks(y_tick)    plt.grid(alpha=0.8)    plt.show()if __name__ == '__main__':    y_predict, y_test = logist_fun()    draw_fun(y_predict, y_test)

后果如图

5.逻辑回归的决策边界

以鸢尾花数据集为例子,简单化,只取前两个特色,和目标值为0和1的数据集,而后画下分布图

import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom matplotlib import font_managerfrom sklearn import datasetsfont = font_manager.FontProperties(fname="/usr/share/fonts/wps-office/msyhbd.ttf", size=15)iris = datasets.load_iris()x = iris.data  # 特征值y = iris.target  # 目标值data = pd.DataFrame(x)data['y'] = y# 目标值有三个,这里只取0和1, 特征值也只取两个,做二分类演示data = data[data['y'] != 2].loc[:, [0, 1, 'y']]X0_0 = data[data['y']==0].loc[:,0]X0_1 = data[data['y']==0].loc[:,1]X1_0 = data[data['y']==1].loc[:,0]X1_1 = data[data['y']==1].loc[:,1]print(data.head())plt.scatter(X0_0, X0_1, color='blue')plt.scatter(X1_0, X1_1, color='red')plt.show()

图像如下
咱们设定的阈值为0.5,也就是

等于0.5, 则

在示例中,则有

其中0 是偏置, 1和2是系数,x1和x2是特征值,转换后,有

批改下代码绘制决策边界

import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom matplotlib import font_managerfrom sklearn import datasetsfrom sklearn.linear_model import LogisticRegressionfrom sklearn.model_selection import train_test_splitfont = font_manager.FontProperties(fname="/usr/share/fonts/wps-office/msyhbd.ttf", size=15)iris = datasets.load_iris()x = iris.data  # 特征值y = iris.target  # 目标值data = pd.DataFrame(x)data['y'] = y# 目标值有三个,这里只取0和1, 特征值也只取两个,做二分类演示data = data[data['y'] != 2].loc[:, [0, 1, 'y']]# 逻辑回归x = data.loc[:,[0, 1]]y = data.loc[:, 'y']x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=102)logic_reg = LogisticRegression()logic_reg.fit(x_train, y_train)# x2特征值和x1的关系def x2(x1):    global logic_reg    return (-logic_reg.intercept_[0] - logic_reg.coef_[0][0] * x1)/logic_reg.coef_[0][1]X0_0 = data[data['y']==0].loc[:,0]X0_1 = data[data['y']==0].loc[:,1]X1_0 = data[data['y']==1].loc[:,0]X1_1 = data[data['y']==1].loc[:,1]x1_plot = np.arange(4,8)x2_Plot = x2(x1_plot)plt.scatter(X0_0, X0_1, color='blue')plt.scatter(X1_0, X1_1, color='red')plt.plot(x1_plot,x2_Plot)plt.show()

后果如下

6.增加多项式扩大

对于线性的分类,决策边界,就是相似一条直线,那如果是非线性的,如下图

它的决策边界是相似一个椭圆,这时候能够引入多项式。

# coding:utf-8import numpy as npimport matplotlib.pyplot as pltfrom matplotlib import font_managerfrom matplotlib.colors import ListedColormapfrom sklearn.linear_model import LogisticRegressionfrom sklearn.pipeline import Pipelinefrom sklearn.preprocessing import PolynomialFeaturesfrom sklearn.preprocessing import StandardScalerfont = font_manager.FontProperties(fname="/usr/share/fonts/wps-office/msyhbd.ttf", size=15)# 结构数据集np.random.seed(666)X = np.random.normal(0, 1, size=(500, 2))y = np.array(X[:,0]**2 + X[:,1]**2 < 1.5, dtype='int')def pnf(degree):    return Pipeline([        ('poly', PolynomialFeatures(degree=degree)),        ('std_scaler', StandardScaler()),        ('log_reg', LogisticRegression())    ])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)    custom_cmap = ListedColormap(['#EF9A9A', '#FFF59D', '#90CAF9'])    plt.contourf(x0, x1, zz, cmap=custom_cmap)poly_log_reg = pnf(degree=2)poly_log_reg.fit(X, y)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()

如图