Icevivian 2020-08-25
本文转自雷锋网,如需转载请至雷锋网官网申请授权。
大多数的机器学习实践者都曾遇到过训练数据和实际运行时用以评估模型的样本差别很大的情况。因此,相对灵活的机器学习解决方案,如DNN和随机森林等,仅依赖于训练数据的模型,在训练数据集和验证数据集没有覆盖的输入空间的表现经常出乎意料甚至是疯狂的。这个问题在重要的政策和公平性约束条件可能被打破的案例下变得尤为严重。
没有被约束的模型在只有很少的训练样本覆盖的输入空间中,可能表现得出乎意料。如图所示,深度神经网络和梯度提升树的预测结果和测试集的真实结果相去甚远。
即便通常情况下正则化能够的到更稳妥的推断结果,但标准的正则化工具并不能确保模型在所有的输入空间里都表现的合理,特别是当输入空间的维度很高时。切换到简单、可控且行为可期的模型将以严重牺牲模型准确率作为代价。
TF Lattice使得在采用(高准确率)灵活模型的同时,通过一些选项,通过一些有语义意义的通识或是策略驱动的形状限制,向学习过程注入领域知识成为可能。例如,你可以指定,模型的输入相对于给定的输入应该是单调递增的。这些额外的领域知识可以帮助模型学习到训练数据以外的知识,并且使得模型的行为对用户来说是可期、可控的。
TensorFlow Lattice 是一个类库用来训练有约束的、可解释的基于栅格的模型。栅格是一个插值查询表,可以用来近似数据中任意的输入-输出关系 。
上述例子是一个基于2个输入特征和4个参数的栅格函数,这4个参数是栅格函数在输入空间4个顶角的函数值;其他函数值是通过这些参数得到的插值。你也可以采用更高维度的栅格或者更细粒度网格参数来的到更灵活的函数。该类库利用Keras层对象tfl.layers.Lattice实现栅上述栅格。TensorFlow 栅格也提供了分段线性函数(tfl.layers.PWLCalibration Keras 层)来校准和规范化输入的特征到栅格函数可接受的输入范围:上述栅格例子是0到1。
针对分类的特征,TensorFlow栅格提供了分类类型的校准,得到类似的输出边界,以便于输入到栅格中。结合上述的校准器和栅格,我们将得到校准后的栅格模型。
TensorFlow Lattice层提供了许多类型的约束,可以被用来向模型的训练过程注入领域知识:
除了形状约束之外,TensorFlow lattice 提供了一系列正则器来控制函数在每个特征上的灵活性和平滑性。这包括拉普拉斯正则化(更平坦的函数),海森正则化(更加线性校准的函数),褶皱正则化(更加平滑的校准函数)以及扭曲正则化(更加成对线性的栅格函数)。
这个案例来自我们端到端的函数形状约束教程,该教程涉及许多包含上面提到的约束条件的估计器,开箱即用。假设我们的场景是确定用户是否会点击某个餐馆搜索中得到的结果。这是一个点击率预估任务(CTR),给定特征包括:
我们有如下领域知识来限制或空值我们模型的行为:
我们可以利用TensorFlow Lattice提供的Keras层来创建一个校准的栅格模型。
model = tf.keras.models.Sequential()model.add( tfl.layers.ParallelCombination([ # Feature: average rating tfl.layers.PWLCalibration( # Input keypoints for the piecewise linear function input_keypoints=np.linspace(1., 5., num=20), # Output is monotonically increasing in this feature monotonicity='increasing', # This layer is feeding into a lattice with 2 vertices output_min=0.0, output_max=1.0), # Feature: number of reviews tfl.layers.PWLCalibration( input_keypoints=np.linspace(0., 200., num=20), # Output is monotonically increasing in this feature monotonicity='increasing', # There is diminishing returns on the number of reviews convexity='concave', # Regularizers defined as a tuple ('name', l1, l2) kernel_regularizer=('wrinkle', 0.0, 1.0), # This layer is feeding into a lattice with 3 vertices output_min=0.0, output_max=2.0), # Feature: dollar rating tfl.layers.CategoricalCalibration( # 4 rating categories + 1 missing category num_buckets=5, default_input_value=-1, # Partial monotonicity: calib(0) <= calib(1) monotonicities=[(0, 1)], # This layer is feeding into a lattice with 2 vertices output_min=0.0, output_max=1.0), ]))model.add( tfl.layers.Lattice( # A 2x3x2 grid lattice lattice_size=[2, 3, 2], # Output is monotonic in all inputs monotonicities=['increasing', 'increasing', 'increasing'] # Trust: more responsive to input 0 if input 1 increases edgeworth_trusts=(0, 1, 'positive')))model.compile(...)
上述栅格使得训练得到的模型满足所有给定的约束,并且额外添加的正则化使得模型更加平滑: