本文从分类和回归两个方面介绍了基本的监督学习方法,并用Scikit-Learn做了实例演示。

Python那些事——极简Python带你探索分类与回归的奥秘

为何使用人工智能和机器学习?

地球的未来在于人工智能和机器学习。如果对这些技术一无所知,人们很快会发现自己落伍了。世界发展日新月异,每天都发生着不可思议的变化。在人工智能和机器学习中,有许多实现和技术能够解决实时问题。其中,监督学习是最常用的方法之一。

「人工智能的关键在于表示。」——Jeff Hawkins

什么是监督学习?

在监督学习中,我们首先导入包含训练属性和目标属性的数据集。监督学习算法将学习训练样本和其目标变量之间的关系,然后应用习得的关系对无目标属性的全新输入进行分类。

为了阐明监督学习如何工作,让我们考虑一个案例:根据学生的学习时长预测学生的成绩。

数学公式如下:

Y = f(X)+ C

其中,F 代表学生准备考试的时长与考试分数之间的关系。X 是输入(学习时长),Y 是输出(学生在考试中的得分)。C 代表随机误差。

监督学习算法的最终目标是:以最大的准确率预测给定新输入 X 的 Y 值。有几种方法都可以实现监督学习,我们将探索其中一些最常用的方法。

基于给定的数据集,机器学习问题将分为两类:分类和回归。如果给定数据同时具有输入(训练)值和输出(目标)值,那么它属于分类问题。如果数据集有着连续数值属性而没有任何目标标签,那么它属于回归问题。

Classification: Has the output label. Is it a Cat or Dog?Regression: How much will the house sell for?

分类问题

让我们来举例说明。一名医学研究者希望通过分析乳腺癌数据来预测患者应该接受三种治疗方式中的哪一种。这个数据分析任务属于分类,其中构建的模型或分类器需要预测类别的标签,比如「疗法 1」、「疗法 2」、「疗法 3」。

分类问题预测离散且无序的类别标签。这个过程分两个阶段:学习阶段、分类阶段。

分类方法以及如何选择最合适的方法

最常用的算法包括:

1. K 近邻

2. 决策树

3. 朴素贝叶斯

4. 支持向量机

在学习阶段,分类模型通过分析训练集来构建分类器。在分类阶段,模型会预测出给定数据的类别标签。被分析的数据集元组及其相关类别标签被分隔成训练集和测试集。我们从要分析的数据集中随机抽取部分元组构成训练集。剩下的数据自然就是测试集了,且二者相互独立,也就是说测试集不参与训练过程。

测试集用于评估分类器的预测准确率。分类器的准确率指分类器在测试集中作出正确预测的百分比。为了达到更高的准确率,最好的方法是测试不同的算法并针对每一种算法进行调参。最后通过交叉验证可以找出最佳分类器。

为了给任务选择一个好的算法,我们必须考虑不同算法的准确率、训练时间、线性度、参数数量及特殊情况。

运用 Scikit-Learn 在 IRIS 数据集上实现 KNN 算法,根据给定输入预测花的种类。

首先,我们需要深入理解、探索给定数据集,这样才能应用机器学习算法。在本例中,我们使用了从 scikit-learn 导入的 IRIS 数据集。接下来我们边看代码边分析数据集。

请确保你的电脑上已经安装了 Python。然后,请使用 PIP 安装如下程序包:

pip install pandaspip install matplotlibpip install scikit-learn

在下面的代码片段中,我们调用几个 Pandas 中的方法来了解 IRIS 数据集的属性。

输出:

<class ‘sklearn.datasets.base.Bunch’>dict_keys([‘data’, ‘target’, ‘target_names’, ‘DESCR’, ‘feature_names’])]<class ‘numpy.ndarray’> <class ‘numpy.ndarray’>(150, 4)[‘setosa’ ‘versicolor’ ‘virginica’]sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)0 5.1 3.5 1.4 0.21 4.9 3.0 1.4 0.22 4.7 3.2 1.3 0.23 4.6 3.1 1.5 0.24 5.0 3.6 1.4 0.2

scikit-learn 中 的 K 近邻算法

如果一个算法只保存训练集的元组,待收到测试元组后再进行处理,那么它就是懒惰学习算法。该算法只有收到测试数据时才执行泛化,基于测试数据与已保存的训练数据的相似性进行分类。

K 近邻分类器就是一种懒惰学习算法。

KNN 基于类比学习。所谓类比学习,就是通过比较给定的测试元组和与其相似的训练元组来学习。训练元组由 n 个属性来描述。每一个元组表示 n 维空间中的一个点。如此一来,所有的训练元组都保存在 n 维模式空间中。当输入未知元组时,k 近邻分类器在模式空间中搜索最接近未知元组的 k 个训练元组。这 k 个训练元组就是未知元组的 k 个「最近邻」。

「亲密度」由距离度量定义,例如欧式距离。合适的 K 值根据实验而定。

在下面的代码片段中,我们从 sklearn 中导入 KNN 分类器,将其用于我们的输入数据,之后用于对花进行分类。

from sklearn import datasetsfrom sklearn.neighbors import KNeighborsClassifier# Load iris dataset from sklearniris = datasets.load_iris()# Declare an of the KNN classifier class with the value with neighbors.knn = KNeighborsClassifier(n_neighbors=6)# Fit the model with training data and target valuesknn.fit(iris['data'], iris['target'])# Provide data whose class labels are to be predictedX = [ [5.9, 1.0, 5.1, 1.8], [3.4, 2.0, 1.1, 4.8],]# Prints the data providedprint(X)# Store predicted class labels of Xprediction = knn.predict(X)# Prints the predicted class labels of Xprint(prediction)

输出:

[1 1]

这里,

0 对应 Versicolor(杂色鸢尾)

1 对应 Virginica(维吉尼亚鸢尾)

2 对应 Setosa(山鸢尾)

基于给定输入,使用 KNN 分类器,两张图中的花都被预测为 Versicolor。

用于 IRIS 数据集分类的 KNN 算法直观图

Python那些事——极简Python带你探索分类与回归的奥秘

回归

我们通常将确定两个或多个变量之间关系的过程叫做回归。例如,通过给定的输入数据 X 来预测某人的收入。

这里的目标变量是我们要预测的未知变量,连续性指的是 Y 值之间不存在间隙(间断)。

预测收入是一个经典的回归问题。你的输入数据应包括所有可用于预测收入的信息(也叫特征),例如工作时长、教育程度、职位、住所等。

回归模型

最常用的回归模型如下:

  • 线性回归

  • Logistic 回归

  • 多项式回归

线性回归使用最佳拟合直线(即回归线)在因变量 Y 和一或多个自变量 X 之间建立关联。

数学公式如下:

h(xi) = βo + β1 * xi + e

其中 βo 代表截距,β1 代表回归线的斜率,e 是误差项。

图形表示如下:

Python那些事——极简Python带你探索分类与回归的奥秘

Logistic 回归算法应用在因变量属于某一类别的情况。Logistic 回归的思想是找出特征与特定输出概率之间的关系。

数学公式如下:

p(X) = βo + β1 * X

其中,

p(x) = p(y = 1 | x)

图形表示如下:

Python那些事——极简Python带你探索分类与回归的奥秘

多项式回归是回归分析的一种形式。以 x 的 n 次多项式形式对自变量 x 和因变量 y 之间的关系进行建模。

解决线性回归问题

对于数据集 X 及对应的目标值 Y,我们使用普通最小二乘法训练一个线性模型。通过这个模型,我们可以以尽可能小的误差来预测给定未知输入 x 的输出值 y。

给定数据被分隔成训练集和测试集。训练集是有标注的(已加载特征值),因此该算法可以从这些标注样本中学习。测试集没有标注,即你不知道要预测的值。

我们以要训练的一个特征为例,运用线性回归拟合训练集,然后使用测试集进行预测。

在 scikit-learn 中实现线性回归

from sklearn import datasets, linear_modelimport matplotlib.pyplot as pltimport numpy as np# Load the diabetes datasetdiabetes = datasets.load_diabetes()# Use only one feature for trainingdiabetes_X = diabetes.data[:, np.newaxis, 2]# Split the data into training/testing setsdiabetes_X_train = diabetes_X[:-20]diabetes_X_test = diabetes_X[-20:]# Split the targets into training/testing setsdiabetes_y_train = diabetes.target[:-20]diabetes_y_test = diabetes.target[-20:]# Create linear regression objectregr = linear_model.LinearRegression()# Train the model using the training setsregr.fit(diabetes_X_train, diabetes_y_train)# Input dataprint('Input Values')print(diabetes_X_test)# Make predictions using the testing setdiabetes_y_pred = regr.predict(diabetes_X_test)# Predicted Dataprint("Predicted Output Values")print(diabetes_y_pred)# Plot outputsplt.scatter(diabetes_X_test, diabetes_y_test, color='black')plt.plot(diabetes_X_test, diabetes_y_pred, color='red', linewidth=1)plt.show()

输出:

Input Values[[ 0.07786339] [-0.03961813] [ 0.01103904] [-0.04069594] [-0.03422907] [ 0.00564998] [ 0.08864151] [-0.03315126] [-0.05686312] [-0.03099563] [ 0.05522933] [-0.06009656][ 0.00133873] [-0.02345095] [-0.07410811] [ 0.01966154][-0.01590626] [-0.01590626] [ 0.03906215] [-0.0730303 ]]Predicted Output Values[225.9732401 115.74763374 163.27610621 114.73638965 120.80385422 158.21988574 236.08568105 121.81509832 99.56772822 123.83758651 204.73711411 96.53399594 154.17490936 130.91629517 83.3878227 171.36605897137.99500384 137.99500384 189.56845268 84.3990668]undefinedGraph between (diabetes_X_test, diabetes_y_pred) predictions will be continuous on the line equation.(diabetes_X_test, diabetes_y_pred) 预测图是线性且连续的。

Python那些事——极简Python带你探索分类与回归的奥秘

(diabetes_X_test, diabetes_y_pred) 预测图是线性且连续的。

相关文章