我们的目标是构建一个机器学习模型,可以从已知品种的鸢尾花测量数据中进行学习,从而能够预测新鸢尾花的品种。在这个问题中,我们要在多个选项中预测其中一个(鸢尾花的品种)。这是一个分类(classification)问题的示例。可能的输出(鸢尾花的不同品种)叫作类别(class)。数据集中的每朵鸢尾花都属于三个类别之一,所以这是一个三分类问题。
初识数据鸢尾花(Iris)数据集,这是机器学习和统计学中一个经典的数据集。它包含在 scikit-learn 的 datasets 模块中。调用 load_iris 函数来加载数据:
from sklearn.datasets import load_iris
iris_dataset = load_iris()
#load_iris 返回的 iris 对象是一个 Bunch 对象,与字典非常相似,里面包含键和值:
print("Keys of iris_dataset: \n{}".format(iris_dataset.keys()))
#*Keys of iris_dataset:
#dict_keys(['target_names', 'feature_names', 'DESCR', 'data', 'target'])*
#DESCR 键对应的值是数据集的简要说明。
训练数据和测试数据
不能将用于构建模型的数据用于评估模型,这种“记忆”无法告诉我们模型的泛化(generalize)能力如何
将收集好的带标签数据(此例中是 150 朵花的测量数据)分成两部分。一部分数据用于构建机器学习模型,叫作训练数据(training data)或训练集(training set)。其余的数据用来评估模型性能,叫作测试数据(test data)、 测试集(test set)或留出集(hold-out set)
scikit-learn 中的 train_test_split 函数可以打乱数据集并进行拆分,25% 的数据作为测试集是很好的经验法则
from sklearn.datasets import load_iris
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)
#train_test_split 函数利用伪随机数生成器将数据集打乱。
#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))
检查数据
构造模型之前,检查数据,看看不用机器学习能不能轻松完成,或者需要的信息没有包括在数据中。规范数据的格式等。检查数据的最佳方法之一就是将其可视化。一种可视化方法是绘制散点图(scatter plot)。所以我们一次只能绘制两个特征(也可能是3 个)。用这种方法难以对多于 3 个特征的数据集作图。解决这个问题的一种方法是绘制散点图矩阵(pair plot),从而可以两两查看所有的特征。
mglearn库导入(https://blog.csdn.net/leilei9406/article/details/83538117)
pandas中的scatter_matrix函数解释(https://blog.csdn.net/hurry0808/article/details/78573585?locationNum=7&fps=1)
使用散点图矩阵图,可以两两发现特征之间的联系
import mglearn
import pandas as pd
from sklearn.datasets import load_iris
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)
#train_test_split 函数利用伪随机数生成器将数据集打乱。
#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中的数据创建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='0',
hist_kwds={'bins':20},s=60,alpha=8,cmap=mglearn.cm3)
构建第一个模型:k-means
建此模型只需要保存训练集即可。要对一个新的数据点做出预测,算法会在训练集中寻找与这个新数据点距离最近的数据点,然后将找到的数据点的标签赋值给这个新数据点。
k 近邻分类算法是在 neighbors 模块的 KNeighborsClassifier 类中实现的。我们需要将这个类实例化为一个对象,然后才能使用这个模型。这时我们需要设置模型的参数。KNeighborsClassifier 最重要的参数就是邻居的数目,这里我们设为 1:
from sklearn.neighbors import KNeighborsClassifier
knn=KNeighborsClassifier(n_neighbors=1)
knn.fit(X_train,y_train)
#knn 对象对算法进行了封装,既包括用训练数据构建模型的算法,也包括对新数据点进行预测的算法。它还包括算法从训练数据中提取的信息。对于 KNeighborsClassifier 来说,里面只保存了训练集。
#基于训练集来构建模型,需要调用 knn 对象的 fit 方法,输入参数为 X_train 和 y_train,二者都是 NumPy 数组,前者包含训练数据,后者包含相应的训练标签:
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=1, n_neighbors=1, p=2, weights='uniform')
做出预测
X_new = np.array([[5, 2.9, 1, 0.2]])
print("X_new.shape: {}".format(X_new.shape))
#将这朵花的测量数据转换为二维 NumPy 数组的一行,这是因为 scikit-learn的输入数据必须是二维数组。
prediction = knn.predict(X_new)
print("Prediction: {}".format(prediction))
print("Predicted target name: {}".format(iris_dataset['target_names'][prediction]))
评估模型
对测试数据中的每朵鸢尾花进行预测,并将预测结果与标签(已知的品种)进行对比。我们可以通过计算精度(accuracy)来衡量模型的优劣。
y_pred = knn.predict(X_test)
print("Test set predictions:\n {}".format(y_pred))
print("Test set score: {:.2f}".format(np.mean(y_pred == y_test)))
对于这个模型来说,测试集的精度约为 0.97