我的问题是关于基于训练集创建自定义转换并将其重新应用于新的观测值。为了实现这个目标,我通常使用sklearn中的Pipeline对象。
我要构建的转换是针对分类变量的自定义分组。该方法允许选择类别被认为是稀有的比例。如果某个类别的出现比例小于指定的比例(参数),则我们将该类别归类(重命名)为“其他”。
当测试集中的某些类别不在火车集中出现时,就会出现问题。下面的代码引发以下错误:
ValueError: Cannot setitem on a Categorical with a new category, set the
categories first
这是我使用的代码:
trainDF = df[0:8000]
testDF = df[8000:10142]
class CustomBinningCategoricalFeature(TransformerMixin):
def __init__(self, percRareClass):
self.percRareClass = percRareClass
self.rareClass = {}
def fit(self, X, y = 0):
for column_name in list(X.head(0)):
if (X[column_name].dtype != np.dtype(float)):
df = pd.crosstab(index = X[column_name], columns = 'count')
df['prop'] = df['count']/df['count'].sum()
self.rareClass[column_name] = df.index[df['prop'] < self.percRareClass].tolist()
return(self)
def transform(self, X, y = 0):
for column_name in self.rareClass.keys():
#X.loc[~X[column_name].isin(list(X[column_name].unique())), column_name] = 'OTHER'
X.loc[X[column_name].isin(self.rareClass[column_name]), column_name] = 'OTHER'
return X
pipeline = make_pipeline(CustomBinningCategoricalFeature(0.01))
pipeline.fit(trainDF)
transformed_testDF = pipeline.transform(testDF)
在行业中,可能会发生新类别。在这种情况下,我们面临至少两个选择:
如果火车组中的类别未知,则不对新数据评分
由于这是第一次出现该类别,因此我们可以将其视为稀有类别,因此我们将其分配为“ OTHER”类别。
在我们的情况下,我们要选择第二个选项。
您是否知道一种编码拟合和变换方法的方法,以便在管道中使用它们并根据上面的第二个选项将变换应用于新数据(将“ OTHER”分配给测试集中出现的新类别)?