@@ -618,6 +618,7 @@ cancer_test["predicted"] = knn_pipeline.predict(cancer_test[["Smoothness", "Conc
618
618
cancer_test[["ID", "Class", "predicted"]]
619
619
```
620
620
621
+ (eval-performance-clasfcn2)=
621
622
### Evaluate performance
622
623
623
624
``` {index} scikit-learn; score
@@ -1478,6 +1479,66 @@ set the number of neighbors $K$ to 1, 7, 20, and 300.
1478
1479
1479
1480
+++
1480
1481
1482
+ ### Evaluating on the test set
1483
+
1484
+ Now that we have tuned the KNN classifier and set $K =$ {glue: text }` best_k_unique ` ,
1485
+ we are done building the model and it is time to evaluate the quality of its predictions on the held out
1486
+ test data, as we did earlier in {numref}` eval-performance-clasfcn2 ` .
1487
+ We first need to retrain the KNN classifier
1488
+ on the entire training data set using the selected number of neighbors.
1489
+ Fortunately we do not have to do this ourselves manually; ` scikit-learn ` does it for
1490
+ us automatically. To make predictions and assess the estimated accuracy of the best model on the test data, we can use the
1491
+ ` score ` and ` predict ` methods of the fit ` GridSearchCV ` object. We can then pass those predictions to
1492
+ the ` crosstab ` function to print a confusion matrix.
1493
+
1494
+ ``` {code-cell} ipython3
1495
+ cancer_tune_grid.score(
1496
+ cancer_test[["Smoothness", "Concavity"]],
1497
+ cancer_test["Class"]
1498
+ )
1499
+ ```
1500
+
1501
+ ``` {code-cell} ipython3
1502
+ :tags: [remove-cell]
1503
+ cancer_acc_tuned = cancer_tune_grid.score(
1504
+ cancer_test[["Smoothness", "Concavity"]],
1505
+ cancer_test["Class"]
1506
+ )
1507
+ glue("cancer_acc_tuned", "{:0.0f}".format(100*cancer_acc_tuned))
1508
+ ```
1509
+
1510
+ ``` {code-cell} ipython3
1511
+ cancer_test["predicted"] = cancer_tune_grid.predict(
1512
+ cancer_test[["Smoothness", "Concavity"]]
1513
+ )
1514
+ pd.crosstab(
1515
+ cancer_test["Class"],
1516
+ cancer_test["predicted"]
1517
+ )
1518
+ ```
1519
+
1520
+ ``` {code-cell} ipython3
1521
+ :tags: [remove-cell]
1522
+ glue("mean_acc_ks", "{:0.0f}".format(100*accuracies_grid["mean_test_score"].mean()))
1523
+ glue("std3_acc_ks", "{:0.0f}".format(3*100*accuracies_grid["mean_test_score"].std()))
1524
+ glue("mean_sem_acc_ks", "{:0.0f}".format(100*accuracies_grid["sem_test_score"].mean()))
1525
+ glue("n_neighbors_max", "{:0.0f}".format(accuracies_grid["n_neighbors"].max()))
1526
+ glue("n_neighbors_min", "{:0.0f}".format(accuracies_grid["n_neighbors"].min()))
1527
+ ```
1528
+
1529
+ At first glance, this is a bit surprising: the performance of the classifier
1530
+ has not changed much at all despite tuning the number of neighbors! For example, our first model
1531
+ with $K =$ 3 (before we knew how to tune) had an estimated accuracy of {glue: text }` cancer_acc_1 ` %,
1532
+ while the tuned model with $K =$ {glue: text }` best_k_unique ` had an estimated accuracy
1533
+ of {glue: text }` cancer_acc_tuned ` %.
1534
+ But upon examining {numref}` fig:06-find-k ` again closely&mdash ; to revisit the
1535
+ cross validation accuracy estimates for a range of neighbors&mdash ; this result
1536
+ becomes much less surprising. From {glue: text }` n_neighbors_min ` to around {glue: text }` n_neighbors_max ` neighbors, the cross
1537
+ validation accuracy estimate varies only by around {glue: text }` std3_acc_ks ` %, with
1538
+ each estimate having a standard error around {glue: text }` mean_sem_acc_ks ` %.
1539
+ Since the cross-validation accuracy estimates the test set accuracy,
1540
+ the fact that the test set accuracy also doesn't change much is expected.
1541
+
1481
1542
## Summary
1482
1543
1483
1544
Classification algorithms use one or more quantitative variables to predict the
0 commit comments