TensorFlow Lattice:灵活、可控、可解释的机器学习
本文转自雷锋网,如需转载请至雷锋网官网申请授权。
大多数的机器学习实践者都曾遇到过训练数据和实际运行时用以评估模型的样本差别很大的情况。因此,相对灵活的机器学习解决方案,如DNN和随机森林等,仅依赖于训练数据的模型,在训练数据集和验证数据集没有覆盖的输入空间的表现经常出乎意料甚至是疯狂的。这个问题在重要的政策和公平性约束条件可能被打破的案例下变得尤为严重。
没有被约束的模型在只有很少的训练样本覆盖的输入空间中,可能表现得出乎意料。如图所示,深度神经网络和梯度提升树的预测结果和测试集的真实结果相去甚远。
即便通常情况下正则化能够的到更稳妥的推断结果,但标准的正则化工具并不能确保模型在所有的输入空间里都表现的合理,特别是当输入空间的维度很高时。切换到简单、可控且行为可期的模型将以严重牺牲模型准确率作为代价。
TF Lattice使得在采用(高准确率)灵活模型的同时,通过一些选项,通过一些有语义意义的通识或是策略驱动的形状限制,向学习过程注入领域知识成为可能。例如,你可以指定,模型的输入相对于给定的输入应该是单调递增的。这些额外的领域知识可以帮助模型学习到训练数据以外的知识,并且使得模型的行为对用户来说是可期、可控的。
TensorFlow Lattice Librayy
TensorFlow Lattice 是一个类库用来训练有约束的、可解释的基于栅格的模型。栅格是一个插值查询表,可以用来近似数据中任意的输入-输出关系 。
上述例子是一个基于2个输入特征和4个参数的栅格函数,这4个参数是栅格函数在输入空间4个顶角的函数值;其他函数值是通过这些参数得到的插值。你也可以采用更高维度的栅格或者更细粒度网格参数来的到更灵活的函数。该类库利用Keras层对象tfl.layers.Lattice实现栅上述栅格。TensorFlow 栅格也提供了分段线性函数(tfl.layers.PWLCalibration Keras 层)来校准和规范化输入的特征到栅格函数可接受的输入范围:上述栅格例子是0到1。
针对分类的特征,TensorFlow栅格提供了分类类型的校准,得到类似的输出边界,以便于输入到栅格中。结合上述的校准器和栅格,我们将得到校准后的栅格模型。
TensorFlow Lattice层提供了许多类型的约束,可以被用来向模型的训练过程注入领域知识:
- 单调性:你可以指定模型输出应该性对输入是单调递增或递减的。在我们的案例里,你也许想要限制模型在预测用户对咖啡店的喜好程度时相对距离是单调递减的,也就是距离越远用户对咖啡店的喜好程度越低。
- 凸性和凹性:你可以指定函数的形状是凸的还是凹的。结合单调性,限制凸性和凹性能够强制函数刻画一些特性,如相对给定的特征收益递减。
- 单峰性:你可以指定函数是单峰的或是单谷的。这可以让你得到相对某个特性具有预期的最佳识别点的函数。
- 成对正向印证: 这个限制表明一个输入特征,在语义上提高了另一个特征更确信程度。例如,具有较高的评论次数的餐厅,将更有信心能得到较高的平均星级评分。但评论数量较大时,模型将对星级评分更加敏感(如相对评分和评论数有更大的斜率)
- 成对优势: 这个约束表明模型应该将某个特征视为更为重要的特征(相比于给定的另一个)。该特性通过确保函数在支配特征上的斜率更大来实现。
除了形状约束之外,TensorFlow lattice 提供了一系列正则器来控制函数在每个特征上的灵活性和平滑性。这包括拉普拉斯正则化(更平坦的函数),海森正则化(更加线性校准的函数),褶皱正则化(更加平滑的校准函数)以及扭曲正则化(更加成对线性的栅格函数)。
案例:参观排序
这个案例来自我们端到端的函数形状约束教程,该教程涉及许多包含上面提到的约束条件的估计器,开箱即用。假设我们的场景是确定用户是否会点击某个餐馆搜索中得到的结果。这是一个点击率预估任务(CTR),给定特征包括:
- 平均评分:一个数值特征,取值从1到5
- 评论数量:一个数值特征,取值从0到200
- 阶梯评分: 分类特征,取值从“$”到“$$$$”,数据表示为0 to 3 缺失值为-1
我们有如下领域知识来限制或空值我们模型的行为:
- 模型的输出相对于平均评分是单调递增的
- 模型的输出相对评论数是单调低递增的,但边际收益递减
- 但有较高的评论数是,模型应该确信平均评分会比较高
- 相比于“$” 的餐馆,用户通常倾向于“$$”的餐馆
我们可以利用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(...)
上述栅格使得训练得到的模型满足所有给定的约束,并且额外添加的正则化使得模型更加平滑: