• 沒有找到結果。

A -近邻算法概述 17

在文檔中 关 于 封 面 (頁 21-27)

表2 - 2 已知电影与未知电影的距离

________________

电影名称

______________

___________________与 未 知 电 影的 距 离 ______________________

California Man m 5

He 's Not Really into Dudes 18.7

Beautiful Woman 19.2

Kevin Longblade 115.3

Robo Slayer 3000 117.4

Amped II

_________________

m 3

____________________

现在我们得到了样本集中所有电影与未知电影的距离按照距离递增排序可以找到乂个距 离最近的电影。假定

^=3

,贝丨』三个最靠近的电影依次是故》

#0;

(7//

少如

0/3»

如 、Beautiful Woman

和。_ _ 从 氣 4-

近邻算法按照距离最近的三部电影的类型,决定未知电影的类型,而这三部 电影全是爱情片,因此我们判定未知电影是爱情片。

本章主要讲解如何在实际环境中应用々-近邻算法同时涉及如何使用

?7

出(^工具和相关的机 器学习术语。按 照

1.5

节开发机器学习应用的通用步骤,我们使用

?

乂出如语言开发&-近邻算法的简 单 应 用 ,以检验算法使用的正确性。

k

-近邻算法的一般流程 A .廣 ,^a.. :¾

f , -(1)

收集数据:可以使用任何方法。

(2)

准备数据:距离计算所需要的数值,最好是结构化的数据格式。

(3)

分析数据 :可以使用任何方法。

(4)

训练算 法 :此步驟不适用于

1

近邻算法。

(5)

测试算 法:计算错误率。

(6)

使 用 算 法 :首先需要输入样本数据和结构化的输出结果,然后运行女-近邻算法判定输 入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。

2 . 1 . 1

准 备 : 使 用

P y th o n

导 入 数 据

首 先 ,创 建 名 为 麵 孙 的

?

0

濃 块 ,本章使用的所有代码都在这个文件中。读者可以按照自 己的习惯学习代码,既可以按照本书学习的进度,在自己创建的

?7^«^

文件中编写代码,也可以直 接从本书的源代码中复制

_

仍 文 件 。我推荐读者从头开始创建模块,按照学习的进度编写代码。

无论大家采用何种方法,我们现在已经有了

kNN.py

文件 。在构造完整的丨

-

近邻算法之前,我 们还需要编写一些基本的通用函数,在

kNN.py

文件中增加下面的代码:

f r o m n u m p y i m p o r t ★ i m p o r t o p e r a t o r d e f c r e a t e D a t a S e t { ) :

g r o u p = a r r a y ( [ [ 1 . 0 , 1 .1] [1.0,1. 0], [0,0], [0,0.1]]) l a b e l s = [ ' A ' , ' A ' , ' B ' , ' B 1]

r e t u r n group, l a b e l s

在上面的代码中,我们导人了两个模块;第一个是科学计算包

> ^ ! ^ ^

第二个是运算符模块

,

18

2

it

-近邻算法

-

近邻算法执行排序操作时将使用这个模块提供的函数,后面我们将进一步介绍。

为了方便使用。

3^

60

社 沾

61^)

函数 ,它创建数据集和标签,如图

2-1

所 示 。然后依次执行 以下步骤:保存

_ $ 7

文 件 ,改变当前路径到存储

— .?7

文 件 的 位 置 ,打开

?

1«^

开 发环境。

Xifc^Linux、Mac O S

还是

Windows

都需要在打开终端,在命令提亦符下完成上述操作。只要我 们按照默认配置安装

? 3 ^ ( ® ,

01»«

^ 0 8

终端内都可以直接输人

9 7

0 1 ^

而 在 斯

1«10

8

命令 提水符下需要输人。

:\Python2 . 6\python _ e x e ,

进人

?7

00

交互式开发环境。

进人

?

丫出

(^

开发环境之后,输人下列命令导人上面编辑的程序模块

:

> >> i m p o r t k N N

上 述 命 令 导 人 臟 模 块 。为了确保输人相同的数据集,麵 模 块 中 定 义 了 函 数^ 的七扣壯沾社,在 卩

0

«命令提本符下输入下属 命 令:

>>> g r o u p , l a b e l s = k N N . c r e a t e D a t a S e t ()

上述命令创建了变量

910

叩 和

1

013

,在

?7

^

命 令提示 符下,输人变量的名字以检验是否正确 地 定 义变 量:

>>> g r o u p

a r r a y ([[ 1 1 . 1]

0.1]])

l a b e l s

[ ' A f, ' A ' , 'B,, 'B']

这里有

4

组 数 据 ,每组数据有两个我们已知的属性或者特征值。上面的

9!^

卩?矩阵每行包含一个 不同的数据,我们可以把它想象为某个日志文件中不同的测量点或者入口。由于人类大脑的限制,

我们通常只能可视化处理三维以下的事务。因此为了简单地实现数据可视化,对于每个数据点我 们通常只使用两个特征。

向量

1

61

包含了每个数据点的标签信息,

1

61

包含的元素个数等于取。叩 矩 阵 行 数 。这 里我们将数据点

(1

1.1)

定义为类八,数据点

(0, 0.1)

定义为类

8

。为了说明方便,例子中的数值是 任 意选择的,并没有给出轴标签,图

2-2

是带有类标签信息的四个数据点。

~ ° -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2

•图2-2 &近邻算法:带有4个数据点的简单例子

2.1 A

-近邻算 法概述

19

现在我们巳经知道

?7««^

如何解析数据,如何加载数据,以及

_

算法的工作原理,接下来 我们将使用这些方法完成分类任务。

2 . 1 . 2 从文本文件中解析数据

本节使用程序清单

2-1

的函数运行

_

算 法 ,为每组数据分类。这里首先给出卜近邻算法的伪 代码和实际的

?

乂出

011

代 码 ,然后详细地解释每行代码的含义。该函数的功能是使用&-近邻算法将 每组数据划分到某个类中,其伪代码如下:

对未知类别属性的数据集中的每个点依次执行以下操作:

(1)

计算已知类别数据集中的点与当前点之间的距离;

(2)

按照距离递增次序排序;

(3)

选取与当前点距离最小的走个点;

(4)

确定前灸个点所在类别的出现频率;

(5)

返回前女个点出现频率最高的类别作为当前点的预测分类。

?

0 « ^

函数

<=13331&0 ()

如程序清单

2_1

所 示。

程序清单

2 - 1

各近邻算法

d e f c l a s s i f y O ( i n X , dataSet, labels, k ) : d a t a S e t S i z e = d a C a S e t .s h a p e fO]

d i f f M a t = t i l e ( i n X , ( d a t a S e t S i z e , 1)) - d a t a S e t s q D i f f M a t = d i f f M a t * * 2

s q D i s t a n c e s = s q D i f f M a t .s u m (axis=l) d i s t a n c e s = s q D i s t a n c e s * * O .5

s o r t e d D i s t I n d i c i e s - d i s t a n c e s.argaort ()

距 离 计 算

c l a s s C o u n t = { } 选 择 距 离 最 小 资

f o r 1 in r a n g e ( k ) . 的斤个占 ^ \

v o t e I l a b e l = l a b e l s [ s o r t e d D i s t I n d i c i e s [i]]

c l a s s C o u n t [ v o t e l l a b e l ] = c l a s s C o u n t . g e t { v o t e I l a b e l ,0) + 1 s o r t e d C l a s s C o u n t = s o r t e d ( c l a s s C o u n t .i t e r i t e m s (),

k e y = o p e r a t o r . i t e m g e t t e r { l ) , r e v e r s e = T r u e ) < ~ ^

r e t u r n s o r t e d C l a s s C o u n t [ 0 ] [0] 办 排 序

classifyO ()

函数有

4

个输人参数

:

用于分类的输人向量是丨必,输人的训练样本集为

(1313861,

标签向量为

131^13

,最后的参数义表示用于选择最近邻居的数目,其中标签向量的元素数目和矩 阵 如

1

&

的行数相同。程序清单

2-1

使用欧氏距离公式,计算两个向量点

和成之间的距离

0 :

d = 」(xA0 - xB0 )2 + (xA{ - xBt )2

例 如 ,点

(0

0)

(1, 2)

之间的距离计算为:

V(l-0)2+(2-0)2

如果数据集存在

4

个 特 征 值 ,则点

(1

0, 0

1)

(7, 6, 9

4)

之间的距离计算为:

20

2

1

-近邻算法

V(7 - 1)2 + (6 - 0)2 + (9

0)2 + (4

1)2

计算完所有点之间的距离后,可以对数据按照从小到大的次序排序。然 后 ,确定前

k

个距离 最小元素所在的主要分类

© ,

输人々总是正整数;最 后 ,将

< ^

0

恤 字 典 分 解 为 元 组 列 表 ,然后 使用程序第二行导入运算符模块的让挪

9

过 t e r ^ m ,按照第二个元素的次序对元组进行排序©。

此处的

3#

序 为 逆 序 ,即按照从最大到最小次序排序,最后返回发生频率最高的元素标签。

为了预测数据所在分类,在卩沖如提示符中输入下列命令

:

>>> k N N . c l a s s i f y 0 ( [ 0 , 0 ] , gr oup, labels, 3)

输 出 结 果 应 该 是 艮 大 家 也 可 以 改 变 输 人

[0,0]

为其他 值 ,测试程序的运行结果。

到现在为止,我们已经构造了第一个分类器,使用这个分类器可以完成很多分类任务。从这 个 实例出发,构造使用分类算法将会更加容易。

2 . 1 . 3 如何测试分类器

上文我们已经使用女

-

近邻算法构造了第一个分类器,也可以检验分类器给出的答案是否符合 我们的预期。读者可能会问:

分类器何种情况下会出错?

或 者

答案是否总是正确的?” 答 案 是否定的

,

分类器并不会得到百分百正确的结果

,

我们可以使用多种方法检测分类器的正确率。

此外分类器的性能也会受到多种因素的影响,如分类器设置和数据集等。不同的算法在不同数据 集上的表现可能完全不同,这也是本部分的

6

章都在讨论分类算法的原因所在。

为了测试分类器的效果,我们可以使用已知答案的数据,当然答案不能告诉分类器,检验分 类器给出的结果是否符合预期结果。通过大量的测试数据,我们可以得到分类器的错误率—— 分 类器给出错误结果的次数除以测试执行的总数。错误率是常用的评估方法,主要用于评估分类器 在某个数据集上的执行效果。完美分类器的错误率为

0 ,

最差分类器的错误率是

1.0

,在 这 种 情 况 下 ,分类器根本就无法找到一个正确答案。读者可以在后面章节看到实际的数据例子。

上一节介绍的例子已经可以正常运转了,但是并没有太大的实际用处,本章的后两节将在现 实世界中使用

/

卜近邻算法。首 先 ,我们将使用

&-

近邻算法改进约会网站的效果,然后使用々-近邻 算法改进手写识别系统。本书将使用手写识别系统的测试程序检测々

-

近邻算法的效果。

2 . 2 示例:使用々-近邻算法改进约会网站的配对效果

我的朋友海伦一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的 人 选 ,但她没有从中找到喜欢的人。经过一番总结,她发现曾交往过三种类型的人:

□ 不喜欢的人

□ 魅力一般的人

□ 极具魅力的人

尽管发现了上述规律,但海伦依然无法将约会网站推荐的匹配对象归人恰当的分类。她觉得 可以在周一到周五约会那些魅力一般的人,而周末则更喜欢与那些极具魅力的人为伴。海伦希望

2 . 2

示 例 :使 用

1

近邻 算法改 进约会网站的配对效果

21

我们的分类软件可以更好地帮助她将匹配对象划分到确切的分类中。此外海伦还收集了一些约会 网站未曾记录的数据信息,她认为这些数据更有助于匹配对象的归类。

|

示例:在约会网站上使用&近邻算法

' ' ;; • f ^ , : , i (1)

收集数据:提供文本文件。

(2)_

准备数据

:

使用?沖

00

解析文本文件。

( 3 )分 析 数 据 :使用河3中10«化画二维扩散图。

(4)

训练算 法:此步驟不适用于卜近邻算法。

(5)

测试算法:使用海伦提供的部分数据作为测试样本。

测试样本和非测试样本的区别在于:测试样本是已经完成分类的数据,如果预测分类 与实际类别不同,则标记为一个错误。

(6)

使 用 算 法 :产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否 为自己喜欢的类型。

2 . 2 . 1 准 备 数 据 :从文本文件中解析数据

海伦收集约会数据巳经有了一段时间,她把这些数据存放在文本文件

(1

1^

及 抓 比 加 中 ,每 个样本数据占据一行,总共有

1000

行 。海伦的样本主要包含以下

3

种 特 征 :

□ 每年获得的飞行常客里程数

□ 玩视频游戏所耗时间百分比

□ 每周消费的冰淇淋公升数

在将上述特征数据输人到分类器之前,必须将待处理数据的格式改变为分类器可以接受的格 式 。在

kNN.py

中创建名为

file2matrix

的 函数,以此来处理输人格式问题。该函数的输人为文 件 名 字符 串输出为训练样本矩阵和类标签向量。

将下面的代码增加到

_ . ?7

程序清单

2 - 2

将文本记录到转换

NumPy

的解析程序

程序清单

2 - 2

将文本记录到转换

NumPy

的解析程序

在文檔中 关 于 封 面 (頁 21-27)