提交 f1a95d48 编写于 作者: W wizardforcel

ch15pic

上级 2bea8f92
......@@ -103,6 +103,8 @@ ckd = ckd.join('Class', color_table)
ckd.scatter('Hemoglobin', 'Glucose', colors='Color')
```
![](img/15-1.png)
假设爱丽丝是不在数据集中的新患者。 如果我告诉你爱丽丝的血红蛋白水平和血糖水平,你可以预测她是否有 CKD 嘛? 确实看起来可以! 你可以在这里看到非常清晰的规律:右下角的点代表没有 CKD 的人,其余的倾向于有 CKD 的人。 对于人来说,规律是显而易见的。 但是,我们如何为计算机编程来自动检测这种规律?
### 最近邻分类器
......@@ -119,6 +121,8 @@ alice = make_array(0, 1.5)
show_closest(alice)
```
![](img/15-2.png)
因此,我们的最近邻分类器是这样工作的:
+ 找到训练集中离新点最近的点。
......@@ -137,8 +141,11 @@ alice = make_array(0, 0.97)
show_closest(alice)
```
![](img/15-3.png)
这里有数百个未分类的新点,都是红色的。
![](img/15-4.png)
每个红点在训练集中都有一个最近邻(与之前的蓝点和金点相同)。对于一些红点,你可以很容易地判断最近邻是蓝色还是金色。对于其他点来说,通过眼睛来做出决定更为棘手。那些是靠近决策边界的点。
......@@ -146,8 +153,9 @@ show_closest(alice)
对于每个红点,它必须找到训练集中最近的点;它必须将红点的颜色改变为最近邻的颜色。
结果图显示哪些点将划分为“CKD”(全部为蓝色),或者“非 CKD”(全部为黄金)。
结果图显示哪些点将划分为“CKD”(全部为蓝色),或者“非 CKD”(全部为金色)。
![](img/15-5.png)
决策边界是分类器从将红点转换为蓝色变成金色的地方。
......@@ -159,6 +167,8 @@ show_closest(alice)
ckd.scatter('White Blood Cell Count', 'Glucose', colors='Color')
```
![](img/15-6.png)
如你所见,非 CKD 个体都聚集在左下角。大多数 CKD 患者在该簇的上方或右侧,但不是全部。上图左下角有一些 CKD 患者(分散在金簇中的少数蓝点表示)。这意味着你不能从这两个检测结果确定,某些人是否拥有 CKD。
如果提供爱丽丝的血糖水平和白细胞计数,我们可以预测她是否患有慢性肾病嘛?是的,我们可以做一个预测,但是我们不应该期望它是 100% 准确的。直觉上,似乎存在预测的自然策略:绘制 Alice 在散点图中的位置;如果她在左下角,则预测她没有 CKD,否则预测她有 CKD。
......@@ -195,6 +205,8 @@ ckd.scatter('White Blood Cell Count', 'Glucose', colors='Color')
ckd.scatter('White Blood Cell Count', 'Glucose', colors='Color')
```
![](img/15-7.png)
之前,我们说我们预计得到一些分类错误,因为在左下方有一些蓝色和金色的点。
但是训练集中的点,也就是已经在散点图上的点呢?我们会把它们误分类吗?
......@@ -241,10 +253,16 @@ plt.xlim(-2, 6)
plt.ylim(-2, 6);
```
![](img/15-8.png)
我们得到以下分类区域和决策边界:
![](img/15-9.png)
把测试数据放在这个图上,你可以立刻看到分类器对于几乎所有的点都正确,但也有一些错误。 例如,测试集的一些蓝点落在分类器的金色区域。
![](img/15-10.png)
尽管存在一些错误,但分类器看起来在测试集上表现得相当好。 假设原始样本是从底层总体中随机抽取的,我们希望分类器在整个总体上具有相似的准确性,因为测试集是从原始样本中随机选取的。
## 表的行
......@@ -324,6 +342,8 @@ ckd.scatter('Hemoglobin', 'Glucose', colors='Color')
plots.scatter(alice.item(0), alice.item(1), color='red', s=30);
```
![](img/15-11.png)
为了找到 Alice 点和其他点之间的距离,我们只需要属性的值:
```py
......@@ -523,6 +543,8 @@ alice_5_nearest_neighbors
下面的图片放大了爱丽丝和她五个最近邻。 这两个金点就在红点正下方的圆圈内。 分类器说,爱丽丝更像她身边的三个蓝点。
![](img/15-12.png)
我们正在实现我们的 K 最近邻分类器。 在接下来的两节中,我们将把它放在一起并评估其准确性。
## 实现分类器
......@@ -565,6 +587,8 @@ banknotes = banknotes.join('Class', color_table)
banknotes.scatter('WaveletVar', 'WaveletCurt', colors='Color')
```
![](img/15-13.png)
非常有趣! 这两个测量值看起来对于预测钞票是否伪造有帮助。 然而,在这个例子中,你现在可以看到蓝色的簇和金色的簇之间有一些重叠。 这表示基于这两个数字,很难判断钞票是否合法。 不过,你可以使用 K 最近邻分类器来预测钞票的合法性。
花点时间想一想:假设我们使用`k = 11`(是假如)。 图中的哪些部分会得到正确的结果,哪些部分会产生错误? 决定边界是什么样子?
......@@ -575,6 +599,8 @@ banknotes.scatter('WaveletVar', 'WaveletCurt', colors='Color')
banknotes.scatter('WaveletSkew', 'Entropy', colors='Color')
```
![](img/15-14.png)
似乎存在规律,但它是非常复杂。 尽管如此, K 最近邻分类器仍然可以使用,并将有效地“发现”规律。 这说明了机器学习有多强大:它可以有效地利用规律,我们不曾预料到它,或者我们打算将其编入计算机。
### 多个属性
......@@ -593,6 +619,8 @@ ax.scatter(banknotes.column('WaveletSkew'),
c=banknotes.column('Color'));
```
![](img/15-15.png)
真棒!只用 2 个属性,两个簇之间有一些重叠(这意味着对于重叠中的一些点,分类器必然犯一些错误)。但是当我们使用这三个属性时,两个簇几乎没有重叠。换句话说,使用这 3 个属性的分类器比仅使用 2 个属性的分类器更精确。
这是分类中的普遍现象。每个属性都可能会给你提供新的信息,所以更多的属性有时可以帮助你建立一个更好的分类器。当然开销是,现在我们必须收集更多的信息来衡量每个属性的值,但是如果这个开销显着提高了我们的分类器的精度,那么它可能非常值得。
......@@ -678,18 +706,24 @@ wine_with_colors = wine.join('Class', color_table)
wine_with_colors.scatter('Flavanoids', 'Alcohol', colors='Color')
```
![](img/15-16.png)
蓝点(第一类)几乎完全与金点分离。 这表明了,为什么两种第一类葡萄酒之间的距离小于两个不同类别葡萄酒之间的距离。 我们使用不同的一对属性,也可以看到类似的现象:
```py
wine_with_colors.scatter('Alcalinity of Ash', 'Ash', colors='Color')
```
![](img/15-17.png)
但是对于不同的偶对,图像更加模糊。
```py
wine_with_colors.scatter('Magnesium', 'Total Phenols', colors='Color')
```
![](img/15-18.png)
让我们来看看,是否可以基于所有的属性来实现一个分类器。 之后,我们会看到它有多准确。
### 实现计划
......@@ -905,8 +939,12 @@ patients_with_colors = patients.join('Class', color_table)
patients_with_colors.scatter('Bland Chromatin', 'Single Epithelial Cell Size', colors='Color')
```
![](img/15-19.png)
这个绘图完全是误导性的,因为有一堆点的`x`坐标和`y`坐标都有相同的值。 为了更容易看到所有的数据点,我将为`x`和`y`值添加一点点随机抖动。 这是看起来的样子:
![](img/15-20.png)
例如,你可以看到有大量的染色质为 2 和上皮细胞大小为 2 的样本;所有都不是癌症。
请记住,抖动仅用于可视化目的,为了更容易感知数据。 我们现在已经准备好使用这些数据了,我们将使用原始数据(没有抖动)。
......@@ -970,6 +1008,8 @@ sales.sort('SalePrice')
sales.hist('SalePrice', bins=32, unit='$')
```
![](img/15-21.png)
### 相关性
没有单个属性足以预测销售价格。 例如,第一层面积(平方英尺)与销售价格相关,但仅解释其一些变化。
......@@ -981,6 +1021,8 @@ correlation(sales, 'SalePrice', '1st Flr SF')
0.64246625410302249
```
![](img/15-22.png)
事实上,没有任何单个属性与销售价格的相关性大于 0.7(销售价格本身除外)。
```py
......@@ -1116,6 +1158,8 @@ test.with_column('Fitted', test.drop(0).apply(fit)).scatter('Fitted', 0)
plots.plot([0, 5e5], [0, 5e5]);
```
![](img/15-23.png)
多元回归的残差图通常将误差(残差)与预测变量的实际值进行比较。 我们在下面的残差图中看到,我们系统性低估了昂贵房屋的值,由图右侧的许多正的残差值所示。
```py
......@@ -1123,6 +1167,8 @@ test.with_column('Residual', test_prices-test.drop(0).apply(fit)).scatter(0, 'Re
plots.plot([0, 7e5], [0, 0]);
```
![](img/15-24.png)
就像简单的线性回归一样,解释预测结果至少和预测一样重要。 很多解释多元回归的课程不包含在这个课本中。 完成这门课之后的下一步自然是深入研究线性建模和回归。
## 最近邻回归
......@@ -1222,3 +1268,5 @@ Test set RMSE for nearest neighbor regression: 31210.6572877
test.with_column('Residual', test_prices-nn_test_predictions).scatter(0, 'Residual')
plots.plot([0, 7e5], [0, 0]);
```
![](img/15-25.png)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册