机器学习笔记2 – sklearn之iris数据集
2017-12-26 16:52
393 查看
前言
本篇我会使用scikit-learn这个开源机器学习库来对iris数据集进行分类练习。我将分别使用两种不同的
scikit-learn内置算法——
Decision Tree(决策树)和
kNN(邻近算法),随后我也会尝试自己实现
kNN算法。目前为止,我还是在机器学习的入门阶段,文章中暂不详细解释算法原理,如果想了解细节信息可自行搜索。
代码分解
读取数据集
scikit-learn中预制了很多经典数据集,非常方便我们自己练习用。使用方式也很容易:
# 引入datasets from sklearn import datasets # 获取所需数据集 iris = datasets.load_iris()
load_iris返回的结果有如下属性:
feature_names - 分别为:
sepal length (cm),
sepal width (cm),
petal length (cm)和
petal width (cm)
data - 每行的数据,一共四列,每一列映射为
feature_names中对应的值
target - 每行数据对应的分类结果值(也就是每行数据的
label值),其值为[0,1,2]
target_names - target的值对应的名称,其值为['setosa' 'versicolor' 'virginica']
分离数据
监督学习可以用一个简单的数学公式来代表:
y = f(X)
按上一篇中的相关术语描述就是已知
X(features),通过方法
f(classifier)求
y(label)。
按照这个思路,我将
iris数据分离为:
# X = features X = iris.data # y = label y = iris.target
那如何来使用数据呢?因为只有150行数据,所以为了验证算法的正确性,需要将数据分成两部分:
训练数据和
测试数据,很幸运的是
scikit-learn也提供了方便分离数据的方法
train_test_split,我将数据分离成
60%(即90条数据)用于训练,
40%(即60条数据)用于测试,代码如下:
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.6)
内置算法——Decision Tree(决策树)
上一篇中已经用过决策树,使用决策树的代码简单如下:# Decision tree classifier # 生成决策树 my_classification = tree.DecisionTreeClassifier() # 训练 my_classification.fit(X_train, y_train) # 预测 predictions = my_classification.predict(X_test)
通过决策树算法,最终得到的模型的准确率有多少呢?这个时候可以使用
scikit-learn的
accuracy_score方法:
# 获得预测准确率 print(accuracy_score(y_test, predictions))
由于train_test_split是随机切分数据,因此最终跑出来的准确率不是一个固定值
内置算法——kNN(邻近算法)
kNN算法就是选取k个最近邻居来归类样本值的方法,这是最简单的一种分类算法,当然缺点也很明显,必须循环计算测试样本值和所有的样本之间的距离,运行效率比较低。在选用kNN算法的时候,k值最好是
奇数,偶数值会造成无法归到唯一类的情况(属于不同分类的概率正好相等)。
只需在上述分离数据之后,将决策树算法的代码替换为:
# N neighbors classifier # 生成kNN my_classification2 = KNeighborsClassifier(n_neighbors=5) # 训练 my_classification2.fit(X_train, y_train) # 预测 predictions2 = my_classification2.predict(X_test) # 获得预测准确率 print(accuracy_score(y_test, predictions2))
由于train_test_split是随机切分数据,因此最终跑出来的准确率不是一个固定值。而且由于算法不同,即便是相同的数据,跑出来的准确率也和决策树跑出来的不同。
自己实现kNN
基本思路是沿用上述内置kNN算法的代码,重新实现KNeighborsClassifier,称之为
MyKNN好了。除了初始化函数之外,还需要
fit和
predict这两个方法,并且方法签名和原先的保持一致,所以
MyKNN类的基本结构如下:
class MyKNN: def __init__(self, n_neighbors=5): pass def fit(self, X_train, y_train): pass def predict(self, X_test): pass
实现__init__
初始化方法仅需初始化几个参数以便后续使用:def __init__(self, n_neighbors=5): self.n_neighbors = n_neighbors self.X_train = None self.y_train = None
实现fit
在这里我简单处理该方法,由于原先fit方法包含了X和y两个参数,因此沿用该方法签名,这样就不需要改动其他代码了:def fit(self, X_train, y_train): self.X_train = X_train self.y_train = y_train
实现predict
我需要在该方法中遍历计算测试数据和训练数据之间的距离,两点之间的距离可以使用欧几里得公式,因此需要先定义一个外部方法my_euclidean:
def my_euclidean(a, b): return distance.euclidean(a, b)
我需要计算当前测试数据与K个最近距离的训练数据之间的值,然后看一下这K个数据中,最多的分类是哪种,则可认为测试数据也属于该种分类(概率最高)。因此先定义一个私有方法
__closest:
def __closest(self, row): all_labels = [] for i in range(0, len(self.X_train)): dist = my_euclidean(row, self.X_train[i]) # 获取k个最近距离的邻居,格式为(distance, index)的tuple集合 all_labels = self.__append_neighbors(all_labels, (dist, i)) # 将k个距离最近的邻居,映射为label的集合 nearest_ones = np.array([self.y_train[idx] for val, idx in all_labels]) # 使用numpy的unique方法,分组计算label的唯一值及其对应的值第一次出现的index和值的计数 # 例: elements = [1, 2], elements_index = [3,0], elements_count = [1, 4] 这个结合表示: # elements = [1, 2] : 出现了1和2两种类型的数据 # elements_index = [3,0] : 1第一次出现的index是3, 2第一次出现的index是0 # elements_count = [1, 4] : 1共出现了1次, 2共出现了4次 elements, elements_index, elements_count = np.unique(nearest_ones, return_counts=True, return_index=True) # 返回最大可能性的那种类型的label值 return elements[list(elements_count).index(max(elements_count))]
为了提升性能,我定义了
__append_neighbors方法,该方法将当前
距离-序号的tuple加入到数组中并按升序排序,最终只截取前k个值,可以用python的特性很容易实现该逻辑:
def __append_neighbors(self, arr, item): if len(arr) <= self.n_neighbors: arr.append(item) return sorted(arr, key=lambda tup: tup[0])[:self.n_neighbors]
后记
短短几行代码就实现了自己的kNN算法,我本地跑下来的准确率在95%以上。
需要完整代码可以在我的GitHub上找到。
本文在我的博客园和我的个人博客上同步发布,作者保留版权,转载请注明来源。
相关文章推荐
- Spark 机器学习实践 :Iris数据集的分类
- [Java][机器学习]用决策树分类算法对Iris花数据集进行处理
- 学习笔记TF067:TensorFlow Serving、Flod、计算加速,机器学习评测体系,公开数据集
- 机器学习iris数据集导入
- 机器学习笔记(十)大型数据集的学习
- Coursera 机器学习(by Andrew Ng)课程学习笔记 Week 6(二)——误差分析与数据集偏斜处理
- TensorFlow官方教程学习笔记之2-用于机器学习初学者学习的MNIST数据集(MNIST For ML Beginners)
- 机器学习笔记:初识sklearn(二)
- 使用sklearn中的Iris植物分类数据集进行特征检验与预测分析
- [机器学习]Scikit-Learn模块学习笔记——数据集模块datasets
- 机器学习:sklearn数据集与机器学习组成
- 机器学习笔记(4)---K-近邻算法(2)---使用sklearn中的KNN算法
- Python机器学习——Sklearn——划分数据集——交叉检验
- 【学习笔记】机器学习之用TensorFlow cnn 测试CIFAR-10数据集
- 【机器学习】SVM iris数据集实现2
- 机器学习笔记(14)——sklearn降维方法举例(RandomProjection,TSVD,t-SNE)
- 机器学习笔记:初识sklearn(一)
- 机器学习笔记3-拆分数据集和训练集
- 机器学习入门实战——感知机算法实战Iris数据集
- 【机器学习】Iris Data Set(鸢尾属植物数据集)