Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
data8-textbook-zh
提交
b60f2a25
D
data8-textbook-zh
项目概览
OpenDocCN
/
data8-textbook-zh
8 个月 前同步成功
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
data8-textbook-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b60f2a25
编写于
1月 26, 2018
作者:
W
wizardforcel
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ch15.
上级
682dcba3
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
168 addition
and
0 deletion
+168
-0
15.md
15.md
+168
-0
未找到文件。
15.md
浏览文件 @
b60f2a25
...
@@ -348,3 +348,171 @@ array([ 0.59610766, -0.19065363])
...
@@ -348,3 +348,171 @@ array([ 0.59610766, -0.19065363])
```
```
这非常方便,因为我们现在可以在每行的数据上使用数组操作了。
这非常方便,因为我们现在可以在每行的数据上使用数组操作了。
### 只有两个属性时点的距离
我们需要做的主要计算是,找出 Alice 的点与其他点之间的距离。 为此,我们需要的第一件事就是计算任意一对点之间的距离。
我们如何实现呢? 在二维空间中,这非常简单。 如果我们在坐标`
(x0, y0)
`处有一个点,而在`
(x1, y1)
`处有另一个点,则它们之间的距离是:
![](http://latex.codecogs.com/gif.latex?D%20%3D%20%5Csqrt%7B%28x_0-x_1%29%5E2%20+%20%28y_0-y_1%29%5E2%7D)
(这是从哪里来的?它来自勾股定理:我们有一个直角三角形,边长为`
x0 - x1
`和`
y0 - y1
`,我们想要求出斜边的长度。)
在下一节中,我们将看到,当存在两个以上的属性时,这个公式有个直接的扩展。 现在,让我们使用公式和数组操作来求出 Alice 和第 3 行病人的距离。
```py
patient3 = np.array(ckd_attributes.row(3))
alice, patient3
(array([ 0. , 1.1]), array([ 0.59610766, -0.19065363]))
distance = np.sqrt(np.sum((alice - patient3)**2))
distance
1.4216649188818471
```
我们需要 Alice 和一堆点之间的距离,所以让我们写一个称为距离的函数来计算任意一对点之间的距离。 该函数将接受两个数组,每个数组包含一个点的`
(x, y)
`坐标。 (记住,那些实际上是患者的血红蛋白和血糖水平。)
```py
def distance(point1, point2):
"""Returns the Euclidean distance between point1 and point2.
Each argument is an array containing the coordinates of a point."""
return np.sqrt(np.sum((point1 - point2)**2))
distance(alice, patient3)
1.4216649188818471
```
我们已经开始建立我们的分类器:距离函数是第一个积木。 现在让我们来研究下一个片段。
### 在整个行上使用`
apply
`
回想一下,如果要将函数应用于表的列的每个元素,一种方法是调用`
table_name.apply(function_name, column_label)
`。 当我们在列的每个元素上调用该函数时,它求值为由函数返回值组成的数组。所以数组的每个条目都基于表的相应行。
如果使用`
apply
`而不指定列标签,则整行将传递给该函数。 让我们在一个非常小的表格上,看看它的工作原理,表格包含训练样本中前五个患者的信息。
```py
t = ckd_attributes.take(np.arange(5))
t
```
| Hemoglobin | Glucose |
| --- | --- |
| 0.456884 | 0.133751 |
| 1.153 | -0.947597 |
| 0.770138 | -0.762223 |
| 0.596108 | -0.190654 |
| -0.239236 | -0.49961 |
举个例子,假设对于每个病人,我们都想知道他们最不寻常的属性是多么的不寻常。 具体而言,如果患者的血红蛋白水平远高于其血糖水平,我们想知道它离平均值有多远。 如果她的血糖水平远远高于她的血红蛋白水平,那么我们想知道它离平均值有多远。
这与获取两个量的绝对值的最大值是一样的。 为了为特定的行执行此操作,我们可以将行转换为数组并使用数组操作。
```py
def max_abs(row):
return np.max(np.abs(np.array(row)))
max_abs(t.row(4))
0.49961028259186968
```
现在我们可以将`
max_abs
`应用于`
t
`表的每一行:
```py
t.apply(max_abs)
array([ 0.4568837 , 1.15300352, 0.77013762, 0.59610766, 0.49961028])
```
这种使用`
apply
`的方式帮助我们创建分类器的下一个积木。
### Alice 的 K 最近邻
如果我们想使用 K 最近邻分类器来划分 Alice,我们必须确定她的 K 个最近邻。 这个过程中的步骤是什么? 假设`
k = 5
`。 然后这些步骤是:
+ 步骤 1:的是 Alice 与训练样本中每个点之间的距离。
+ 步骤 2:按照距离的升序对数据表进行排序。
+ 步骤 3:取得有序表的前 5 行。
步骤 2 和步骤 3 似乎很简单,只要我们有了距离。 那么我们来关注步骤 1。
这是爱丽丝:
```py
alice
array([ 0. , 1.1])
```
我们需要一个函数,它可以求出 Alice 和另一个点之间的距离,它的坐标包含在一行中。 `
distance
`函数返回任意两点之间的距离,他们的坐标位于数组中。 我们可以使用它来定义`
distance_from_alice
`,它将一行作为参数,并返回该行与 Alice 之间的距离。
```py
def distance_from_alice(row):
"""Returns distance between Alice and a row of the attributes table"""
return distance(alice, np.array(row))
distance_from_alice(ckd_attributes.row(3))
1.4216649188818471
```
现在我们可以调用`
apply
`,将`
distance_from_alice
`函数应用于`
ckd_attributes
`的每一行,第一步完成了。
```py
distances = ckd_attributes.apply(distance_from_alice)
ckd_with_distances = ckd.with_column('Distance from Alice', distances)
ckd_with_distances
```
| Class | Hemoglobin | Glucose | Color | Distance from Alice |
| --- | --- | --- | --- | --- |
| 0 | 0.456884 | 0.133751 | gold | 1.06882 |
| 0 | 1.153 | -0.947597 | gold | 2.34991 |
| 0 | 0.770138 | -0.762223 | gold | 2.01519 |
| 0 | 0.596108 | -0.190654 | gold | 1.42166 |
| 0 | -0.239236 | -0.49961 | gold | 1.6174 |
| 0 | -0.0304002 | -0.159758 | gold | 1.26012 |
| 0 | 0.282854 | -0.00527964 | gold | 1.1409 |
| 0 | 0.108824 | -0.623193 | gold | 1.72663 |
| 0 | 0.0740178 | -0.515058 | gold | 1.61675 |
| 0 | 0.83975 | -0.422371 | gold | 1.73862 |
(省略了 148 行)
对于步骤 2,让我们以距离的升序对表排序:
```py
sorted_by_distance = ckd_with_distances.sort('Distance from Alice')
sorted_by_distance
```
| Class | Hemoglobin | Glucose | Color | Distance from Alice |
| --- | --- | --- | --- | --- |
| 1 | 0.83975 | 1.2151 | darkblue | 0.847601 |
| 1 | -0.970162 | 1.27689 | darkblue | 0.986156 |
| 0 | -0.0304002 | 0.0874074 | gold | 1.01305 |
| 0 | 0.14363 | 0.0874074 | gold | 1.02273 |
| 1 | -0.413266 | 2.04928 | darkblue | 1.03534 |
| 0 | 0.387272 | 0.118303 | gold | 1.05532 |
| 0 | 0.456884 | 0.133751 | gold | 1.06882 |
| 0 | 0.178436 | 0.0410639 | gold | 1.07386 |
| 0 | 0.00440582 | 0.025616 | gold | 1.07439 |
| 0 | -0.169624 | 0.025616 | gold | 1.08769 |
(省略了 148 行)
步骤 3:前五行对应 Alice 的五个最近邻;你可以将五替换为任意正整数。
```py
alice_5_nearest_neighbors = sorted_by_distance.take(np.arange(5))
alice_5_nearest_neighbors
``
`
| Class | Hemoglobin | Glucose | Color | Distance from Alice |
| --- | --- | --- | --- | --- |
| 1 | 0.83975 | 1.2151 | darkblue | 0.847601 |
| 1 | -0.970162 | 1.27689 | darkblue | 0.986156 |
| 0 | -0.0304002 | 0.0874074 | gold | 1.01305 |
| 0 | 0.14363 | 0.0874074 | gold | 1.02273 |
| 1 | -0.413266 | 2.04928 | darkblue | 1.03534 |
爱丽丝五个最近邻中有三个是蓝点,两个是金点。 所以 5 邻近的分类器会把爱丽丝划分为蓝色:它可能预测爱丽丝有慢性肾病。
下面的图片放大了爱丽丝和她五个最近邻。 这两个金点就在红点正下方的圆圈内。 分类器说,爱丽丝更像她身边的三个蓝点。
我们正在实现我们的 K 最近邻分类器。 在接下来的两节中,我们将把它放在一起并评估其准确性。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录