本文概述
在本系列的第一篇文章中, 我深入研究了k-最近邻居算法(k-NN)和葡萄酒质量数据集中预处理在机器学习(ML)分类任务中的作用。在那里, 你发现对许多模型性能指标(例如精度)进行居中和缩放数值数据可以提高k-NN的性能。你还看到, 预处理不是在真空中进行的, 只有在面向预测的ML管道中查看时, 才能判断其值。但是, 我们只看到了在单个模型k-NN中进行预处理的重要性。在这种情况下, 我们的模型表现要好得多, 但情况是否总是如此?不必要!在本文中, 我将探讨在另一个基本模型Logistic回归中缩放和集中数值数据的作用。你不妨通过阅读上一篇文章和/或本文底部的术语表来刷新自己。我们将再次探讨葡萄酒质量数据集。本文中的所有示例都将使用Python。如果你不熟悉Python, 可以在这里查看我们的srcmini课程。我将使用熊猫库满足我们的数据框架需求, 并使用scikit-learn满足我们的机器学习需求。
首先, 我将简要介绍回归, 该回归可用于预测数值变量和类的值。我将介绍线性回归, 逻辑回归, 然后使用后者来预测红酒的质量。然后, 你将看到在回归设置中居中和缩放是否有助于我们的模型。
Python回归简介
Python中的线性回归
如上所述, 回归通常用于从一个数值变量的值预测另一个数值的值。例如, 下面我们对Boston住房数据(scikit-learn中的内置数据集)执行线性回归:在这种情况下, 自变量(x轴)是房间数, 因变量(y轴)是价格。
这样的回归如何工作?简而言之, 其机制如下:我们希望将模型\(y = ax + b \)拟合到数据\((x_i, y_i)\), 也就是说, 我们想找到最优的\(a \ )和\(b \), 给出数据。在普通最小二乘(OLS, 迄今为止最常见)的公式中, 假设误差将在因变量中发生。因此, 通过最小化\ [SSE = \ sum_i(y_i-(ax_i + b))^ 2 \]来找到最佳\(a \)和\(b \), 并且通常使用已知的算法来实现此优化作为梯度下降。在这里, 我们对波士顿房屋数据执行简单的线性回归:
# Import necessary packages
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('ggplot')
from sklearn import datasets
from sklearn import linear_model
import numpy as np
# Load data
boston = datasets.load_boston()
yb = boston.target.reshape(-1, 1)
Xb = boston['data'][:, 5].reshape(-1, 1)
# Plot data
plt.scatter(Xb, yb)
plt.ylabel('value of house /1000 ($)')
plt.xlabel('number of rooms')
# Create linear regression object
regr = linear_model.LinearRegression()
# Train the model using the training sets
regr.fit( Xb, yb)
# Plot outputs
plt.scatter(Xb, yb, color='black')
plt.plot(Xb, regr.predict(Xb), color='blue', linewidth=3)
plt.show()
这种回归反映了数据的总体增长趋势, 但没有更多。我们仅使用了一个预测变量, 并且可能使用了更多变量, 在这种情况下, 模型中将有\(n \)个系数\(a_1, \ ldots, a_n \), 每个预测变量一个。值得注意的是, 变量\(a_i \)的大小告诉我们相应变量与目标变量的相关程度。
Python中的逻辑回归
回归也可以用于分类问题。第一个自然的例子是逻辑回归。在二元分类(两个标签)中, 我们可以将标签视为0和1。再次将预测变量表示为\(x \), 则逻辑回归模型由逻辑函数\ [F(x)= \ frac {1} {1 + e ^ {-(ax + b)}}。\]这是S形(S形)曲线, 你可以在下面看到一个示例。对于任何给定的\(x \), 如果\(F(x)<0.5 \), 则逻辑模型预测y = 0, 或者, 如果\(F(X)> 0.5 \), 则模型预测\(y = 1 \)。再一次, 如果我们有多个预测变量, 我们也有\(n \)个系数\(a_1, \ ldots, a_n \), 每个预测变量一个。在这种情况下, 变量\(a_i \)的大小告诉我们相应变量对预测变量的影响程度。
# Synthesize data
X1 = np.random.normal(size=150)
y1 = (X1 > 0).astype(np.float)
X1[X1 > 0] *= 4
X1 += .3 * np.random.normal(size=150)
X1= X1.reshape(-1, 1)
# Run the classifier
clf = linear_model.LogisticRegression()
clf.fit(X1, y1)
# Plot the result
plt.scatter(X1.ravel(), y1, color='black', zorder=20 , alpha = 0.5)
plt.plot(X1_ordered, clf.predict_proba(X1_ordered)[:, 1], color='blue' , linewidth = 3)
plt.ylabel('target variable')
plt.xlabel('predictor variable')
plt.show()
逻辑回归和数据缩放:Wine数据集
现在, 我们已经了解了逻辑回归的机制, 让我们在美味的葡萄酒数据集上实现逻辑回归分类器。我将导入数据并绘制目标变量(好/不好的酒)以作为补充:
# Import necessary modules
from sklearn import linear_model
from sklearn.cross_validation import train_test_split
# Load data
df = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv ' , sep = ';')
X = df.drop('quality' , 1).values #drop target variable
y1 = df['quality'].values
y = y1 <= 5 # is the rating <= 5?
# plot histograms of original target variable
# and aggregated target variable
plt.figure(figsize=(20, 5));
plt.subplot(1, 2, 1 );
plt.hist(y1);
plt.xlabel('original target value')
plt.ylabel('count')
plt.subplot(1, 2, 2);
plt.hist(y)
plt.xlabel('aggregated target value')
plt.show()
现在, 我们运行逻辑回归并查看其性能!
# Split the data into test and training sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
#initial logistic regression model
lr = linear_model.LogisticRegression()
# fit the model
lr = lr.fit(X_train, y_train)
print('Logistic Regression score for training set: %f' % lr.score(X_train, y_train))
from sklearn.metrics import classification_report
y_true, y_pred = y_test, lr.predict(X_test)
print(classification_report(y_true, y_pred))
Logistic Regression score for training set: 0.752932
precision recall f1-score support
False 0.78 0.74 0.76 179
True 0.69 0.74 0.71 141
avg / total 0.74 0.74 0.74 320
开箱即用, 这种逻辑回归的性能优于K-NN(无论有无缩放)。现在让我们缩放数据并执行逻辑回归:
from sklearn.preprocessing import scale
Xs = scale(X)
Xs_train, Xs_test, y_train, y_test = train_test_split(Xs, y, test_size=0.2, random_state=42)
lr_2 = lr.fit(Xs_train, y_train)
print('Scaled Logistic Regression score for test set: %f' % lr_2.score(Xs_test, y_test))
y_true, y_pred = y_test, lr_2.predict(Xs_test)
print(classification_report(y_true, y_pred))
Scaled Logistic Regression score for test set: 0.740625
precision recall f1-score support
False 0.79 0.74 0.76 179
True 0.69 0.74 0.72 141
avg / total 0.74 0.74 0.74 320
这很有趣! Logistic回归的性能并未随数据缩放而提高。为什么不这样做, 特别是当我们看到k-最近Neigbours的性能随着缩放而大大提高时?原因是, 如果存在范围较大的预测变量不会影响目标变量, 则回归算法将使相应的系数\(a_i \)小, 以至于它们对预测的影响不会太大。 K近邻没有这种内置策略, 因此我们非常需要扩展数据。
在下一篇文章中, 我将通过综合数据集, 添加噪声以及了解定心和定标如何根据噪声强度来改变两个模型的性能, 来解开k-NN和逻辑回归中定心和定标的截然不同的结果。
在下面的交互式窗口中, 你可以自己玩数据。如果需要, 可以通过设置sc = True来缩放数据。然后运行整个脚本, 以报告逻辑回归模型的准确性以及分类报告。
词汇表
有监督的学习:从预测变量中推断目标变量的任务。例如, 从预测变量(例如”年龄”, “性”和”吸烟状态”)推断目标变量”心脏病的存在”。
分类任务:如果目标变量由类别(例如”点击”或”非”, “恶性”或”良性”肿瘤)组成, 则监督学习任务就是分类任务。
回归任务:如果目标变量是连续变化的变量(例如房屋价格)或有序的分类变量(例如”葡萄酒质量等级”), 则监督学习任务就是回归任务。
k最近邻居:一种用于分类任务的算法, 其中为数据点分配由其k个最近邻居的多数票决定的标签。
预处理:科学家将使用任意数量的操作数据将其数据转换成更适合他们想要处理的形式。例如, 在对Twitter数据进行情感分析之前, 你可能希望删除所有html标签, 空白, 扩展缩写并将推文拆分为包含它们的单词的列表。
居中和缩放:这两种都是预处理数值数据的形式, 例如, 由数字组成的数据, 而不是类别或字符串。以变量居中表示从每个数据点减去变量的平均值, 以便新变量的平均值为0;缩放变量是将每个数据点乘以一个常数, 以更改数据范围。有关这些重要性的重要性, 请参见本文的正文以及示例。
本文来自Jupyter笔记本。你可以在此处下载笔记本。
评论前必须登录!
注册