提交 58d465ac 编写于 作者: W wizardforcel

ch15.

上级 a92ead1f
......@@ -798,3 +798,126 @@ classify(wine, special_wine, 5)
是的! 分类器弄对了。
但是我们还不知道它对于所有其它葡萄酒如何,而且无论如何我们都知道,测试已经属于训练集的葡萄酒可能过于乐观了。 在本章的最后部分,我们将葡萄酒分为训练集和测试集,然后测量分类器在测试集上的准确性。
## 分类器的准确性
为了看看我们的分类器做得如何,我们可以将 50% 的数据放入训练集,另外 50% 放入测试集。基本上,我们保留一些数据以便以后使用,所以我们可以用它来测量分类器的准确性。我们始终将这个称为测试集。有时候,人们会把你留下用于测试的数据叫做保留集,他们会把这个估计准确率的策略称为保留方法。
请注意,这种方法需要严格的纪律。在开始使用机器学习方法之前,您必须先取出一些数据,然后放在一边用于测试。你必须避免使用测试集来开发你的分类器:你不应该用它来帮助训练你的分类器或者调整它的设置,或者用头脑风暴的方式来改进你的分类器。相反,在最后你已经完成分类器之后,当你想要它的准确率的无偏估计时,你应该仅仅使用它使用一次。
### 测量我们的葡萄酒分类器的准确率
好吧,让我们应用保留方法来评估 K 最近邻分类器识别葡萄酒的有效性。数据集有 178 个葡萄酒,所以我们将随机排列数据集,并将其中的 89 个放在训练集中,其余 89 个放在测试集中。
```py
shuffled_wine = wine.sample(with_replacement=False)
training_set = shuffled_wine.take(np.arange(89))
test_set = shuffled_wine.take(np.arange(89, 178))
```
我们将使用训练集中的 89 个葡萄酒来训练分类器,并评估其在测试集上的表现。 为了让我们更轻松,我们将编写一个函数,在测试集中每个葡萄酒上评估分类器:
```py
def count_zero(array):
"""Counts the number of 0's in an array"""
return len(array) - np.count_nonzero(array)
def count_equal(array1, array2):
"""Takes two numerical arrays of equal length
and counts the indices where the two are equal"""
return count_zero(array1 - array2)
def evaluate_accuracy(training, test, k):
test_attributes = test.drop('Class')
def classify_testrow(row):
return classify(training, row, k)
c = test_attributes.apply(classify_testrow)
return count_equal(c, test.column('Class')) / test.num_rows
```
现在到了答案揭晓的时候了,我们来看看我们做得如何。 我们将任意使用`k = 5`。
```py
evaluate_accuracy(training_set, test_set, 5)
0.9213483146067416
```
对于一个简单的分类器来说,这个准确率完全不差。
### 乳腺癌诊断
现在我想展示乳腺癌诊断的例子。我受到布列塔尼·温格(Brittany Wenger)的启发,他在 2012 年赢得了谷歌科学竞赛,还是一位 17 岁的高中生。这是布列塔尼:
布列塔尼的科学竞赛项目是构建一个诊断乳腺癌的分类算法。由于她构建了一个精度接近 99% 的算法,她获得了大奖。
让我们看看我们能做得如何,使用我们在这个课程中学到的思路。
所以,让我告诉你一些数据集的信息。基本上,如果一个女性的乳房存在肿块,医生可能想要进行活检,看看它是否是癌症。有几个不同的过程用于实现它。布列塔尼专注于细针抽吸(FNA),因为它比替代方案的侵袭性小。医生得到一块样本,放在显微镜下,拍摄一张照片,一个训练有素的实验室技术人员分析图像,来确定是否是癌症。我们得到一张图片,像下面这样:
不幸的是,区分良性和恶性可能是棘手的。因此,研究人员已经研究了机器学习的用法,来帮助完成这项任务。我们的想法是,我们要求实验室技术人员分析图像并计算各种属性:诸如细胞的通常大小,细胞大小之间有多少变化等等。然后,我们将尝试使用这些信息来预测(分类)样本是否是恶性的。我们有一套来自女性的过去样本的训练集,其中正确的诊断已知,我们希望我们的机器学习算法可以使用它们来学习如何预测未来样本的诊断。
我们最后得到了以下数据集。对于`Class`列,1 表示恶性(癌症);0 意味着良性(不是癌症)。
```py
patients = Table.read_table('breast-cancer.csv').drop('ID')
patients
```
| Clump Thickness | Uniformity of Cell Size | Uniformity of Cell Shape | Marginal Adhesion | Single Epithelial Cell Size | Bare Nuclei | Bland Chromatin | Normal Nucleoli | Mitoses | Class |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 5 | 1 | 1 | 1 | 2 | 1 | 3 | 1 | 1 | 0 |
| 5 | 4 | 4 | 5 | 7 | 10 | 3 | 2 | 1 | 0 |
| 3 | 1 | 1 | 1 | 2 | 2 | 3 | 1 | 1 | 0 |
| 6 | 8 | 8 | 1 | 3 | 4 | 3 | 7 | 1 | 0 |
| 4 | 1 | 1 | 3 | 2 | 1 | 3 | 1 | 1 | 0 |
| 8 | 10 | 10 | 8 | 7 | 10 | 9 | 7 | 1 | 1 |
| 1 | 1 | 1 | 1 | 2 | 10 | 3 | 1 | 1 | 0 |
| 2 | 1 | 2 | 1 | 2 | 1 | 3 | 1 | 1 | 0 |
| 2 | 1 | 1 | 1 | 2 | 1 | 1 | 1 | 5 | 0 |
| 4 | 2 | 1 | 1 | 2 | 1 | 2 | 1 | 1 | 0 |
(省略了 673 行)
所以我们有 9 个不同的属性。 我不知道如何制作它们全部的 9 维散点图,所以我要挑选两个并绘制它们:
```py
color_table = Table().with_columns(
'Class', make_array(1, 0),
'Color', make_array('darkblue', 'gold')
)
patients_with_colors = patients.join('Class', color_table)
patients_with_colors.scatter('Bland Chromatin', 'Single Epithelial Cell Size', colors='Color')
```
这个绘图完全是误导性的,因为有一堆点的`x`坐标和`y`坐标都有相同的值。 为了更容易看到所有的数据点,我将为`x`和`y`值添加一点点随机抖动。 这是看起来的样子:
例如,你可以看到有大量的染色质为 2 和上皮细胞大小为 2 的样本;所有都不是癌症。
请记住,抖动仅用于可视化目的,为了更容易感知数据。 我们现在已经准备好使用这些数据了,我们将使用原始数据(没有抖动)。
首先,我们将创建一个训练集和一个测试集。 数据集有 683 名患者,因此我们将随机排列数据集,并将其中的 342 个放在训练集中,其余的 341 个放在测试集中。
```py
shuffled_patients = patients.sample(683, with_replacement=False)
training_set = shuffled_patients.take(np.arange(342))
test_set = shuffled_patients.take(np.arange(342, 683))
```
让我们选取 5 个最近邻,并观察我们的分类器如何。
```py
evaluate_accuracy(training_set, test_set, 5)
0.967741935483871
```
准确性超过 96%。不错!这样一个简单的技术再一次相当不错。
作为脚注,你可能已经注意到布列塔尼·温格做得更好了。 她使用了什么技术? 一个关键的创新是,她将置信评分纳入了结果:她的算法有一种方法来确定何时无法做出有把握的预测,对于那些患者,甚至不尝试预测他们的诊断。 她的算法对于做出预测的病人是 99% 准确的,所以这个扩展看起来有点帮助。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册