【问题标题】:How to handle unseen categorical values in test data set using python?如何使用python处理测试数据集中看不见的分类值?
【发布时间】:2017-01-19 04:52:18
【问题描述】:

假设我有定位功能。在火车数据集中,它的唯一值是“NewYork”、“Chicago”。但在测试集中,它有“NewYork”、“Chicago”、“London”。 那么在创建一种热门编码时如何忽略“伦敦”? 也就是说,如何不对只出现在测试集中的类别进行编码?

【问题讨论】:

    标签: python machine-learning feature-extraction categorical-data one-hot-encoding


    【解决方案1】:

    通常您永远不想消除信息。您希望事先将这些信息包装在您的模型中。例如,您可能有一些具有 NaN 值的数据:

    train_data = ['NewYork', 'Chicago', NaN]
    

    解决方案 1

    您可能有办法处理此问题,是否估算、删除等取决于您的问题。通常,您可以将 NaN 作为它自己的类别,因为这也是信息。像这样就足够了:

    # function to replace NA in categorical variables
    def fill_categorical_na(df, var_list):
      X = df.copy()
      X[var_list] = df[var_list].fillna('Missing')
      return X
    
    # replace missing values with new label: "Missing"
    X_train = fill_categorical_na(X_train, vars_with_na)
    X_test = fill_categorical_na(X_test, vars_with_na)
    

    因此,当您转向生产时,您可以编写一个脚本,将看不见的类别推入您之前建立的“缺失”类别中。

    解决方案 2

    如果您对这个想法不满意,您可以随时将这些不寻常的案例变成一个新的独特类别,我们称之为“罕见”,因为它并不经常出现。

    train_data = ['NewYork', 'Chicago', 'NewYork', 'Chicago', 'London']
    
    # let's capture the categorical variables first
    cat_vars = [var for var in X_train.columns if X_train[var].dtype == 'O']
    
    def find_frequent_labels(df, var, rare_perc):
      df = df.copy()
      tmp = df.groupby(var)['Target_Variable'].count() / len(df)
      return tmp[tmp>rare_perc].index
    
    for var in cat_vars:
      frequent_ls = find_frequent_labels(X_train, var, 0.01)
      X_train[var] = np.where(X_train[var].isin(frequent_ls), X_train[var], 'Rare')
      X_test[var] = np.where(X_test[var].isin(frequent_ls), X_test[var], 'Rare')
    

    现在,如果有足够多的“正常”类别实例,伦敦将被推入“稀有”类别。无论出现多少新类别,它们都将被归入“稀有”类别;等待它们仍然是罕见的实例并且不会成为主导类别。

    【讨论】:

    • 有人解释否决票。这清楚地解决了这个问题。
    【解决方案2】:

    您可以在一个热编码中使用参数handle_unknown。

    ohe = OneHotEncoder(handle_unknown=‘ignore’)
    

    这不会显示错误,会执行。

    查看文档了解更多信息 https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html

    【讨论】:

      【解决方案3】:

      假设这是您的列表

      train_data = ['NewYork', 'Chicago']
      test_set = ['NewYork', 'Chicago', 'London']
      

      根据您的问题:

      如何不对只出现在测试集中的类别进行编码?

      for each in test_set:
          if filter(lambda element: each in element, train_data):
              print each
      

      这会输出NewYork & Chicago,这意味着London 被跳过。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-28
        • 2018-07-29
        • 2020-02-10
        • 1970-01-01
        • 2017-10-10
        • 2021-07-03
        • 1970-01-01
        • 2013-02-23
        相关资源
        最近更新 更多