用逻辑回归实现鸢尾花数据集分类(1)

匿名 (未验证) 提交于 2019-12-03 00:19:01

鸢尾花数据集的分类问题指导 -- 对数几率回归(逻辑回归)问题研究 (1)

这一篇Notebook是应用对数几率回归(Logit Regression)对鸢尾花数据集进行品种分类的。首先会带大家探索一下数据集中的特征,类别信息。然后带大家从入门与进阶来学习应用逻辑回归分类。

1.背景介绍

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() 
/opt/conda/lib/python3.5/site-packages/matplotlib/font_manager.py:278: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.   'Matplotlib is building the font cache using fc-list. ' 

1.2.IRIS数据集介绍

Iris也称鸢尾花卉数据集,是常用的分类实验数据集,由R.A. Fisher于1936年收集整理的。其中包含3种植物种类,分别是山鸢尾(setosa)变色鸢尾(versicolor)和维吉尼亚鸢尾(virginica),每类50个样本,共150个样本。

该数据集包含4个特征变量,1个类别变量。iris每个样本都包含了4个特征:花萼长度,花萼宽度,花瓣长度,花瓣宽度,以及1个类别变量(label)。我们需要建立一个分类器,分类器可以通过这4个特征来预测鸢尾花卉种类是属于山鸢尾,变色鸢尾还是维吉尼亚鸢尾。其中有一个类别是线性可分的,其余两个类别线性不可分,这在最后的分类结果绘制图中可观察到。

变量名变量解释数据类型
sepal_length花萼长度(单位cmnumeric
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) 

1.2.1. 数据集预览

iris_path = '/home/kesci/input/iris/iris.csv' data = pd.read_csv(iris_path) 
data.head() 
Out[6]:
Sepal.LengthSepal.WidthPetal.LengthPetal.WidthSpecies
05.13.51.40.2setosa
14.93.01.40.2setosa
24.73.21.30.2setosa
34.63.11.50.2setosa
45.03.61.40.2setosa

1.2.2. 鸢尾花三类品种数量的饼图

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) 
33.3%33.3%33.3%
setosaversicolorvirginica
# 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() 

1.2.3. 绘制数据集的特征散点图

特征对两两之间的相关性散点图: 如图所示,特征散点图成对角分布,4个特征两两组合(任意两个特征作为x轴,y轴),不同品种的花用不同颜色标注:setosa(橙色),versicolor(绿色),virginica(粉色)。共有12种组合,其实只有6种,因为另外6种与之对称。

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() 
/opt/conda/lib/python3.5/site-packages/ipykernel_launcher.py:3: FutureWarning:  'pandas.tools.plotting.scatter_matrix' is deprecated, import 'pandas.plotting.scatter_matrix' instead.  

2. Getting Started

2.1. 导入鸢尾花数据集矩阵

用逻辑回归实现鸢尾花数据集分类(2)

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 Dataset contains 150 samples in total,4 features. 
iris.data[:5] 
Out[13]:
array([[5.1, 3.5, 1.4, 0.2],        [4.9, 3. , 1.4, 0.2],        [4.7, 3.2, 1.3, 0.2],        [4.6, 3.1, 1.5, 0.2],        [5. , 3.6, 1.4, 0.2]])

target代表150个样本对应的类别label,即150行x1列的矩阵

样本的类别label含义

Class LabelMeaning
0山鸢尾(setosa)
1变色鸢尾(versicolor))
2维吉尼亚鸢尾(virginica)
print("Labels' shape %s." %(iris.target.shape)) 
Labels' shape 150. 
iris.target 
Out[15]:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

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 
Out[17]:
((105, 2), (105,), (45, 2), (45,))

绘制前两列数据的散点图

# 画出训练集数据点 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) 
567822.533.544.5
训练点花萼长度 Sepal length花萼宽度 Sepal width

2.3. 模型搭建与分类器训练

  1. 导入模型,调用逻辑回归LogisticRegression()函数。
    • penalty: 正则化选择参数(惩罚项的种类),默认方式为L2正则化
    • C: 正则项系数的倒数
    • solver: 对于多分类任务, 使用‘newton-cg’, ‘sag’, ‘saga’ and ‘lbfgs’ 来解决多项式loss
    • multi_class: 默认值‘ovr’适用于二分类问题,对于多分类问题,用‘multinomial’在全局的概率分布上最小化损失
  2. 训练LogisticRegression分类器
    • 调用fit(x,y)的方法来训练模型,其中x为数据的属性,y为所属类型。
  3. 利用训练得到的模型对数据集进行预测 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) 
Out[20]:
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,           intercept_scaling=1, max_iter=100, multi_class='multinomial',           n_jobs=1, penalty='l2', random_state=None, solver='newton-cg',           tol=0.0001, verbose=0, warm_start=False)

2.4. 模型评估

print("Logistic Regression模型训练集的准确率:%.3f" %lr.score(x_train, y_train)) print("Logistic Regression模型测试集的准确率:%.3f" %lr.score(x_test, y_test)) 
Logistic Regression模型训练集的准确率:0.829 Logistic Regression模型测试集的准确率:0.822 

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) 
Logistic Regression模型正确率:0.822 
target_names = ['setosa', 'versicolor', 'virginica'] print(metrics.classification_report(y_test, y_hat, target_names = target_names)) 
             precision    recall  f1-score   support       setosa       1.00      1.00      1.00        16  versicolor       0.81      0.72      0.76        18   virginica       0.62      0.73      0.67        11  avg / total       0.83      0.82      0.82        45  

2.5. 可视化分类结果

绘制图像

下图会绘制逻辑回归分类器在鸢尾花数据集上的决策边界,不同类别的数据点用不同颜色标注。 为了能可视化分类效果,我们会画出决策边界(decision boundry)。

1.确定坐标轴范围,x,y轴各表示一个特征

- 先取二维数组的第一列特征(花萼长度)的最大最小值和步长h = .02生成数组, - 再取二维数组的第二列特征(花萼宽度)的最大最小值和步长h = .02生成数组,  

最后由meshgrid()函数在网格[x_min, x_max] x [y_min, y_max] 中绘制出。生成两个网格矩阵x1, x2

# 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() - .        
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!