machine learning是从数据中提取知识,是统计学,人工智能和计算机科学交叉的研究领域。
机器学习算法是能够将决策过程自动化的算法,决策过程是从已知的示例中泛化得到的:
machine learning中,可以将数据想象成表格,每一个实体或者每一行为一个sample,每一列即实体的属性为这个sample的feature。
scikit-learn:
最有名的Python机器学习库,包含目前最先进的机器学习算法。它依赖于另外两个包:NumPy和SciPy,还有一些其他依赖包:
pip install numpy scipy matplotlib ipython scikit-learn pandas
后面简写为sklearn
Jupyter Notebook:
可以在浏览器中运行代码的交互环境,在探索性数据分析方面很有用。
NumPy:
科学计算的基础包之一,功能包括:多维数组,高级数学函数(线性代数运算和傅里叶变换),以及伪随机数生成器。在sklearn中numpy数组是基本的数据结构,所有数据必须转换成numpy数组,数组的所有元素必须是同一类型。
import numpy as np
x = np.array([[1,2,3],[4,5,6]])
>>>x:
[[1 2 3]
[4 5 6]]
SciPy:
SciPy是用于科学计算的函数集合,具有线性代数高级程序,数学函数优化,信号处理,特殊数学函数和统计分布等多项功能。 sklearn利用SciPy中的函数集合来实现算法,这里对我们最重要的是scipy.sparse
,它可以给出稀疏矩阵,即sparse matrice,稀疏矩阵用于保存一个大部分元素都是0的二维数组,也是sklearn中除了numpy的另一个数据表达方式。
matplotlib:
matplotlib是主要的科学绘图库,生成可发布的可视化内容,比如折线图,直方图,散点图等,可以使用%matplotlib notebook
命令将图像直接显示在浏览器中,还可以提供交互环境。
%matplotlib inline
import matplotlib.pyplot as plt
x = np.linespace(-10, 10, 100) # 创建一个-10到10之间的一个共100个数的数列
y = np.sin(x)
plt.plot(x, y, marker="x") # 绘制一个数组关于另一个数组的折线图
pandas:
pandas是用于处理和分析数据的库,基于一种叫DataFrame的数据结构,类似于excel表格,pandas中包含了大量用于修改表格和操作表格的方法,还可以像sql那样对表格进行查询和连接,而且pandas接受各种数据格式,每一列数据的类型都可以完全不一样。总而言之,pandas的功能及其强大,可以去额外学习它。
import pandas as pd
data = {'Name': ["John", "Anna", "Peter", "Linda"],
'Location' : ["New York", "Paris", "Berlin", "London"],
'Age' : [24, 13, 53, 33]
}
data_pandas = pd.DataFrame(data)
# IPython.display allows "pretty printing" of dataframes
# in the Jupyter notebook
display(data_pandas)
上述代码会生成一个美观的表格。查询这个表格的方法:
display(data_pandas[data_pandas.Age > 30])
这是一个花分类的应用:
现有每朵花的一些数据,即花瓣的长和宽,花萼的长和宽,单位为cm,这些花已经被鉴定为属于setosa, versicolor, virginica三个品种之一。
目标: 假设我们现在会在野外遇到这三种花,我们需要构造一个ML模型,从已有的数据中学习,从而预测新的野花的品种。因为我们已经sample花的数据和品种,所以这是一个监督学习。
这是一个classification问题,可能的输出都是一个类别class,数据中的每朵花都是这三个类别之一,所以这是一个三分类的问题。一朵花就是一个数据点,他的品种为标签label。
由于这些数据是ML和统计学中的一个经典的数据集,所以这个数据集被包含在了sklearn的datasets模块中,所以我们可以直接调用这些数据。
from sklearn.datasets import load_iris
iris_dataset = load_iris() # 这里返回的是一个bunch对象,类似与字典,里面是键值对
print("Keys of iris_dataset:\n", iris_dataset.keys())
>>>Keys of iris_dataset:
dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename']) # descr是数据集的简要说明
print("Target names:", iris_dataset['target_names']) #target_name的值是一个数组,里面是我们要预测的花的品种
>>> Target names: ['setosa' 'versicolor' 'virginica']
print("Feature names:\n", iris_dataset['feature_names']) #feature_name是一个字符串列表,对每一个特征feature有说明
>>> Feature names:
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
print("Shape of data:", iris_dataset['data'].shape) #data数组的形状shape是sample x feature的数量,永远遵循这个约定
>>> Shape of data: (150, 4)
print("First five rows of data:\n", iris_dataset['data'][:5]) # 打印出来前五个sample的feature数据
>>> First five rows of data:
[[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]]
print("Target:\n", iris_dataset['target']) # target是一维数组,每朵花对应其中的一个数据,品种被转换成了0,1,2三个整数。
>>> Target:
[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]
模型是否适用?–训练数据与测试数据:
如果我们想使用上面的数据构建一个ML模型,用于预测新测量的花的品种,但是在将模型应用于新的测量数据之前,我们需要知道这个模型是否有效。
但是很不幸的是我们不能将用于构建模型的数据在评估模型上使用,因为我们的模型会知道整个数据集的结果,所以一定会得到正确的预测结果。所以这种模型的记忆能力无法衡量这个模型的泛化generalize 能力。
所以我们必须使用新数据即模型没有见过的数据来评估模型的性能,那么我们可以将收集好的数据分为两部分,一部分用来构建机器学习模型,即训练数据training data/set。另一部分的数据用来评估模型的性能,即测试数据test data/set。那么怎么划分这些数据呢?sklearn中有train_test_split
函数可以打乱数据集并且按照75%为训练数据,25%为测试数据的方式来拆分数据集,这个比例是可以修改的,但是默认的这个比例是最好的,在机器学习中,数据通常用大写的X表示,数据对应的标签用小写的y表示。
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)
检查数据:
下一步就是检查数据了,需要观察数据是否正确。最好的方式是将数据可视化:
iris_dataframe = pd.DataFrame(X_train, columns=iris_dataset.feature_names) # 我们首先将numpy数组转换成pandas的dataform,
pd.plotting.scatter_matrix(iris_dataframe, c=y_train, figsize=(15, 15), # 使用dataform创建散点图矩阵
marker='o', hist_kwds={'bins': 20}, s=60,
alpha=.8, cmap=mglearn.cm3)
构建模型 – k近邻算法:
调用fit
方法构建模型
k近邻算法:这个模型只需要保存训练集就可以了,如果要对一个新的数据点做出预测,算法只需要在这个训练集中寻找与这个新的数据点距离最近的数据点,然后将找到的这个sample的标签直接给这个需要预测的数据点就可以了。这个k的含义是,在数据集中找到与这个新数据点最近的任意k个邻居,然后找到这些邻居里面数量最多的类别,将这个类别赋予给新的数据点。
from sklearn.neighbors import KNeighborsClassifier # sklearn中所有的机器学习模型都在各自的类中实现
knn = KNeighborsClassifier(n_neighbors=1) # 我们将这个类实例化为一个对象,我们才能使用这个模型,这里设置邻居的数量为1
knn.fit(X_train, y_train) # 基于训练集构建模型,这里返回的是knn对象本身并做了原处修改,表明knn模型已经创建
对新数据做出预测:
调用predict
方法做出预测
X_new = np.array([[5, 2.9, 1, 0.2]]) # 将一朵花的数据转换为二维数组numpy中的一行,这是因为sklearn只接受二维数组
print("X_new.shape:", X_new.shape)
>>> X_new.shape: (1, 4)
prediction = knn.predict(X_new) # 生成一个预测结果list,因为只有一朵花,所以list中只有一个数字
print("Prediction:", prediction)
print("Predicted target name:", iris_dataset['target_names'][prediction])
>>> Prediction: [0]
Predicted target name: ['setosa']
现在我们的模型做出了预测为这朵花编号为0,那么我们是否能相信这个预测的结果呢?
评估模型:
调用score
方法算出模型的精确度
这里就要用到之前预留的test data了,因为里面的数据不被模型知道,并且我们已知数据对应的标签。所以我们可以通过模型对test data中的数据进行预测,然后对比我们已知的标签,计算精度accuracy来评估这个模型:
y_pred = knn.predict(X_test) # 这是第一种方法,根据模型算出测试数据的标签
print("Test set score: {:.2f}".format(np.mean(y_pred == y_test))) #将预测出来的标签跟已知的正确标签做比较
>>> Test set score: 0.97
print("Test set score: {:.2f}".format(knn.score(X_test, y_test))) # 第二种方法是直接使用score算出accuracy
>>> Test set score: 0.97