前言

本篇我会使用scikit-learn这个开源机器学习库来对iris数据集进行分类练习。

我将分别使用两种不同的scikit-learn内置算法——Decision Tree(决策树)kNN(邻近算法),随后我也会尝试自己实现kNN算法。目前为止,我还是在机器学习的入门阶段,文章中暂不详细解释算法原理,如果想了解细节信息可自行搜索。

代码分解

读取数据集

scikit-learn中预制了很多经典数据集,非常方便我们自己练习用。使用方式也很容易:

  1. # 引入datasets
  2. from sklearn import datasets
  3. # 获取所需数据集
  4. 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数据分离为:

  1. # X = features
  2. X = iris.data
  3. # y = label
  4. y = iris.target

那如何来使用数据呢?因为只有150行数据,所以为了验证算法的正确性,需要将数据分成两部分:训练数据测试数据,很幸运的是scikit-learn也提供了方便分离数据的方法train_test_split,我将数据分离成60%(即90条数据)用于训练,40%(即60条数据)用于测试,代码如下:

  1. from sklearn.model_selection import train_test_split
  2. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.6)

内置算法——Decision Tree(决策树)

上一篇中已经用过决策树,使用决策树的代码简单如下:

  1. # Decision tree classifier
  2. # 生成决策树
  3. my_classification = tree.DecisionTreeClassifier()
  4. # 训练
  5. my_classification.fit(X_train, y_train)
  6. # 预测
  7. predictions = my_classification.predict(X_test)

通过决策树算法,最终得到的模型的准确率有多少呢?这个时候可以使用scikit-learnaccuracy_score方法:

  1. # 获得预测准确率
  2. print(accuracy_score(y_test, predictions))

由于train_test_split是随机切分数据,因此最终跑出来的准确率不是一个固定值

内置算法——kNN(邻近算法)

kNN算法就是选取k个最近邻居来归类样本值的方法,这是最简单的一种分类算法,当然缺点也很明显,必须循环计算测试样本值和所有的样本之间的距离,运行效率比较低。

在选用kNN算法的时候,k值最好是奇数,偶数值会造成无法归到唯一类的情况(属于不同分类的概率正好相等)。

只需在上述分离数据之后,将决策树算法的代码替换为:

  1. # N neighbors classifier
  2. # 生成kNN
  3. my_classification2 = KNeighborsClassifier(n_neighbors=5)
  4. # 训练
  5. my_classification2.fit(X_train, y_train)
  6. # 预测
  7. predictions2 = my_classification2.predict(X_test)
  8. # 获得预测准确率
  9. print(accuracy_score(y_test, predictions2))

由于train_test_split是随机切分数据,因此最终跑出来的准确率不是一个固定值。而且由于算法不同,即便是相同的数据,跑出来的准确率也和决策树跑出来的不同。

自己实现kNN

基本思路是沿用上述内置kNN算法的代码,重新实现KNeighborsClassifier,称之为MyKNN好了。除了初始化函数之外,还需要fitpredict这两个方法,并且方法签名和原先的保持一致,所以MyKNN类的基本结构如下:

  1. class MyKNN:
  2. def __init__(self, n_neighbors=5):
  3. pass
  4. def fit(self, X_train, y_train):
  5. pass
  6. def predict(self, X_test):
  7. pass

实现_init_

初始化方法仅需初始化几个参数以便后续使用:

  1. def __init__(self, n_neighbors=5):
  2. self.n_neighbors = n_neighbors
  3. self.X_train = None
  4. self.y_train = None

实现fit

在这里我简单处理该方法,由于原先fit方法包含了X和y两个参数,因此沿用该方法签名,这样就不需要改动其他代码了:

  1. def fit(self, X_train, y_train):
  2. self.X_train = X_train
  3. self.y_train = y_train

实现predict

我需要在该方法中遍历计算测试数据和训练数据之间的距离,两点之间的距离可以使用欧几里得公式,因此需要先定义一个外部方法my_euclidean

  1. def my_euclidean(a, b):
  2. return distance.euclidean(a, b)

我需要计算当前测试数据与K个最近距离的训练数据之间的值,然后看一下这K个数据中,最多的分类是哪种,则可认为测试数据也属于该种分类(概率最高)。因此先定义一个私有方法__closest

  1. def __closest(self, row):
  2. all_labels = []
  3. for i in range(0, len(self.X_train)):
  4. dist = my_euclidean(row, self.X_train[i])
  5. # 获取k个最近距离的邻居,格式为(distance, index)的tuple集合
  6. all_labels = self.__append_neighbors(all_labels, (dist, i))
  7. # 将k个距离最近的邻居,映射为label的集合
  8. nearest_ones = np.array([self.y_train[idx] for val, idx in all_labels])
  9. # 使用numpy的unique方法,分组计算label的唯一值及其对应的值第一次出现的index和值的计数
  10. # 例: elements = [1, 2], elements_index = [3,0], elements_count = [1, 4] 这个结合表示:
  11. # elements = [1, 2] : 出现了1和2两种类型的数据
  12. # elements_index = [3,0] : 1第一次出现的index是3, 2第一次出现的index是0
  13. # elements_count = [1, 4] : 1共出现了1次, 2共出现了4次
  14. elements, elements_index, elements_count = np.unique(nearest_ones, return_counts=True, return_index=True)
  15. # 返回最大可能性的那种类型的label值
  16. return elements[list(elements_count).index(max(elements_count))]

为了提升性能,我定义了__append_neighbors方法,该方法将当前距离-序号的tuple加入到数组中并按升序排序,最终只截取前k个值,可以用python的特性很容易实现该逻辑:

  1. def __append_neighbors(self, arr, item):
  2. if len(arr) <= self.n_neighbors:
  3. arr.append(item)
  4. return sorted(arr, key=lambda tup: tup[0])[:self.n_neighbors]

后记

短短几行代码就实现了自己的kNN算法,我本地跑下来的准确率在95%以上。

需要完整代码可以在我的GitHub上找到。


本文在我的博客园我的个人博客上同步发布,作者保留版权,转载请注明来源。

机器学习笔记2 – sklearn之iris数据集的更多相关文章

  1. Python机器学习笔记 使用sklearn做特征工程和数据挖掘

    特征处理是特征工程的核心部分,特征工程是数据分析中最耗时间和精力的一部分工作,它不像算法和模型那样式确定的步骤,更多的是工程上的经验和权衡,因此没有统一的方法,但是sklearn提供了较为完整的特征处 ...

  2. Python机器学习笔记:sklearn库的学习

    网上有很多关于sklearn的学习教程,大部分都是简单的讲清楚某一方面,其实最好的教程就是官方文档. 官方文档地址:https://scikit-learn.org/stable/ (可是官方文档非常 ...

  3. 机器学习笔记(四)--sklearn数据集

    sklearn数据集 (一)机器学习的一般数据集会划分为两个部分 训练数据:用于训练,构建模型. 测试数据:在模型检验时使用,用于评估模型是否有效. 划分数据的API:sklearn.model_se ...

  4. 机器学习笔记5-Tensorflow高级API之tf.estimator

    前言 本文接着上一篇继续来聊Tensorflow的接口,上一篇中用较低层的接口实现了线性模型,本篇中将用更高级的API--tf.estimator来改写线性模型. 还记得之前的文章<机器学习笔记 ...

  5. Python机器学习笔记:使用Keras进行回归预测

    Keras是一个深度学习库,包含高效的数字库Theano和TensorFlow.是一个高度模块化的神经网络库,支持CPU和GPU. 本文学习的目的是学习如何加载CSV文件并使其可供Keras使用,如何 ...

  6. 从Iris数据集开始---机器学习入门

    代码多来自<Introduction to Machine Learning with Python>. 该文集主要是自己的一个阅读笔记以及一些小思考,小总结. 前言 在开始进行模型训练之 ...

  7. Google机器学习笔记 4-5-6 分类器

    转载请注明作者:梦里风林 Google Machine Learning Recipes 4 官方中文博客 - 视频地址 Github工程地址 https://github.com/ahangchen ...

  8. Python机器学习笔记:利用Keras进行分类预测

    Keras是一个用于深度学习的Python库,它包含高效的数值库Theano和TensorFlow. 本文的目的是学习如何从csv中加载数据并使其可供Keras使用,如何用神经网络建立多类分类的数据进 ...

  9. 【转】机器学习笔记之(3)——Logistic回归(逻辑斯蒂回归)

    原文链接:https://blog.csdn.net/gwplovekimi/article/details/80288964 本博文为逻辑斯特回归的学习笔记.由于仅仅是学习笔记,水平有限,还望广大读 ...

随机推荐

  1. jquery实现抽奖小游戏

    在很多网站或游戏活动中我们都会看到有关抽奖的活动或界面: 下面我将给大家介绍下如何通过javascript来实现这样的一个抽奖功能,主要从下面三个步骤入手(文中着重介绍第三部分有关功能的实现): 1. ...

  2. [Intel Edison开发板] 06、Edison开发在linux中烧写、配置、搭建开发环境

    1.前言 linux上烧写.配置.搭建Edison环境,千万不要用默认的setup tool for ubuntu!!! (即使,你用的就是ubuntu) 因为,其默认的工具会从一个坏链接下载配置文件 ...

  3. SUID,SGID,SBIT这些到底是什么

    SUID,SGID,SBIT这些都是文件的特殊权限. SUID(Set UID)文件执行过程中,用户拥有文件的root权限. SGID(Set GID)文件执行过程中,执行者拥有该文件的用户组的权限. ...

  4. CSS和文档

    1. 块级元素: p,div,ul,ol,h1,h2 . . . h6等.块级元素独占一行,旁边不能有其他元素. 2. 行内元素:span,a,strong,em等. display属性可以使块级元素 ...

  5. 微信分享 JSSDK的使用

    我现在做过的在微信中运行的项目,基本上都有微信分享功能,所以,会使用JSSDK分享页面是非常重要的.分享功能的代码一般会放在beforeCreate或mounted钩子中,代码如下: this.$ht ...

  6. Vocabulary & Phrase

    Vocabulary A ANSI    美国国家标准学会,American National Standards Institute的缩写 a couple of    [口语]少数的,几个 a s ...

  7. scala(一)Nothing、Null、Unit、None 、null 、Nil理解

    相对于java的类型系统,scala无疑要复杂的多!也正是这复杂多变的类型系统才让OOP和FP完美的融合在了一起! Nothing: 如果直接在scala-library中搜索Nothing的话是找不 ...

  8. NetFlow学习笔记

    NetFlow学习笔记 标签: netflow 由于工作需要,对NetFlow做了一些学习和调研,并总结成文档以供学习分享. 背景:随着系统的升级与漏洞的修补,入侵主机进而进行破坏的病毒攻击方式在攻击 ...

  9. JavaScript学习笔记(七)——函数的定义与调用

    在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...

  10. Java提高十六:TreeMap深入分析

    上一篇容器元素比较Comparable&Comparator分析的时候,我们提到了TreeMap,但没有去细致分析它,只是说明其在添加元素的时候可以进行比较,从而使得集合有序,但是怎么做的呢? ...