1.1. 逻辑回归 Logistic Regression (对数几率回归 Logit Regression)
名字
关于名字,有文献将Logistic Regression译为“逻辑回归”, 但中文“逻辑”与logitic 和 logit 的含义相去甚远,因此在《机器学习》中意译为“对数几率回归”,简称“对率回归”。
线性回归
在介绍对数几率回归之前先介绍一下线性回归,线性回归的主要思想是通过历史数据拟合出一条直线,因变量与自变量是线性关系,对新的数据用这条直线进行预测。 线性回归的公式如下:
y=w0+w1x1+...+wnxn=wTx+b
逻辑回归
对数几率回归是一种广义的线性回归分析模型,是一种预测分析。虽然它名字里带回归,但实际上对数几率回归是一种分类学习方法。它不是仅预测出“类别”, 而是可以得到近似概率预测,这对于许多需要利用概率辅助决策的任务很有用。普遍应用于预测一个实例是否属于一个特定类别的概率,比如一封email是垃圾邮件的概率是多少。 因变量可以是二分类的,也可以是多分类的。因为结果是概率的,除了分类外还可以做ranking model。LR的应用场景很多,如点击率预测(CTR)、天气预测、一些电商的购物搭配推荐、一些电商的搜索排序基线等。
对数几率函数是一种“Sigmoid”函数,呈现S型曲线,它将zy值。 对数几率回归公式如下:
z=wTx+b,
其中,Sigmoid函数。
Logistic Regression算法是将线性函数的结果映射到了Sigmoid函数中,即y=11+e(wTx+b)。
Sigmoid函数
下图绘制了Sigmoid函数形状,如图所示,sigmoid函数输出值范围在(0,1)之间,即代表了数据属于某一类别的概率,0.5是作为判别的临界值。
# Sigmoid曲线: import matplotlib.pyplot as plt import numpy as np def Sigmoid(x): return 1.0 / (1.0 + np.exp(-x)) x = np.arange(-10, 10, 0.1) h = Sigmoid(x) # Sigmoid函数 plt.plot(x, h) plt.axvline(0.0, color='k') plt.axhline(y=0.5, ls='dotted', color='k') plt.yticks([0.0, 0.5, 1.0]) # y axis label plt.title(r'Sigmoid函数曲线', fontsize = 15) plt.text(5,0.8,r'$y = \frac{1}{1+e^{-z}}$', fontsize = 18) plt.show()
1.2.IRIS数据集介绍
Iris也称鸢尾花卉数据集,是常用的分类实验数据集,由R.A. Fisher于1936年收集整理的。其中包含3种植物种类,分别是山鸢尾(setosa)变色鸢尾(versicolor)和维吉尼亚鸢尾(virginica),每类50个样本,共150个样本。
该数据集包含4个特征变量,1个类别变量。iris每个样本都包含了4个特征:花萼长度,花萼宽度,花瓣长度,花瓣宽度,以及1个类别变量(label)。我们需要建立一个分类器,分类器可以通过这4个特征来预测鸢尾花卉种类是属于山鸢尾,变色鸢尾还是维吉尼亚鸢尾。其中有一个类别是线性可分的,其余两个类别线性不可分,这在最后的分类结果绘制图中可观察到。
变量名 | 变量解释 | 数据类型 |
---|---|---|
sepal_length | 花萼长度(单位cm | numeric |
sepal_width | 花萼宽度(单位cm) | numeric |
petal_length | 花瓣长度(单位cm) | numeric |
petal_width | 花瓣宽度(单位cm) | numeric |
species | 种类 | categorical |
# 导入所需要的包 import pandas as pd import numpy as np import matplotlib.pyplot as plt import plotly.plotly as py import plotly.graph_objs as go from sklearn.decomposition import PCA from plotly.offline import init_notebook_mode, iplot init_notebook_mode(connected = True)
iris_path = '/home/kesci/input/iris/iris.csv' data = pd.read_csv(iris_path)
data.head()
labels = data.groupby('Species').size().index values = data.groupby('Species').size() trace = go.Pie(labels=labels, values=values) layout = go.Layout(width=350, height=350) fig = go.Figure(data=[trace], layout=layout) iplot(fig)
# Feature Plot groups = data.groupby(by = "Species") means, sds = groups.mean(), groups.std() means.plot(yerr = sds, kind = 'bar', figsize = (9, 5), table = True) plt.show()
col_map = {'setosa': 'orange', 'versicolor': 'green', 'virginica': 'pink'} pd.tools.plotting.scatter_matrix(data.loc[:, 'Sepal.Length':'Petal.Width'] , diagonal = 'kde', color = [col_map[lb] for lb in data['Species']], s = 75, figsize = (11, 6)) plt.show()
from sklearn.datasets import load_iris import matplotlib.pyplot as plt
iris = load_iris()
# data对应了样本的4个特征,共150个样本,即150行x4列的矩阵 print("Iris Dataset contains %s samples in total,%s features."%(iris.data.shape[0], iris.data.shape[1]))
iris.data[:5]
target代表150个样本对应的类别label,即150行x1列的矩阵
样本的类别label含义
Class Label | Meaning |
---|---|
0 | 山鸢尾(setosa) |
1 | 变色鸢尾(versicolor)) |
2 | 维吉尼亚鸢尾(virginica) |
print("Labels' shape %s." %(iris.target.shape))
iris.target
2.2 创建训练集与测试集
在这里我们先前取两列数据(即特征花萼长度与宽度)进行对数几率回归的分类。这个例子借鉴于此。 用train_test_split函数将原始数据集按7:3的比例分成训练集与测试集
from sklearn.model_selection import train_test_split X = iris.data[:, :2] # 取前两列数据 Y = iris.target x_train, x_test, y_train, y_test = train_test_split(X,Y, test_size = 0.3, random_state = 0)
x_train.shape,y_train.shape,x_test.shape, y_test.shape
# 画出训练集数据点 trace = go.Scatter(x = X[:,0], y = X[:,1], mode = 'markers', marker = dict(color = np.random.randn(150),size = 10, colorscale='Viridis',showscale=False)) layout = go.Layout(title = '训练点', xaxis=dict(title='花萼长度 Sepal length', showgrid=False), yaxis=dict(title='花萼宽度 Sepal width',showgrid=False), width = 700, height = 380) fig = go.Figure(data=[trace], layout=layout)
iplot(fig)
2.3. 模型搭建与分类器训练
- 导入模型,调用逻辑回归LogisticRegression()函数。
- penalty: 正则化选择参数(惩罚项的种类),默认方式为L2正则化
- C: 正则项系数的倒数
- solver: 对于多分类任务, 使用‘newton-cg’, ‘sag’, ‘saga’ and ‘lbfgs’ 来解决多项式loss
- multi_class: 默认值‘ovr’适用于二分类问题,对于多分类问题,用‘multinomial’在全局的概率分布上最小化损失
- 训练LogisticRegression分类器
- 调用fit(x,y)的方法来训练模型,其中x为数据的属性,y为所属类型。
- 利用训练得到的模型对数据集进行预测 predict(),返回预测结果。
Tips: 可以通过点击cell中的+来“添加代码片段功能”来直接导入需要的代码
from sklearn.linear_model import LogisticRegression # lr = LogisticRegression(C = 1e5) # C: Inverse of regularization strength lr = LogisticRegression(penalty='l2',solver='newton-cg',multi_class='multinomial') lr.fit(x_train,y_train)
print("Logistic Regression模型训练集的准确率:%.3f" %lr.score(x_train, y_train)) print("Logistic Regression模型测试集的准确率:%.3f" %lr.score(x_test, y_test))
LogisticRegression分类器正确率分析
from sklearn import metrics y_hat = lr.predict(x_test) accuracy = metrics.accuracy_score(y_test, y_hat) #错误率,也就是np.average(y_test==y_pred) print("Logistic Regression模型正确率:%.3f" %accuracy)
target_names = ['setosa', 'versicolor', 'virginica'] print(metrics.classification_report(y_test, y_hat, target_names = target_names))
# Plot the decision boundary. For that, we will assign a color to each # point in the mesh [x_min, x_max]x[y_min, y_max]. x1_min, x1_max = X[:, 0].min() - .