您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 Code iProcess 课程 认证 咨询 工具 火云堂 讲座吧   成长之路  
会员   
 
   
 
  
每天15篇文章
不仅获得谋生技能
更可以追随信仰
 
     
   
 订阅
  捐助
机器学习笔记2 – sklearn之iris数据集
 
2108 次浏览     评价:  
 2018-3-2 
 
编辑推荐:

本文来自于fujiabin,本篇会使用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上找到。

   
2108 次浏览  评价: 差  订阅 捐助
相关文章

我们该如何设计数据库
数据库设计经验谈
数据库设计过程
数据库编程总结
 
相关文档

数据库性能调优技巧
数据库性能调整
数据库性能优化讲座
数据库系统性能调优系列
相关课程

高性能数据库设计与优化
高级数据库架构师
数据仓库和数据挖掘技术
Hadoop原理、部署与性能调优
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
 
 

关于我们 | 联系我们 | 京ICP备10020922号 京公海网安备110108001071号