我正在开发一种“预测模型即服务”的应用程序,其结构如下:

  • 离线训练模型
  • 定期将模型参数上传到“预测服务器”
  • 预测服务器
  • 将单个观测值作为输入,并输出预测

  • 我正在尝试使用patsy,但遇到以下问题:当出现单个预测时,如何将其转换为正确的形状,使其看起来像一排训练数据?

    当训练数据中的DesignInfo在内存中可用时,patsy文档提供了一个示例:http://patsy.readthedocs.io/en/latest/library-developers.html#predictions
    # offline model training
    import patsy
    
    data = {'animal': ['cat', 'cat', 'dog', 'raccoon'], 'cuteness': [3, 6, 10, 4]}
    eq_string = "cuteness ~ animal"
    
    
    dmats = patsy.dmatrices(eq_string,data)
    design_info = dmats[1].design_info
    train_model(dmats)
    
    
    # online predictions
    input_data = {'animal': ['raccoon']}
    
    # if the DesignInfo were available, I could do this:
    new_dmat = build_design_matrices([design_info], input_data)
    make_prediction(new_dmat, trained_model)
    

    然后输出:
    [DesignMatrix with shape (1, 3)
       Intercept  animal[T.dog]  animal[T.raccoon]
               1              0                  1
       Terms:
         'Intercept' (column 0)
         'animal' (columns 1:3)]
    

    请注意,该行与训练数据的形状相同;它有一个animal[T.dog]列。在我的应用程序中,我无法访问DesignInfo来为新数据构建DesignMatrix。具体而言,预测服务器将如何知道训练数据中还有多少其他类别的动物,并且以什么顺序?

    我以为可以 pickle ,但是事实证明还不支持:https://github.com/pydata/patsy/issues/26

    我也可以简单地将矩阵列保留为字符串,然后从该联机中重建矩阵,但这似乎有些脆弱。

    有什么好方法吗?

    最佳答案

    假设您的目标是能够在不进行重新培训的情况下重新启动服务器,则看来最好的选择(直到patsy实现 pickle )是 pickle dataeq_string以及train_model计算的任何参数。然后,在重新启动服务器后,您可以释放dataeq_string,然后再次调用dmats = patsy.dmatrices(eq_string,data)。这应该运行得非常快,因为它实际上并不是在训练模型,而只是预处理数据。然后,您还将解开由train_model计算的参数(问题中未显示),服务器应准备好为新输入进行预测。

    请注意,如果将其分为客户端和服务器组件,则服务器应执行上面讨论的所有操作,而客户端应仅将问题中定义的input_data发送给它。 (客户端不需要查看dmatsdesign_info。)

    10-05 22:17