机器学习编程:从编码到深度学习
上QQ阅读APP看书,第一时间看更新

5.3 操作中的分类函数

这是我们最终的二元分类器代码,非常漂亮。它加载Roberto的数据文件,并从中学习,然后输出一堆分类结果,如下所示:

当我们从线性回归问题转向分类问题时,必须修改程序代码中的大多数函数。我们有一个全新的sigmoid()函数。旧的predict()函数被拆分为forward()和classify()这两个单独的函数,前者用于训练样本,后者用于分类输出。我们还修改了用于计算损失及其梯度的数学公式,现在使用的是log损失函数,而不是均方误差函数。因此,我们对loss()函数和gradient()函数有了全新的实现方式。

我们还编写了一个新的test()函数,用于打印输出正确的分类结果占全部分类结果的百分比。指令np.sum(classify(X,w)==Y)的含义是:首先将预测值与标签值进行比较并返回一个数组,其中预测值与标签值相匹配的元素返回True,预测值与标签值不匹配的元素返回False;然后,计算匹配元素的数量。

虽然有些代码自进入线性回归模型的内容后就发生了变化,但是这些代码核心概念并没有改变。loss()函数仍然告诉我们错误的程度。train()函数没有发生任何变化,它仍然使用损失函数的梯度下降方法来查找权重。最后,我们仍然在classify()函数(以前称为predict()函数)中使用这些权重实现对样本数据的分类。下面是我们这个程序运行包含10 000个训练样本时迭代计算的具体情况:

这个程序的准确率为83.3%(30个样本中有25个样本分类正确)。还不算坏!

正确分类的样本所占的比例称为分类器的准确率。虽然准确率并不是衡量分类器性能的最佳标准,但是它简单又直观。因此,准确率这个标准将贯穿本书的始终。ProgML[1]网站给出了更多关于准确率及一些额外的有关度量标准。

[1] https://www.progml.com。参见ProgML 网站上的“The Problem with Accuracy”。