《Python大规模机器学习》 —3.2.4使用SGD实现大规模SVM
3.2.4使用SGD实现大规模SVM
考虑到子采样的局限性(首先是指在大数据集上训练模型的欠拟合),当使用Scikit-learn中的适合于大规模流的线性SVM时,可用的唯一选项仍然是SGDClassifier和SGDRegressor方法,它们都包含在linear_model模块中。我们来看看如何以最佳方式使用它们,并改进我们在示例数据集上的结果。
我们利用本章前面示例中讨论的线性和逻辑回归来将其转化为高效SVM。至于分类,则需要使用loss超参数来设置损失类型。参数取值为'hinge'、'squared_hinge'和'modified_huber'。前面说明SVM公式时已对这些损失函数做了介绍和讨论。
这么做意味着使用软边界的线性SVM(无核函数),这将让SVM能抵抗误分类和噪声数据。但是,也可以使用损失“感知器”,这是一种引起无边界的hinge loss的损失类型,它适应于处理偏差较大的模型。
使用hinge loss函数时,必须考虑以下两方面才能得到最佳结果:
使用任何损失函数时,随机梯度下降变得懒惰,仅在示例违反以前定义的边界时才更新系数向量。这与在对数或平方误差中的损失函数完全相反,这时实际上每个示例都会用于更新系数向量。如果学习中涉及许多特征,那么这种懒惰方法会产生更稀疏的系数向量,从而减少过拟合。(更密集的向量意味着更多过拟合,因为某些系数可能捕获比数据信号中更多的噪声。)
仅'modified_huber'损失允许概率估计,这使它成为逻辑损失(详见随机逻辑回归)的可行替代方法。经过改进的Huber在处理多类的一对多(OVA)预测时,其多模型概率输出优于hinge loss的标准决策函数特征(概率比决策函数原始输出更好,因为其规模相同,在0~1之间)。该损失函数直接从决策函数中估计概率来工作:。
至于回归问题,SGDRegressor有两个SVM损失选项:
两者都能启动线性支持向量回归,在ε值内的误差将被忽略(预测残差)。如果超过ε值
,epsilon_insensitive损失会将此错误按原样处理。squared_epsilon_insensitive损失以类似方式运行,因为平凡导致误差更严重,但更大误差会影响构建更多模型。
在这两种情况下,设置正确的epsilon超参数至关重要。作为默认值,Scikit-learn建议epsilon = 0.1,但问题的最佳值必须通过交叉验证网格搜索来确定,具体过程将在下一段中看到。
请注意,在回归损失中,还可使用不启动SVM优化的'huber'损失,而只是通过从平方切换到线性损失传递epsilon参数值距离方式来修改常用的'squared_loss',这样会对于异常值不敏感。
在本示例中,我们将重复流过程若干次,以演示如何设置不同超参数和变换特征;我们将使用方便的函数来减少重复的代码行数量。此外,限制实例数量或算法的容差值可以加快实例运行速度。以这种方式能保持最短训练和验证时间,而不会让你等太久。
至于方便的包装函数,第一个将有目的地一次流化部分或全部数据(使用max_rows参数设置限制)。完成流化后,该函数找出所有分类特征的级别并记录数字的不同范围。提醒一下,记录范围是非常重要的。SGD和SVM算法对不同范围尺度非常敏感,它们在处理[-1,1]范围以外的数据时性能较差。
我们的函数输出返回两个已训练的Scikit-learn对象:DictVectorizer(将字典中的特征范围转换为特征向量)和重新缩放[0,1]范围内的数值变量的MinMaxScaler(用于保持数据集中的值稀疏,从而使得内存使用率降低,并在大多数值为零时实现快速计算)。唯一约束是要求用户知道用于预测模型的数值和类别变量的特征名,实际上忽略未包含在binary_features或numeric_features参数列表中的特征。如果流没有特征名,则需要使用fieldnames参数对其命名:
该代码能轻松地用于你自己的大规模数据的机器学习应用程序。如果你的数据流是在线数据流(连续数据流)或数据流太长,则通过设置max_rows参数来限制不同的观察示例数量。
第二个函数从数据流中提取数据并将其转换为特征向量,如果提供合适的MinMaxScaler对象而不是None设置,则规范化数字特征:
有了这两个函数,现在再次模拟在前一章中提到的第一个回归问题(即共享单车数据集),但这次使用hinge loss而不是以前使用的均方差。
第一步,提供要流化的文件名以及一个属性和数值变量的列表(来自文件标题和文件原始信息),我们的封装函数代码将返回某些热编码变量和值范围的相关信息。在这种情况下,大多数变量为二进制,这对稀疏表示来说非常完美,因为数据集中的大多数值都为零:
从输出结果不难看出,已使用其变量名将定性变量编码,并在下划线后添加其值,然后将其转换为二进制特征(特征存在时值为1,否则将其设置为零)。请注意,我们一直将SGD模型参数设置为average=True来保证具有更快收敛性(对应于上一章讨论的平均随机梯度下降(ASGD)模型):
现在处理森林覆盖类型的分类问题:
从流中采样并拟合DictVectorizer和MinMaxScaler对象并得到大量可用实例后,这次使用渐进式验证开始学习过程(在其训练前通过对实例测试模型给出错误度量),对于代码中通过sample变量指定的每一批某数量的示例,脚本都会通过显示最近示例的平均准确度来报告情况:
在必须处理超过575 000个实例的情况下,我们设置在学习50 000个实例后程序提前停止。读者可根据计算机的效率和时间可用性自由修改这些参数,注意,代码运行可能需要一些时间。我们在时钟频率为2.20GHz的英特尔酷睿i3处理器上的计算时间大约为30分钟。
- 点赞
- 收藏
- 关注作者
评论(0)