栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【python机器学习基础教程】

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【python机器学习基础教程】

主要使用python和scikit-learn库

必要的库和工具 SciPy

所有代码默认导入以下库:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn

SciPy
如果想保存一个大部分元素都是0的二维数组,可以使用稀疏矩阵:

from scipy import sparse
import numpy as np
#创建一个二维NumPy数组,对角线为 1,其余都为0
eye = np.eye(4)
print("NumPy array:n{}".format(eye))
NumPy array:
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]
#将NumPy数组转换为CSR格式的SciPy稀疏矩阵
#只保存非零元素
sparse_matrix = sparse.csr_matrix(eye)
print("nSciPy sparse CSR matrix:n{}".format(sparse_matrix))
SciPy sparse CSR matrix:
  (0, 0)	1.0
  (1, 1)	1.0
  (2, 2)	1.0
  (3, 3)	1.0
matplotlib

matplotlib是Python主要的科学绘图库,其功能为生成可发布的可视化内容,如折线图、直方图、散点图等。
举例:

%matplotlib inline
import matplotlib.pyplot as plt

#在-10和10之间生成一个数列,共100个数
x=np.linspace(-10,10,100)
#用正弦函数创建第二个数组
y=np.sin(x)
#plot函数绘制一个数组关于另一个数组的折线图
plt.plot(x,y,marker="x")

需要指出的是,这个库在pycharm上并不能跑,要画图的话需要用其他库。

pandas

pandas是用于处理和分析数据的Python库。

import pandas as pd
from IPython.display import display
#创建关于人的简单数据集
data={'Name':["John","Anna","Peter","Linda"],
'location':["New York","Paris","Berlin","London"],
'Age':[24,13,53,33]
}
data_pandas=pd.DataFrame(data)
display(data_pandas)
    Name  location  Age
0   John  New York   24
1   Anna     Paris   13
2  Peter    Berlin   53
3  Linda    London   33

查询这个表格的方法有很多种。举个例子:

#选择年龄大于30的所有行
display(data_pandas[data_pandas.Age >30])

输出结果如下:

    Name location  Age
2  Peter   Berlin   53
3  Linda   London   33
第一个应用:鸢尾花分类

我们的目标是构建一个机器学习模型,可以从这些已知品种的鸢尾花测量数据中进行学习,从而可以预测新鸢尾花的品种。

因为我们有已知品种的鸢尾花的测量数据,所以这是一个监督学习问题。
在这个问题中,我们要在多个选项中预测其中一个(鸢尾花的品种)。这是一个分类问题。
可能的输出(鸢尾花的不同品种)叫做类别。
数据集中的每朵鸢尾花都属于三个类别之一,所以这是一个三分类问题。

单个数据点(一朵鸢尾花)的预期输出是这朵花的品种。对于一个数据点来说,它的品种叫做标签。

from sklearn.datasets import load_iris
iris_dataset=load_iris()
print("Keys of iris_dataset:n{}".format(iris_dataset.keys()))

输出:

Keys of iris_dataset:
dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
print(iris_dataset['DESCR'][:193]+"n...")

输出:

.. _iris_dataset:

Iris plants dataset
--------------------

**Data Set Characteristics:**

    :Number of Instances: 150 (50 in each of three classes)
    :Number of Attributes: 4 numeric, pre
...

data数据的每一行对应一朵花,列代表每朵花的四个测量数据:

print("Shape of data:{}".format(iris_dataset['data'].shape))

输出:

Shape of data:(150, 4)

可以看出,数组中包含150朵不同的花的测量数据。

机器学习中的个体叫做样本,其属性叫做特征。
data数组的形状(shape)是样本数乘以特征数。

训练数据与测试数据

我们使用新数据来评估模型的性能。
通常的做法是将收集好的带标签数据分成两部分,一部分用于构建机器学习模型,叫做训练数据或训练集。其余的数据用来评估模型性能,叫做测试数据、测试集或留出集。

scikit-learn中的train_test_split函数可以打乱数据集并进行拆分。这个函数将75%的行数据及其对应标签作为训练集,剩下25%的数据及其标签作为测试集。
训练集和测试集的分配比例可以随意,但使用25%的数据作为测试集是很好的经验法则。

scikit-learn中的数据通常用大写的X表示,而标签用小写的y表示。我们用大写的X是因为数据是一个二维数组(矩阵),用小写的y是因为目标是一个一维数组(向量)。
对数据调用train_test_split,并对输出结果采用下面这种命名方法:

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(iris_dataset['data'],iris_dataset['target'],random_state=0)

为了确保多次运行同一函数能够得到相同的输出,我们利用random_state参数指定了 随机数生成器的种子。这样函数输出就是固定不变的,所以这行代码的输出始终相同。

train_test_split函数的输出为X_train、X_test、y_train和y_test,它们都是Numpy数组。X_train包含75%的行数据,X_test包含剩下 的25%:

print("X_train shape:{}".format(X_train.shape))
print("y_train shape:{}".format(y_train.shape))

输出:

X_train shape:(112, 4)
y_train shape:(112,)

输入:

print("X_test shape:{}".format(X_test.shape))
print("y_test shape:{}".format(y_test.shape))

输出:

X_test shape:(38, 4)
y_test shape:(38,)

观察数据

检查数据的最佳方法之一是将其可视化。
一种可视化方法是绘制散点图
数据不多——散点图矩阵,从而两两查看所有的特征。

#利用X_train中的数据创建DataFrame
#利用iris_dataset.feature_names中的字符串对数据列进行标记
iris_dataframe=pd.DataFrame(X_train,columns=iris_dataset.feature_names)

#利用DataFrame创建散点图矩阵,按y_train着色
grr=pd.scatter_matrix(iris_dataframe,c=y_train,figsize=(15,15),marker='o',hist_kwds={'bins':20},s=60,alpha=.8,cmap=mglearn.cm3)

运行文件正式代码:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn
import matplotlib.pyplot as plt
from  sklearn.datasets import load_iris
import pandas as pd
iris_dataset=load_iris()
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(iris_dataset['data'],iris_dataset['target'],random_state=0)
#利用X_train中的数据创建DataFrame
#利用iris_dataset.feature_names中的字符串对数据列进行标记
iris_dataframe=pd.DataFrame(X_train,columns=iris_dataset.feature_names)

#利用DataFrame创建散点图矩阵,按y_train着色
grr=pd.plotting.scatter_matrix(iris_dataframe,c=y_train,figsize=(15,15),marker='o',hist_kwds={'bins':20},s=60,alpha=.8,cmap=mglearn.cm3)
plt.show()


从图中可以看出,利用花瓣和花萼的测量数据基本可以将三个类别区分开。

k近邻算法

K近邻分类器
构建此模型只需要保存训练集即可。要对一个新的数据点做出预测,算法会在训练集中寻找与这个新数据点距离最近的数据点,然后将找到的数据点的标签赋值给这个新数据点。

k近邻算法中k的含义是,我们可以考虑训练集里与新数据点最近的任意k个邻居(比如最近的3个或5个邻居),而非只考虑最近的那一个。然后,我们可以用这些邻居中数量最多的类别做出预测。

scikit-learn中所有的机器学习模型都在各自的类中实现,这些类被称为Estimator类。
k近邻分类算法是在neighbors模块的KNeighborsClassifier类中实现的。我们需要将这个类实例化为一个对象,然后才能使用这个模型。
这时我们需要设置模型的参数。
NeighborsClassifier最重要的参数就是邻居的数目,这里我们设为1:

from sklearn.neighbors import KNeighborsClassifier
knn=KNeighborsClassifier(n_neighbors=1)

想要基于训练集来构建模型,需要调用knn对象的fit方法,输入参数为X_train和y_train,二者都是Numpy数组,前者包含训练数据,后者包含相应的训练标签:

knn.fit(X_train,y_train)
做出预测

假设:我们在野外发现了一朵鸢尾花,花萼长5cm宽2.9cm,花瓣长1cm宽0.2cm。这朵鸢尾花属于哪个品种?我们可以将这些数据放在一个Numpy数组中,再次计算形状,样本形状为样本数(1)乘以特征数(4):

X_new = np.array([[5,2.9,1,0.2]])
print("X_new.shape:{}".format(X_new.shape))

输出:

X_new.shape:(1, 4)

我们必须将这朵花的测量数据转换为二维Numpy数组的一行,这是因为scikit-learn的输入数据必须是二维数组。

我们调用knn对象的predict方法来进行预测:

prediction=knn.predict(X_new)
print("Prediction:{}".format(prediction))
print("Predict target name :{}".format(iris_dataset['target_names'][prediction]))

输出:

Prediction:[0]
Predict target name :[‘setosa’]

评估模型

这里需要用到之前创建的测试集,这些数据并没有用于构建模型,但我们知道测试集中每朵鸢尾花的实际品种。

因此,我们可以对测试数据中的每朵鸢尾花进行预测,并将预测结果与标签(已知的品种)进行对比。
我们可以通过计算精度来衡量模型的优劣,精度就是品种预测正确的花所占的比例:

y_pred=knn.predict(X_test)
print("Test set prediction:n{}".format(y_pred))

输出:

Test set prediction:
[2 1 0 2 0 2 0 1 1 1 2 1 1 1 1 0 1 1 0 0 2 1 0 0 2 0 0 1 1 0 2 1 0 2 2 1 0
2]

print("Test set score:{:.2f}".format(np.mean(y_pred==y_test)))

输出:

Test set score:0.97

我们还可以使用knn对象的score方法来计算测试集的精度:

print("Test set score:{:.2f}".format(knn.score(X_test,y_test)))

输出:

Test set score:0.97

模型的精度是0.97,也就是说,对于测试集中的鸢尾花,我们的预测有97%是正确的。

监督学习 分类与回归

监督机器学习问题主要有两种,分别叫做分类和回归。

分类问题的目标是预测类别标签,这些标签来自预定义的可选列表。
分类问题有时分为二分类和多分类。

在二分类问题中,我们通常将其中一个类别称为正类,另一个类别称为反类。

泛化、过拟合与欠拟合

如果一个模型能够对没见过的数据做出准确预测,我们就说它能够从训练集泛化到测试集。
过拟合:训练集上表现很好,不能新数据上的模型——对现有信息量而言过于复杂
欠拟合:过于简单的模型,甚至在训练集上表现就很差。

监督学习算法

一个模拟的二分类数据集示例是forge数据集,它有两个特征。
下列代码将绘制一个散点图,将此数据集中的所有数据点可视化。
图像以第一个特征为x轴,第二个特征为y轴。
每个数据点对应图像中一点,每个点的颜色和形状对于其类别。

#生成数据集
X,y=mglearn.datasets.make_forge()
#数据集绘图
mglearn.discrete_scatter(X[:0],X[:,1],y)
plt.legend(["Class 0","Class 1"],loc=4)
plt.xlabel("First feature")
plt.ylabel("Second feature")
print("X.shape:{}".format(X.shape))


输出:

X.shape:(26,2)

从X.shape可以看出,这个数据集包含26个数据点和2给特征。

用模拟的wave数据集来说明回归算法。
wave数据集只有一个输入特征和一个连续的目标变量(或响应),后者是模型想要预测的对象。
下面绘制的图像中单一特征位于x轴,回归目标(输出)位于y轴。

X,y=mglearn.datasets.make_wave(n_samples=40)
plt.plot(X,y,'o')
plt.ylim(-3,3)
plt.xlabel("Feature")
plt.ylabel("Target")
plt.show()

k近邻 k近邻分类

k-NN算法最简单的版本只考虑一个最近邻,也就是与我们想要预测的数据点最近的训练数据点。
预测结果就是这个训练数据点的已知输出。

mglearn.plots.plot_knn_classification(n_neighbors=1)

除了仅考虑最近邻,还可以考虑任意个(k个)邻居。
3个近邻的例子:

mglearn.plots.plot_knn_classification(n_neighbors=3)


现在看一下如何通过scikit-learn来应用k近邻算法。
首先,将数据分为训练集和测试集,以便评估泛化性能:

from sklearn.model_selection import train_test_split
X,y = mglearn.datasets.make_forge()

X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)

然后,导入类并将其实例化。
这时可以设置参数,比如邻居的个数。
这里我们将其设为3:

from sklearn.neighbors import KNeighborsClassifier
clf=KNeighborsClassifier(n_neighbors=3)

现在,利用训练集对分类器进行拟合。
对于KNeighborsClassifier来说就是保存数据,以便在预测时计算与邻居之间的距离:

clf.fit(X_train,y_train)

调用predict方法来对测试数据进行预测。
对于测试集中的每个数据点,都要计算它在训练集的最近邻,然后找出其中出现次数最多的类别。

print("Test set predictions :{}".format(clf.predict(X_test)))

输出:

Test set predictions :[1 0 1 0 1 0 0]

为了评估模型的泛化能力好坏,我们可以对测试数据和测试标签调用score方法:

print("Test set accuracy :{:.2f}".format(clf.score(X_test,y_test)))

输出:

Test set accuracy :0.86

模型精度约为86%

分析KNeighborsClassifier

对于二维数据集,我们还可以在xy平面上画出所有可能的测试点的预测结果。
我们根据平面中每个点所属的类别对平面进行着色。
这样可以查看决策边界,即算法对类别0和类别1的分界线。

下面代码分别将1个、3个和9个邻居三种情况的决策边界可视化。

fig ,axes = plt.subplots(1,3,figsize=(10,3))

for n_neighbors,ax in zip([1,3,9],axes):
   clf = KNeighborsClassifier(n_neighbors=n_neighbors).fit(X,y)
   mglearn.plots.plot_2d_separator(clf,X,fill=True,eps=0.5,ax=ax,alpha=.4)
   mglearn.discrete_scatter(X[:,0],X[:,1],y,ax=ax)
   ax.set_title("{}neighbor(s)".format(n_neighbors))
   ax.set_xlabel("feature 0")
   ax.set_ylabel("feature 1")
axes[0].legend(loc=3)


从左图可以看出,使用单一邻居绘制的决策边界紧跟着训练数据。随着邻居个数越来越多,决策边界也越来越平滑。
使用更少的邻居对应更高的模型复杂度。

我们来研究一下是否能证实模型复杂度和泛化能力之间的关系。
我们将在现实世界的乳腺癌数据集上进行研究。
先将数据集分成训练集和测试集,然后用不同的邻居个数对训练集和测试集的性能进行评估。

from sklearn.datasets import load_breast_cancer

cancer = load_breast_cancer()
X_train,X_test,y_train,y_test=train_test_split(cancer.data,cancer.target,stratify=cancer.target,random_state=66)
training_accuracy=[]
test_accuracy=[]
neighbors_settings=range(1,11)

for n_neighbors in  neighbors_settings:
  #构建模型
  clf=KNeighborsClassifier(n_neighbors=n_neighbors)
  clf.fit(X_train,y_train)
  #记录数据集精度
  training_accuracy.append(clf.score(X_train,y_train))
  #记录泛化精度
  test_accuracy.append(clf.score(X_test,y_test))
plt.plot(neighbors_settings,training_accuracy,label="training accuracy")
plt.plot(neighbors_settings,test_accuracy,label="test accuracy")
plt.ylabel("Accuracy")
plt.xlabel("n_neighbors")
plt.legend()
plt.show()

k近邻回归

k近邻算法可以用于回归。
我们从单一近邻开始,这次使用wave数据集。
我们添加了3个测试数据点,在x轴上用绿色五角星表示。
利用单一邻居的预测结果就是最近邻的目标值。在图中用蓝色五角星表示:

mglearn.plots.plot_knn_regression(n_neighbors=1)


同样,也可以用多个近邻进行回归。
在使用多个近邻时,预测结果为这些邻居的平均值:

mglearn.plots.plot_knn_regression(n_neighbors=3)


用于回归的k近邻算法在scikit-learn的KNeighborsRegressor类中实现。

from sklearn.neighbors import KNeighborsRegressor
X,y=mglearn.datasets.make_wave(n_samples=40)
#将wave数据集分为训练集和测试集
X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=0)

#模型实例化,并将邻居个数设为3
reg=KNeighborsRegressor(n_neighbors=3)
#利用训练数据和训练目标值来拟合模型
reg.fit(X_train,y_train)

现在可以对测试集进行预测:

print("Test set predictions:n{}".format(reg.predict(X_test)))

Test set predictions:
[-0.05396539 0.35686046 1.13671923 -1.89415682 -1.13881398 -1.63113382
0.35686046 0.91241374 -0.44680446 -1.13881398]

我们还可以用score方法来 评估模型,对于回归问题,这一方法返回的是 R 2 R^2 R2分数。 R 2 R^2 R2分数也叫做决定系数,是回归模型预测的优先度量,位于0到1之间。 R 2 = 1 R^2=1 R2=1对应完美预测, R 2 = 0 R^2=0 R2=0对应常数模型,即总是预测训练集响应(y_train)的平均值:

print("Test set R^2:{:.2f}".format(reg.score(X_test,y_test)))

Test set R^2:0.83

分析KNeighborsRegressor

对于我们的一维数据集,可以查看所有特征值对应的预测结果。
为了便于绘图,我们创建一个由许多点组成的测试数据集:

fig,axes=plt.subplots(1,3,figsize=(15,4))
#创建1000个数据点,在-3和3之间均匀分布
line=np.linspace(-3,3,1000).reshape(-1,1)
for n_neighbors,ax in zip([1,3,9],axes):
#利用1个,3个或9个邻居分别进行预测
   reg=KNeighborsRegressor(n_neighbors=n_neighbors)
   reg.fit(X_train,y_train)
   ax.plot(line,reg.predict(line))
   ax.plot(X_train,y_train,'^',c=mglearn.cm2(0),markersize=8)
   ax.plot(X_test,y_test,'v',c=mglearn.cm2(1),markersize=8)
   ax.set_title(
       "{}neighbor(s)n train score:{:.2f} test score:{:.2f}".format(
     n_neighbors,reg.score(X_train,y_train),
     reg.score(X_test,y_test)))
   ax.set_xlabel("Feature")
   ax.set_ylabel("Target")
axes[0].legend(["Model predictions","Training data/target","Test data/target"],loc="best")

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/839991.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号