帮助解决 ML 问题的类型:当训练数据分布在不同的子组/类别中时

数据挖掘 机器学习
2021-10-06 15:57:30

我一直在寻找一段时间,但没有任何运气 - 希望有更多知识的人可以就我一直在考虑的以下 ML 问题给我一些建议:

假设您试图在电影上映前预测烂番茄“番茄计”的得分。通常,您可以通过编译一些现有电影的特征和标签列表并将其输入到有监督的 ML 算法中来解决此问题。

在此示例中,功能列表将是描述电影的标准指标,例如预算、拍摄时长、演员人数等,而标签是电影的 Tomatometer 得分,以 0 到 100 之间的值给出. 每部电影都可以使用这个分数来表达,但它们单独分布在许多类型、制作国家等,这意味着训练数据中有自然子集。

假设我们的训练数据仅包含属于五种类型的电影(例如动作、惊悚、恐怖、奇幻和纪录片),而我们希望我们的算法适用于该类型以外的电影(例如科幻或动画),但对于出于疑问,我们无法访问这些整个类别。在此示例中,还假设某些特征对某些类型比其他类型更重要,例如,与动画相比,大型演员阵容可能与动作片的得分相关性更高。

转换数据以使其对子组(流派)不变的一般方法是什么,或者这里可以使用什么 ML 算法(如果有的话)?这种情况是否有通用名称(我可以搜索一些关键字?)

1个回答

我将尝试改写您的问题:如何使用某些类别特征中包含的信息x来预测y测试集中存在看不见的类别值的情况?

假设训练集代表测试集分布,您会期望测试集中也存在大类别。

因此,我们主要关注可能存在于训练集中但不存在于测试集中和/或存在于测试集中但不存在于训练集中的小类别。

处理这种情况的一种方法是将小类别(例如,低于所有观察值的 2%)合并为一个类别。这样,您就可以将任何新类别级别视为合并类别的一部分。

下面我分享一下我是如何在 python 中实现上述内容的,以一种可以在 scikit learn 管道中组合的方式:

from collections import Counter
import pandas as pd

class mergeSmallCategoryLevels():
    def __init__(self, min_frac):
        self.min_frac = min_frac
        
    def fit(self, X, y=None, **fit_params):
        category_counts = pd.DataFrame.from_dict(Counter(X), orient = "index", columns = ["count"])
        min_category_count = len(X)*self.min_frac
        large_categories = category_counts[category_counts["count"] >= min_category_count]
        self.large_categories = list(large_categories.index.values)
        return self

    def transform(self, X, **transform_params):
        ans = [val if val in self.large_categories else ".merged" for val in X]
        ans = pd.DataFrame({"category_feature":ans})
        return ans.to_numpy().reshape(-1, 1)