用Python从零开始实现机器学习Baseline
在预测建模问题上建立基准性能是重要的。
基准线为之后评估的更高级方法提供了一个比较点。
在这个教程中,你将学习如何从头开始用Python实现基础的机器学习算法。
完成本教程后,您将了解:
- 如何实现随机预测算法。
- 如何实现零规则预测算法。
描述
有很多机器学习算法可供选择。事实上,有数百种。
你必须知道给定算法的预测结果是好还是坏。但你怎么知道呢?
答案是使用基准预测算法。基准预测算法提供了一组预测值,你可以像评估任何其他预测值一样来评估这些预测值,例如分类准确率或RMSE。
这些算法的得分在评估你的问题上的所有其他机器学习算法时提供了所需的比较点。
一旦建立,你就可以评论某个给定的算法相比朴素基线算法有多大的改进,提供有关给定方法实际有多好的上下文信息。
最常使用的两个基线算法是:
- 随机预测算法。
- 零规则算法。
当开始解决一个比传统分类或回归问题更棘手的新问题时,首先为你的预测问题设计一个特定的随机预测算法是个好主意。之后你可以在此基础上改进,设计一个零规则算法。
教程
本教程分为2部分:
- 随机预测算法。
- 零规则算法。
这些步骤将为你提供处理实施和计算机器学习算法基准性能所需的基础。
1. 随机预测算法
随机预测算法预测的结果是根据训练数据中观察到的随机情况。
这可能是一个最简单的算法来实现。
它要求你存储训练数据中所有不同的结果值,这在回归问题中可能有很多不同的值,因此可能会很大。
因为随机数用于做决策,在使用算法之前固定随机数种子是个好主意。这是为了确保每次运行算法时我们得到的随机数集相同,从而做出相同的决策。
以下是实现随机预测算法的函数random_algorithm()。
该函数需要一个包含输出值的训练数据集和一个用于预测输出值的测试数据集。
该函数适用于分类和回归问题。它假定训练数据中每行的最后一列是输出值。
首先,从训练数据中收集唯一输出值的集合。然后,对于测试集中的每一行,从集合中随机选择一个输出值。
# Generate random predictions
def random_algorithm(train, test):output_values = [row[-1] for row in train]unique = list(set(output_values))predicted = list()for row in test:index = randrange(len(unique))predicted.append(unique[index])return predicted
我们可以用一个只包含输出列的简单小数据集来测试这个函数。
训练数据集的输出值要么是“0”要么是“1”,这意味着算法将从中选择的预测集合是{0, 1}。测试集也包含一列数据,因为预测结果未知,所以没有数据。
from random import seed
from random import randrange# Generate random predictions
def random_algorithm(train, test):output_values = [row[-1] for row in train]unique = list(set(output_values))predicted = list()for row in test:index = randrange(len(unique))predicted.append(unique[index])return predictedseed(1)
train = [[0], [1], [0], [1], [0], [1]]
test = [[None], [None], [None], [None]]
predictions = random_algorithm(train, test)
print(predictions)
运行此示例会为测试数据集计算随机预测并打印这些预测。
随机预测算法易于实现且运行速度快,但作为基准我们可以做得更好。
2. 零规则算法
零规则算法比随机算法是一个更好的基准。
它使用关于给定问题的更多信息来创建一条规则,以便进行预测。这规则因问题类型不同而不同。
让我们从分类问题开始,预测一个类别标签。
分类
对于分类问题,一条规则是预测训练数据集中最常见的类值。这意味着,如果训练数据集中有90个“0”类实例和10个“1”类实例,那么它将预测“0”,并达到90/100或90%的基准准确率。
这比只能平均达到82%准确率的随机预测算法要好得多。关于如何估算随机搜索的准确率的详细信息,请参见下文:
= ((0.9 * 0.9) + (0.1 * 0.1)) * 100
= 82%
下面是一个名为zero_rule_algorithm_classification()的函数,该函数实现了分类情况下的零规则算法。
# zero rule algorithm for classification
def zero_rule_algorithm_classification(train, test):output_values = [row[-1] for row in train]prediction = max(set(output_values), key=output_values.count)predicted = [prediction for i in range(len(test))]return predicted
该函数利用了max()函数的key属性,这有点巧妙。
给定训练数据中观察到的类值列表,max()函数接受一组唯一的类值,并对集合中的每个类值对类值列表进行计数。
结果是,它返回在训练数据集中观察到的类值列表中出现次数最多的类值。
如果所有类别的值出现次数相同,则我们选择在数据集中观察到的第一个类别值。
一旦我们选择了一个类值,它将用于对测试数据集中的每一行进行预测。
以下是一个使用人为数据集的示例,该数据集包含4个“0”类和2个“1”类的示例。我们期望算法为测试数据集中的每一行选择“0”类作为预测结果。
from random import seed
from random import randrange# zero rule algorithm for classification
def zero_rule_algorithm_classification(train, test):output_values = [row[-1] for row in train]prediction = max(set(output_values), key=output_values.count)predicted = [prediction for i in range(len(test))]return predictedseed(1)
train = [['0'], ['0'], ['0'], ['0'], ['1'], ['1']]
test = [[None], [None], [None], [None]]
predictions = zero_rule_algorithm_classification(train, test)
print(predictions)
回归
回归问题需要预测一个实数值。
对于实值的良好默认预测是预测中心趋势。这可以是均值或中位数。
一个好的默认值是使用训练数据中输出值的平均值(也称为平均数)。
这可能会比随机预测有更低的误差,随机预测将返回任何观察到的输出值。
下面是一个执行此功能的函数,名为zero_rule_algorithm_regression()。它通过计算观察到的输出值的平均值来工作。
mean = sum(value) / total values
一旦计算出均值,然后预测训练数据中每一行的均值。
from random import randrange# zero rule algorithm for regression
def zero_rule_algorithm_regression(train, test):output_values = [row[-1] for row in train]prediction = sum(output_values) / float(len(output_values))predicted = [prediction for i in range(len(test))]return predicted
这个函数可以用一个简单的例子来测试。
我们可以构造一个小型数据集,已知其平均值为15。
10
15
12
15
18
20mean = (10 + 15 + 12 + 15 + 18 + 20) / 6
mean = 90 / 6
mean = 15
以下是完整的示例。我们期望测试数据集中的每一行都会预测出均值为15。
from random import seed
from random import randrange# zero rule algorithm for regression
def zero_rule_algorithm_regression(train, test):output_values = [row[-1] for row in train]prediction = sum(output_values) / float(len(output_values))predicted = [prediction for i in range(len(test))]return predictedseed(1)
train = [[10], [15], [12], [15], [18], [20]]
test = [[None], [None], [None], [None]]
predictions = zero_rule_algorithm_regression(train, test)
print(predictions)
运行示例会计算预测的输出值并打印出来。如预期的那样,测试数据集中每一行的均值为15。
[15.0, 15.0, 15.0, 15.0, 15.0, 15.0]
扩展
以下是一些您可以作为本教程的扩展进行调查和实现的基准算法的扩展。
- 替代中心趋势,其中中位数、众数或其他中心趋势计算被预测而不是平均值。
- 移动平均法用于时间序列问题,其中预测的是最后n个记录的平均值。