首页
学习
活动
专区
工具
TVP
发布

人工智能:有监督学习分类与回归

本节内容翻译自东南大学出版社出版的《人工智能:Python实现(影印版)》第2章内容。

本节将使用监督学习技术来学习数据的分类具体包括:有监督学习和无监督学习,分类的含义,多种数据预处理方法,标签编码,逻辑斯特回归分类器,朴素贝叶斯分类器,混淆矩阵,支持向量机、单变量和多变量线性回归器、支持向量回归机等。

1有监督学习与无监督学习

机器学习是当前人工智能发展的加速器,由机器学习延伸的深度学习表现出异常出色的性能,将实际中的很多问题落地解决。机器学习方法大致可分为有监督学习和无监督学习两种。当然,还有半监督学习等方法在以后的内容中讨论。有监督学习是指基于有标记的训练数据建立机器学习模型的过程。例如,假设我们要建立一个雷达目标识别系统,根据各种观测参数(如大小、速度、外观、形状等)自动识别目标类别。那么,我们需要创建一个包含所有必要细节的雷达目标数据库并对其进行标记,算法根据输入数据和已标记类别学习一个映射,完成给定输入数据预测目标类别的功能。无监督学习是指基于无标记的训练数据建立机器学习模型的过程。从某种意义上说,由于没有可用标签,因此可根据数据本身的特征学习模型。例如,假设我们要建立一个目标数据管理系统,需要将无标签的数据分成若干组,以方便数据的管理。无监督学习的难点在于在学习的标准是未知的,需要尽可能以最好的方式将给定的数据分成若干组。

2分类的含义

有监督学习中的一大主要任务就是分类技术。分类就是将数据划分到已知的若干个类中的一种技术。在机器学习中,分类解决了判定新数据点所属类别的问题。基于给定数据和标签的训练数据集建立分类模型。例如,判定给定的一幅图像是否包含人脸。首先,需要构建一个训练数据集,包含人脸和不是人脸两类图像。然后,根据训练样本来训练模型。最后,将训练好的模型用于预测推断。一个好的分类系统可以准确地预测给定数据的类别。分类技术被广泛用于人脸识别、垃圾邮件识别、推荐引擎等应用中。

基于学习的分类技术需要提供足够多的样本,以便能够推广模型的能力。如果样本数量不足,那么模型可能会过拟合训练数据,这极有可能导致其在未知数据上表现不佳。过拟合是机器学习领域中一个非常普遍的问题,因为模型对数据进行了过渡的学习以至于无法适应训练数据中未观察到的模式。在训练各种机器学习模型时,这个因素是必须考虑和值得注意的。

3数据预处理

现实世界中存在的大量原始数据是无法直接用于机器学习算法的。机器学习算法希望在训练模型前对数据进行一定的格式化。为了准备机器学习算法输入的数据,必须对数据进行预处理并将其转换为正确的格式。常用的数据格式化方法主要有:

l二值化

l平均去除

l缩放

l正常化

为了更好地示例化讲解,我们选择在Python环境下,基于numpy和sklearn进行数据格式化。首先,导入相关开发包:

import numpy as np

from sklearn importpreprocessing

然后,定义如下示例数据:

input_data =np.array([[5.1, -2.9, 3.3],

[-1.2, 7.8, -6.1],

[3.9, 0.4, 2.1],

[7.3, -9.9, -4.5]])

接下来一一介绍上面的几种的预处理技术。

二值化

二值化主要用于将实数值转换为布尔值。

对于上面的示例数据,可直接使用内置Binarizer方法对输入数据进行二值化:

# Binarize data

data_binarized =preprocessing.Binarizer(threshold=2.1).transform(input_data)

print("\nBinarizeddata:\n", data_binarized)

其中threshold=2.1表示以2.1作为阈值,大于等于2.1的数值转化为,小于2.1的数值转化为1。输出结果如下:

Binarized data:

[[1. 0. 1.]

[0. 1. 0.]

[1. 0. 0.]

[1. 0. 0.]]

去除平均值

去除平均值就是从特征向量中去除均值,使得每个特征都以零为中心,消除特征向量中的特征偏差。它是机器学习中常用的预处理技术。

对于上面的示例数据,可直接使用内置scale方法对输入数据进行去除平均值:

# Print mean andstandard deviation

print("\nBEFORE:")

print("Mean=", input_data.mean(axis=0))

print("Stddeviation =", input_data.std(axis=0))

# Remove mean

data_scaled =preprocessing.scale(input_data)

print("\nAFTER:")

print("Mean=", data_scaled.mean(axis=0))

print("Stddeviation =", data_scaled.std(axis=0))

其中,前三行显示输入数据的平均值和标准偏差,后三行显示去除平均值后数据的平均值和标准偏差。

运行代码,输出以下内容:

BEFORE:

Mean = [ 3.775-1.15 -1.3 ]

AFTER:

Std deviation = [1. 1.1.]

从结果可以看出,操作后数据的平均值非常接近,且标准偏差为1。

缩放

在数据测量中,由于特征计量的差异,有的特征数值非常大,而另一些特征数值非常小,这就导致数据特征向量中不同维度上的值可能存在较大的差异。为了给不同维度上的数值提供一个公平的竞争环境,对数据进行缩放操作是非常必要的。我们不希望仅仅因为测量的原因使得特征被人为设置的过大或过小。

对于上面的示例数据,可直接使用内置MinMaxScaler方法对输入数据进行缩放:

# Min max scaling

data_scaler_minmax =preprocessing.MinMaxScaler(feature_range=(0, 1))

data_scaled_minmax =data_scaler_minmax.fit_transform(input_data)

print("\nMin maxscaled data:\n", data_scaled_minmax)

运行代码,得到如下结果:

Min max scaled data:

[0. 1. 0. ]

由结果可见,每行的最大值为1,所有其他值都相对于此值进行了缩放。

归一化

归一化也称为标准化,通过修改特征向量中的值,使得不同样本数据可以在一个共同的尺度上对它们进行测量。在机器学习中,归一化有多种形式,最常见的形式就是通过改变样本数据的值,使它们总和为1。例如:L1归一化,即最小绝对偏差,使每个样本数据的绝对值总和为1。L2归一化,即最小二乘法,使每个样本数据的平方和为1。通常,L1归一化技术被认为比L2归一化技术更稳健,因为L1归一化可以抵抗数据中的异常值。很多时候,数据往往含有异常值,导致无法做任何事情。故而希望在计算过程中能够安全有效地忽略它们。但是,如果问题是一个异常值很重要的问题,那么L2标准化可能是一个更好的选择。

对于上面的示例数据,可直接使用内置normalize方法对输入数据分别进行L1和L2归一化:

# Normalize data

data_normalized_l1 =preprocessing.normalize(input_data, norm='l1')

data_normalized_l2 =preprocessing.normalize(input_data, norm='l2')

print("\nL1normalized data:\n", data_normalized_l1)

print("\nL2normalized data:\n", data_normalized_l2)

输出结果如下:

L1 normalized data:

[ 0.609375 0.0625 0.328125 ]

L2 normalized data:

4标签编码

有监督学习分类时,标签是必不可少的信息。实际中,这些标签可以是文字,数字或其他形式。sklearn中的机器学习函数期望它们是数字。因此,如果标签不是数字,那么就需要将他们表示为数字。

在现实世界中,标签通常是以单词形式出现的,以便于人类的辨识和记忆。要将单词标签转换为数字,我们需要对标签进行编码。标签编码是指将单词标签转换为数字形式的过程。基于sklearn对标签进行编码,导入相关Python包:

from sklearn importpreprocessing

定义一些样本标签:

# Sample input labels

input_labels = ['red','black', 'red', 'green', 'black', 'yellow', 'white']

创建标签编码器对象并训练之:

# Create label encoderand fit the labels

encoder =preprocessing.LabelEncoder()

encoder.fit(input_labels)

输出单词和数字之间的映射:

# Print the mapping

print("\nLabelmapping:")

for i, item inenumerate(encoder.classes_):

print(item, '-->', i)

输出结果如下:

Label mapping:

black --> 0

green --> 1

white --> 3

yellow --> 4

下面编码一组随机排序的标签:

# Encode a set of labelsusing the encoder

test_labels = ['green','red', 'black']

encoded_values =encoder.transform(test_labels)

print("\nLabels=", test_labels)

print("Encodedvalues =", list(encoded_values))

输出结果如下:

Labels = ['green','red', 'black']

Encoded values = [1, 2,0]

让我们来解码一组随机数字:

# Decode a set of valuesusing the encoder

encoded_values = [3, 0,4, 1]

decoded_list =encoder.inverse_transform(encoded_values)

print("\nEncodedvalues =", encoded_values)

print("Decodedlabels =", list(decoded_list))

输出结果如下:

Encoded values = [3, 0,4, 1]

Decoded labels =['white', 'black', 'yellow', 'green']

任务2:检查映射的编码和解码步骤是否正确。

5逻辑斯特回归

逻辑斯特(Logistic)回归是一种分类器,虽然其名称中带有“回归”两字。该分类器用于建模输入变量和输出变量之间的关系。通常输入变量是独立的自变量,输出变量只能取一组固定的离散值,对应于分类问题的类别。

逻辑斯特(Logistic)回归的目标是通过使用逻辑函数估计概率来确定自变量和因变量之间的关系。这个逻辑函数是一个sigmoid曲线,用来构建具有各种参数的函数。它与广义线性模型分析密切相关,我们试图将一条线与一组点相吻合以最小化误差。我们不使用线性回归,而是使用逻辑斯特回归。逻辑回归本身实际上不是一种分类技术,但是我们以这种方式使用它来促进分类,故而称为逻辑斯特(Logistic)回归。由于其简单性,它在机器学习中应用非常普遍。

导入下列软件包:

import numpy as np

from sklearn importlinear_model

import matplotlib.pyplotas plt

用二维向量和相应的标签定义样本输入数据:

# Define sample inputdata

X = np.array([[3.1,7.2], [4, 6.7], [2.9, 8], [5.1, 4.5], [6, 5], [5.6, 5], [3.3, 0.4], [3.9, 0.9],[2.8, 1], [0.5, 3.4], [1, 4], [0.6, 4.9]])

y = np.array([0, 0, 0,1, 1, 1, 2, 2, 2, 3, 3, 3])

使用以上数据来训练分类器。先创建逻辑回归分类器对象:

# Create the logisticregression classifier

classifier =linear_model.LogisticRegression(solver='liblinear', C=1)

使用数据训练分类器:

# Train the classifier

classifier.fit(X, y)

通过查看类的边界来可视化分类器的性能:

# Visualize theperformance of the classifier

visualize_classifier(classifier,X, y)

其中,函数visualize_classifier定义如下:

defvisualize_classifier(classifier, X, y):

# Define the minimum and maximum values forX and Y

# that will be used in the mesh grid

min_x, max_x = X[:, 0].min() - 1.0, X[:,0].max() + 1.0

min_y, max_y = X[:, 1].min() - 1.0, X[:,1].max() + 1.0

# Define the step size to use in plottingthe mesh grid

mesh_step_size = 0.01

# Define the mesh grid of X and Y values

x_vals, y_vals =np.meshgrid(np.arange(min_x, max_x, mesh_step_size), np.arange(min_y, max_y,mesh_step_size))

# Run the classifier on the mesh grid

output =classifier.predict(np.c_[x_vals.ravel(), y_vals.ravel()])

# Reshape the output array

output = output.reshape(x_vals.shape)

# Create a plot

plt.figure()

# Choose a color scheme for the plot

# Overlay the training points on the plot

plt.scatter(X[:, 0], X[:, 1], c=y, s=75,edgecolors='black', linewidth=1, cmap=plt.cm.Paired)

# Specify the boundaries of the plot

plt.xlim(x_vals.min(), x_vals.max())

plt.ylim(y_vals.min(), y_vals.max())

# Specify the ticks on the X and Y axes

plt.xticks((np.arange(int(X[:, 0].min() -1), int(X[:, 0].max() + 1), 1.0)))

plt.yticks((np.arange(int(X[:, 1].min() -1), int(X[:, 1].max() + 1), 1.0)))

plt.show()

该函数将分类器对象,输入数据和标签作为输入参数来创建函数定义,然后定义了将在我们的网格中使用的X和Y方向的最小值和最大值。接着,定义网格的步长并使用最小值和最大值创建网格。这里的网格可以理解为一系列采样点,用于评估函数的值,以便我们可以看到类的边界。再在网格上的所有点上运行分类器,得到计算结果。最后,创建图形,选择配色方案,并覆盖所有点,使用最小值和最大值指定图的边界,添加刻度线并显示图形。结果如下:

如果在下面一行中将C的值更改为100,

classifier =linear_model.LogisticRegression(solver='liblinear', C=100)

则会看到边界变得更加准确:

这里的原因是C对错误分类施加了一定的惩罚,所以该算法对训练数据拟合更好。不过使用这个参数应该小心,因为如果增加太多,它会过拟合训练数据,不会有很好的泛化能力。

6朴素贝叶斯分类器

朴素贝叶斯是一种基于贝叶斯定理构建分类器的技术。贝叶斯定理根据与此事件相关的不同条件描述事件发生的概率。给定一组特征向量和对应类标签来构建一个朴素贝叶斯分类器。假设的数据满足独立同分布假设,即朴素贝叶斯分类器的朴素条件。

给定类变量,我们可以看到给定特征如何影响,而不管它对其他特征的影响如何。例如,如果一只动物被发现,它可能被认为是猎豹,有四条腿,有一条尾巴,运行速度约为70英里/小时。朴素贝叶斯分类器认为每个特征都对结果有独立贡献。结果是指这种动物是猎豹的概率。我们不关心皮肤图案,腿的数量,尾巴的存在和移动速度之间可能存在的相关性。我们来看看如何构建一个朴素贝叶斯分类器。

导入下列软件包:

import numpy as np

from sklearn.naive_bayesimport GaussianNB

from sklearn importcross_validation

下面载入数据,构建朴素贝叶斯分类器,并训练模型,预测数据,计算预测精度,显示分类器:

# Input file containingdata

input_file ='data_multivar_nb.txt'

# Load data from inputfile

data =np.loadtxt(input_file, delimiter=',')

X, y = data[:, :-1],data[:, -1]

# Create Naive Bayesclassifier

classifier =GaussianNB()

# Train the classifier

classifier.fit(X, y)

# Predict the values fortraining data

y_pred =classifier.predict(X)

# Compute accuracy

accuracy = 100.0 * (y ==y_pred).sum() / X.shape[0]

print("Accuracy ofNaive Bayes classifier =", round(accuracy, 2), "%")

# Visualize theperformance of the classifier

visualize_classifier(classifier,X, y)

运行上述代码,得到如下结果和图像:

Accuracy of Naive Bayesclassifier = 99.75 %

对数据进行交叉验证,划分训练数据和测试数据,测试预测精度,绘制预测效果:

# Cross validation

# Split data intotraining and test data

X_train, X_test,y_train, y_test = cross_validation.train_test_split(X, y, test_size=0.2, random_state=3)

classifier_new =GaussianNB()

classifier_new.fit(X_train,y_train)

y_test_pred =classifier_new.predict(X_test)

# compute accuracy ofthe classifier

accuracy = 100.0 *(y_test == y_test_pred).sum() / X_test.shape[0]

print("Accuracy ofthe new classifier =", round(accuracy, 2), "%")

# Visualize theperformance of the classifier

visualize_classifier(classifier_new,X_test, y_test)

运行上面程序,得到如下结果:

Accuracy of the newclassifier = 100.0 %

根据训练的分类器,计算精度、准确率、召回率和F1分数。

# Scoring functions

num_folds = 3

accuracy_values =cross_validation.cross_val_score(classifier,

X, y, scoring='accuracy', cv=num_folds)

print("Accuracy:" + str(round(100*accuracy_values.mean(), 2)) + "%")

precision_values =cross_validation.cross_val_score(classifier,

X, y, scoring='precision_weighted',cv=num_folds)

print("Precision:" + str(round(100*precision_values.mean(), 2)) + "%")

recall_values =cross_validation.cross_val_score(classifier,

X, y, scoring='recall_weighted',cv=num_folds)

print("Recall:" + str(round(100*recall_values.mean(), 2)) + "%")

f1_values =cross_validation.cross_val_score(classifier,

X, y, scoring='f1_weighted',cv=num_folds)

print("F1: " +str(round(100*f1_values.mean(), 2)) + "%")

运行上面程序,得到如下结果:

Accuracy: 99.75%

Precision: 99.76%

Recall: 99.75%

F1: 99.75%

7混淆矩阵

混淆矩阵是用来描述分类器性能的图形或表。它通常由已知的真实数据集的测试数据集中计算得到。将每个类与其他类进行比较,看看有多少个样本被错误分类。在这个表的构建过程中,会涉及到机器学习领域中非常重要的几个关键度量。让我们考虑一个二类分类的情况,输出是或1:

l真正例:预测为1的样本,真实数据也是1。

l真反例:预测为的样本,真实数据也是。

l假正例:预测为1的样本,但真实数据为。也被称为I型误差。

l假反例:预测为的样本,但真实数据为1。也被称为II型误差。

根据问题,我们可能不得不优化我们的算法以减少误报率或漏报率。例如,在一个生物识别系统,避免误报是非常重要的,因为错误的人可能会接触到敏感信息。

如何创建一个混淆矩阵?首先,导入下列软件包:

import numpy as np

import matplotlib.pyplotas plt

from sklearn.metricsimport confusion_matrix

from sklearn.metricsimport classification_report

然后定义真实标签和预测标签:

# Define sample labels

true_labels = [2, 0, 0,2, 4, 4, 1, 0, 3, 3, 3]

pred_labels = [2, 1, 0,2, 4, 3, 1, 0, 1, 3, 3]

根据标签创建混淆矩阵:

# Create confusionmatrix

confusion_mat =confusion_matrix(true_labels, pred_labels)

可视化混淆矩阵:

# Visualize confusionmatrix

plt.title('Confusionmatrix')

plt.colorbar()

ticks = np.arange(5)

plt.xticks(ticks, ticks)

plt.yticks(ticks, ticks)

plt.ylabel('Truelabels')

plt.xlabel('Predictedlabels')

plt.show()

运行程序,结果如下:

同时,输出计算报告:

# Classification report

targets = ['Class-0','Class-1', 'Class-2', 'Class-3', 'Class-4']

print('\n',classification_report(true_labels, pred_labels, target_names=targets))

执行程序,结果如下:

precision recall f1-score support

Class-0 1.00 0.67 0.80 3

Class-1 0.33 1.00 0.50 1

Class-2 1.00 1.00 1.00 2

Class-3 0.67 0.67 0.67 3

Class-4 1.00 0.50 0.67 2

avg / total 0.85 0.73 0.75 11

8支持向量机

支持向量机(SVM)是使用类之间的分离超平面定义的分类器。这个超平面可以理解为一条线的无限维版本。给定标记的训练数据和二类分类问题,SVM找到将训练数据分成两类的最优超平面。该分类器可以很容易地扩展到N类的问题。

考虑一个具有两类点的二维情况。鉴于它是2D的,只需要处理2D平面中的点和线。这比在高维空间中的矢量和超平面更容易可视化。当然,这是SVM问题的简化版本。在将其应用于高维数据之前,了解它并将其可视化是非常重要的。

考虑下图:

给定两类点,要求找到最优超平面来分离两个类。如何定义最优?图中,你可以绘制许多不同的线来分离两类点,但是实线是最好的超平面(分离线),因为它可以最大化每个点与分离线之间的距离。虚线上的点称为支持向量。两条虚线之间的垂直距离称为最大间隔(margin)。

例:使用支持向量机分类收入数据

下面将构建一个支持向量机分类器,根据14个属性来预测给定人的收入。目标是看每年的收入高于或低于5万美元,这是一个二元分类问题。数据为人口普查收入数据集https://archive.ics.uci.edu/ml/datasets/Census+Income。在这个数据集中要注意的一点是,每个数据点是字和数字的混合体。我们不能使用原始格式的数据,因为算法不知道如何处理单词。我们无法使用标签编码器转换所有内容,因为数字数据很有价值。因此,需要使用标签编码器和原始数值数据的组合来构建有效的分类器。

导入下列软件包:

import numpy as np

from sklearn importpreprocessing

from sklearn.svm importLinearSVC

from sklearn.multiclassimport OneVsOneClassifier

from sklearn importcross_validation

载入数据:

# Input file containingdata

input_file ='income_data.txt'

# Read the data

X = []

y = []

count_class1 = 0

count_class2 = 0

max_datapoints = 25000

将数据转化为分类问题:

with open(input_file,'r') as f:

for line in f.readlines():

if count_class1 >= max_datapointsand count_class2 >= max_datapoints:

break

if '?' in line:

continue

data = line[:-1].split(', ')

if data[-1] == '

X.append(data)

count_class1 += 1

if data[-1] == '>50K' andcount_class2

X.append(data)

count_class2 += 1

# Convert to numpy array

X = np.array(X)

将字符数据转化为数值数据:

# Convert string data tonumerical data

label_encoder = []

X_encoded =np.empty(X.shape)

for i,item inenumerate(X[0]):

if item.isdigit():

X_encoded[:, i] = X[:, i]

else:

label_encoder.append(preprocessing.LabelEncoder())

X_encoded[:, i] =label_encoder[-1].fit_transform(X[:, i])

X = X_encoded[:,:-1].astype(int)

y = X_encoded[:,-1].astype(int)

创建支持向量机并训练之:

# Create SVM classifier

classifier =OneVsOneClassifier(LinearSVC(random_state=0))

# Train the classifier

classifier.fit(X, y)

划分训练集和测试集,训练和测试模型,输出测试F1分数:

# Cross validation

X_train, X_test,y_train, y_test = cross_validation.train_test_split(X, y, test_size=0.2,random_state=5)

classifier =OneVsOneClassifier(LinearSVC(random_state=0))

classifier.fit(X_train,y_train)

y_test_pred =classifier.predict(X_test)

# Compute the F1 scoreof the SVM classifier

f1 =cross_validation.cross_val_score(classifier, X, y, scoring='f1_weighted', cv=3)

print("F1 score:" + str(round(100*f1.mean(), 2)) + "%")

给定一个测试点,预测收入结果:

# Predict output for atest datapoint

input_data = ['37','Private', '215646', 'HS-grad', '9', 'Never-married', 'Handlers-cleaners','Not-in-family', 'White', 'Male', '0', '0', '40', 'United-States']

# Encode test datapoint

input_data_encoded =[-1] * len(input_data)

count = 0

for i, item inenumerate(input_data):

ifitem.isdigit():

input_data_encoded[i] =int(input_data[i])

else:

input_data_encoded[i] =int(label_encoder[count].transform([input_data[i]]))

count += 1

input_data_encoded =np.array(input_data_encoded)

# Run classifier onencoded datapoint and print output

predicted_class =classifier.predict(input_data_encoded.reshape(1,-1))

print('The predictresult is:')

print(label_encoder[-1].inverse_transform(predicted_class)[0])

运行代码,则需要几秒钟来训练分类器。完成后,您将在终端上看到以下内容:

F1 score: 70.82%

还将看到测试数据点的输出:

The predict result is:

如果检查该数据点中的值,则会发现它与小于50K类的数据点紧密对应。可以使用各种不同的内核来改变分类器的性能(F1分数、精度或召回),并尝试多个参数组合。

9回归

回归是估计输入和输出变量之间关系的过程。需要注意的是输出变量不同于分类问题,其数值不再是属于一个固定的可能集合,而是连续实数。因此,有无限的可能性。

在回归中,假定输出变量取决于输入变量,则要研究的是它们之间的相关性。因此,输入变量称为独立变量,也称为预测变量;输出变量称为相关变量,也称为标准变量。输入变量不必彼此独立,很多情况下输入变量之间是存在相关性的。

回归分析有助于我们了解在保持其他输入变量不变时改变某些输入变量,输出变量的值如何变化。在线性回归中,假设输入和输出之间的关系是线性的,通过施加该约束,可以使模型更加快速高效。

有时,线性回归不足以解释输入和输出之间的关系。因此,我们会使用多项式回归,即使用多项式来解释输入和输出之间的关系,在计算上更加复杂,但是具有更高的准确性。实际中,根据问题需要,可采用不同形式的回归模型来建模关系。回归常用于预测价格、经济走势、变化等等。

单变量回归

导入相关软件包:

import numpy as np

from sklearn importlinear_model

import sklearn.metricsas sm

import matplotlib.pyplotas plt

然后,载入数据,并按照80%和20%的比例划分训练集合测试集:

# Input file containingdata

input_file ='../data/data_singlevar_regr.txt'

# Read data

data =np.loadtxt(input_file, delimiter=',')

X, y = data[:, :-1],data[:, -1]

# Train and test split

num_training = int(0.8 *len(X))

num_test = len(X) -num_training

# Training data

X_train, y_train =X[:num_training], y[:num_training]

# Test data

X_test, y_test =X[num_training:], y[num_training:]

其中,数据集中特征间以逗号分隔,一个数据占单独一行。

接下来,创建线性回归器,并根据训练数据训练模型,再对测试数据进行测试:

# Create linearregressor object

regressor =linear_model.LinearRegression()

# Train the model usingthe training sets

regressor.fit(X_train, y_train)

# Predict the output

y_test_pred =regressor.predict(X_test)

然后,对结果进行输出:

# Plot outputs

plt.scatter(X_test,y_test, color='green')

plt.plot(X_test,y_test_pred, color='black', linewidth=4)

plt.xticks(())

plt.yticks(())

plt.show()

# Compute performancemetrics

print("Linearregressor performance:")

print("Meanabsolute error =", round(sm.mean_absolute_error(y_test, y_test_pred), 2))

print("Mean squarederror =", round(sm.mean_squared_error(y_test, y_test_pred), 2))

print("Medianabsolute error =", round(sm.median_absolute_error(y_test, y_test_pred),2))

print("Explainvariance score =", round(sm.explained_variance_score(y_test, y_test_pred),2))

print("R2 score=", round(sm.r2_score(y_test, y_test_pred), 2))

运行程序,得到如下结果:

其中直线为预测的线性模型,绿点为实际的测试数据点。相关量化评测结果如下:

Linear regressorperformance:

Mean absolute error =0.59

Mean squared error =0.49

Median absolute error =0.51

Explain variance score =0.86

R2 score = 0.86

对于学习得到的模型可使用pickle先存储起来,后续使用时只需加载模型进行预测:

import pickle

# Model persistence

output_model_file ='model.pkl'

# Save the model

withopen(output_model_file, 'wb') as f:

pickle.dump(regressor, f)

# Load the model

withopen(output_model_file, 'rb') as f:

regressor_model = pickle.load(f)

# Perform prediction ontest data

y_test_pred_new =regressor_model.predict(X_test)

print("\nNew meanabsolute error =", round(sm.mean_absolute_error(y_test, y_test_pred_new),2))

运行程序,得到如下结果:

New mean absolute error = 0.59

多变量回归

多变量回归与单变量类似,只是输入数据的维度为多维,具体代码如下:

import numpy as np

from sklearn import linear_model

import sklearn.metricsas sm

fromsklearn.preprocessing import PolynomialFeatures

# Input file containingdata

input_file ='../data/data_multivar_regr.txt'

# Load the data from theinput file

data =np.loadtxt(input_file, delimiter=',')

X, y = data[:, :-1],data[:, -1]

# Split data intotraining and testing

num_training = int(0.8 *len(X))

num_test = len(X) -num_training

# Training data

X_train, y_train =X[:num_training], y[:num_training]

# Test data

X_test, y_test =X[num_training:], y[num_training:]

# Create the linearregressor model

linear_regressor =linear_model.LinearRegression()

# Train the model usingthe training sets

linear_regressor.fit(X_train,y_train)

# Predict the output

y_test_pred =linear_regressor.predict(X_test)

# Measure performance

print("LinearRegressor performance:")

print("Meanabsolute error =", round(sm.mean_absolute_error(y_test, y_test_pred), 2))

print("Mean squarederror =", round(sm.mean_squared_error(y_test, y_test_pred), 2))

print("Medianabsolute error =", round(sm.median_absolute_error(y_test, y_test_pred),2))

print("Explainedvariance score =", round(sm.explained_variance_score(y_test, y_test_pred),2))

print("R2 score=", round(sm.r2_score(y_test, y_test_pred), 2))

输出结果如下:

Linear Regressorperformance:

Mean absolute error =3.58

Mean squared error =20.31

Median absolute error =2.99

Explained variance score= 0.86

R2 score = 0.86

创建一个自由度为10的多项式回归器,在训练数据上训练回归器。

# Polynomial regression

polynomial =PolynomialFeatures(degree=10)

X_train_transformed =polynomial.fit_transform(X_train)

datapoint = [[7.75,6.35, 5.56]]

poly_datapoint =polynomial.fit_transform(datapoint)

仔细观察,发现该点与文件中第11行数据([7.66,6.29,5.66])非常接近,因此好的预测结果应该接近于41.35。下面创建回归器并训练模型,最后输出结果:

poly_linear_model =linear_model.LinearRegression()

poly_linear_model.fit(X_train_transformed,y_train)

print("\nLinearregression:\n", linear_regressor.predict(datapoint))

print("\nPolynomialregression:\n", poly_linear_model.predict(poly_datapoint))

运行程序,得到如下结果:

Linear regression:

Polynomial regression:

10支持向量回归机

本小节使用支持向量机概念构建一个回归器估计房价,使用sklearn中由13个属性定义的房价数据集,目标是根据这些属性估算房价。

导入下列软件包:

from sklearn importdatasets

from sklearn.svm importSVR

from sklearn.metricsimport mean_squared_error, explained_variance_score

from sklearn.utilsimport shuffle

载入房价数据:

# Load housing data

data =datasets.load_boston()

为了保证分析是无偏的,打乱数据的顺序:

# Shuffle the data

X, y =shuffle(data.data, data.target, random_state=7)

按照80%和20%的比例划分训练集合测试集:

# Split the data intotraining and testing datasets

num_training = int(0.8 *len(X))

X_train, y_train =X[:num_training], y[:num_training]

X_test, y_test =X[num_training:], y[num_training:]

创建一个线性核支持向量回归机,并根据训练数据训练之:

# Create Support VectorRegression model

sv_regressor =SVR(kernel='linear', C=1.0, epsilon=0.1)

# Train Support VectorRegressor

sv_regressor.fit(X_train,y_train)

该回归其参数C为惩罚因子。不适当的因子可能会导致过拟合,影响模型的泛化能力。参数epsilon指定阈值,若预测值与真实值差异小于阈值,则不施加惩罚。

然后对测试数据进行评测,输出均方误差和方差:

# Evaluate performanceof Support Vector Regressor

y_test_pred =sv_regressor.predict(X_test)

mse =mean_squared_error(y_test, y_test_pred)

evs =explained_variance_score(y_test, y_test_pred)

print("\n####Performance ####")

print("Mean squarederror =", round(mse, 2))

print("Explainedvariance score =", round(evs, 2))

输出的评测结果如下:

#### Performance ####

Mean squared error =15.41

Explained variance score= 0.82

使用新的测试数据进行预测:

# Test the regressor ontest datapoint

test_data = [3.7, 0,18.4, 1, 0.87, 5.95, 91, 2.5052, 26, 666, 20.2, 351.34, 15.27]

print("\nPredictedprice:", sv_regressor.predict([test_data])[0])

输出测试结果如下:

总结

本节中,我们学习了有监督和无监督学习之间的区别。讨论了数据分类问题及其解决方法。了解了如何使用各种方法预处理数据。还学习了标签编码以及如何构建标签编码器。讨论了Logistic回归,并建立了logistic回归分类器。理解了朴素贝叶斯分类器是什么,并学习了如何构建它。还学习了如何建立混淆矩阵。最后讨论了支持向量机,并了解如何构建一个支持向量机分类器和支持向量回归器。

参考文献

[1]普拉提克·乔希(Prateek Joshi),人工智能:Python实现(影印版)(英文版),东南大学出版社, 2017.

PS:本节内容由陆工大硕士研究生张洋硕翻译,王一鸣校对。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180518G1NV7000?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券