我正在设计一个数据库表来存储机器学习特征(即特征存储),并且正在考虑使用这个高/窄模式:event_date, feature_name, feature_value, creation_date
.
这适用于简单的功能,但似乎在更复杂的场景中有所不足。
让我们考虑一个示例场景,我们想要存储与商店相关的功能(商品购买,订单取消......),我们可能有看起来像的功能
活动日期 | 商店名称 | 特征名称 | 特征值 | 创建日期 |
---|---|---|---|---|
2021-01-01 | 食品公司 | items_sold | 10 | 2021-05-01 |
2021-01-02 | 食品公司 | items_sold | 5 | 2021-05-01 |
2021-01-01 | 补充剂公司 | items_sold | 8 | 2021-05-01 |
2021-01-02 | 补充剂公司 | items_sold | 3 | 2021-05-01 |
2021-01-01 | 食品公司 | 订单取消 | 2 | 2021-05-01 |
但是如果我想跟踪更精细的数据,例如产品名称或客户类型,该怎么办?上述模式是否足够灵活?我将如何存储额外的元数据?
架构提案 1
这将元数据包含在特征名称中,例如cheese_item_purchases_french_customer
表示cheese
从 a 购买项目french_customer
,将这两条元数据存储在feature_name
活动日期 | 商店名称 | 特征名称 | 特征值 | 创建日期 |
---|---|---|---|---|
2021-01-01 | 食品公司 | cheese_item_purchases_french_customer | 9 | 2021-05-01 |
2021-01-01 | 食品公司 | cheese_item_purchases_german_customer | 4 | 2021-05-01 |
2021-01-01 | 补充剂公司 | 维生素_d_item_purchases_french_customer | 7 | 2021-05-01 |
2021-01-01 | 补充剂公司 | 维生素_d_item_purchases_german_customer | 2 | 2021-05-01 |
2021-01-01 | 食品公司 | orders_cancelled_french_customer | 2 | 2021-05-01 |
似乎很难查询,需要知道 feature_name 列的确切结构
架构提案 2
添加元数据列
活动日期 | 商店名称 | 特征名称 | 元数据 | 特征值 | 创建日期 |
---|---|---|---|---|---|
2021-01-01 | 食品公司 | items_sold | {product_name:奶酪,customer_class:法国} | 9 | 2021-05-01 |
2021-01-01 | 食品公司 | items_sold | {product_name:奶酪,customer_class:德语} | 4 | 2021-05-01 |
2021-01-01 | 补充剂公司 | items_sold | {product_name:vitamin_d,customer_class:法语} | 7 | 2021-05-01 |
2021-01-01 | 补充剂公司 | items_sold | {product_name:vitamin_d,customer_class:德语} | 2 | 2021-05-01 |
2021-01-01 | 食品公司 | 订单取消 | {customer_class:法语} | 2 | 2021-05-01 |
查询似乎也很困难(而且效率低下?)
架构提案 3
使用两个表来存储特征值和特征元数据
特征存储表
活动日期 | 商店名称 | 特征名称哈希 | 特征值 | 创建日期 |
---|---|---|---|---|
2021-01-01 | 食品公司 | 特征_1 | 10 | 2021-05-01 |
2021-01-01 | 食品公司 | 特征_2 | 5 | 2021-05-01 |
2021-01-01 | 补充剂公司 | 特征_1 | 8 | 2021-05-01 |
2021-01-01 | 补充剂公司 | 特征_2 | 3 | 2021-05-01 |
2021-01-01 | 食品公司 | 特征_3 | 2 | 2021-05-01 |
特征元数据表
特征名称哈希 | 特征名称 | 元数据名称 | 元数据值 |
---|---|---|---|
特征_1 | items_sold | 产品名称 | 起司 |
特征_1 | items_sold | 客户类 | 法语 |
特征_2 | items_sold | 产品名称 | 起司 |
特征_2 | items_sold | 客户类 | 德语 |
特征_3 | 订单取消 | 客户类 | 法语 |
似乎是最灵活和最干净的,但会使查询可能更复杂。例如,我如何检索 have 中feature_store_table
的所有条目{'product_name': 'cheese', 'customer_class': 'french'}
?
当然,所有这些的替代方法是为每个功能使用多个短/宽表,但对于我的用例,我更喜欢坚持高/窄格式。
您对提议的方法或我错过的任何更好的方法有什么建议吗?不管上述前提如何,我一定要考虑转移到多个短/宽表吗?
谢谢