如何根据真实标签y对特征X进行变换?

我已经查看了其他涉及此主题的问题,例如这个这个这个这个这个,以及一些很棒的博客文章,博客1博客2博客3(向各自的作者致敬),但都没有成功。

我想做的是对X中低于某个阈值的行进行变换,但仅限于目标y中对应某些特定类别的行(y != 9)。阈值是基于另一类别(y == 9)计算的。然而,我在理解如何正确实现这一点上遇到了问题。

由于我想对这个进行参数调优和交叉验证,我将不得不使用管道进行变换。我的自定义变换器类如下所示。请注意,我没有包括TransformerMixin,因为我认为我需要在fit_transform()函数中考虑y

class CustomTransformer(BaseEstimator):    def __init__(self, percentile=.90):        self.percentile = percentile    def fit(self, X, y):        # 计算每列的阈值        thresholds = X.loc[y == 9, :].quantile(q=self.percentile, interpolation='linear').to_dict()        # 存储以便后续使用        self.thresholds = thresholds        return self    def transform(self, X, y):        # 创建X的副本        X_ = X.copy(deep=True)        # 替换每列低于阈值的值        for p in self.thresholds:            X_.loc[y != 9, p] = X_.loc[y != 9, p].apply(lambda x: 0 if x < self.thresholds[p] else x)        return X_    def fit_transform(self, X, y=None):        return self.fit(X, y).transform(X, y)

然后将其输入到管道和后续的GridSearchCV中。我在下面提供了一个工作示例。

imports...# 创建一些示例数据来使用random.seed(12)target = [randint(1, 8) for _ in range(60)] + [9]*40shuffle(target)example = pd.DataFrame({'feat1': sample(range(50, 200), 100),                        'feat2': sample(range(10, 160), 100),                       'target': target})example_x = example[['feat1', 'feat2']]example_y = example['target']# 创建一个最终的嵌套管道,其中包含数据预处理步骤和最终的估计器pipeline = Pipeline(steps=[('CustomTransformer', CustomTransformer(percentile=.90)),                           ('estimator', RandomForestClassifier())])# 使用GridSearchCV进行参数调优p_grid = {'estimator__n_estimators': [50, 100, 200]}gs = GridSearchCV(pipeline, p_grid, cv=10, n_jobs=-1, verbose=3)gs.fit(example_x, example_y)

上述代码给我以下错误。

/opt/anaconda3/envs/Python37/lib/python3.7/concurrent/futures/_base.py in __get_result(self)    382     def __get_result(self):    383         if self._exception:--> 384             raise self._exception    385         else:    386             return self._resultTypeError: transform() missing 1 required positional argument: 'y'

我也尝试了其他方法,例如在fit()期间存储相应的类别索引,然后在transform()期间使用这些索引。然而,由于交叉验证期间的训练和测试索引不相同,当在transform()中替换值时会出现索引错误。

那么,有没有巧妙的方法来解决这个问题呢?


回答:

在评论中我提到的是这个:

class CustomTransformer(BaseEstimator):    def __init__(self, percentile=.90):        self.percentile = percentile    def fit(self, X, y):        # 计算每列的阈值        # 我们将y作为X的最后一列添加,所以移除它        X_ = X.iloc[:,:-1].copy(deep=True)        thresholds = X_.loc[y == 9, :].quantile(q=self.percentile, interpolation='linear').to_dict()        # 存储以便后续使用        self.thresholds = thresholds        return self    def transform(self, X):        # 创建实际X的副本,除了附加的目标        # 我们将y作为X的最后一列添加,所以移除它        X_ = X.iloc[:,:-1].copy(deep=True)        # 使用这里获取y        y =  X.iloc[:, -1].copy(deep=True)        # 替换每列低于阈值的值        for p in self.thresholds:            X_.loc[y != 9, p] = X_.loc[y != 9, p].apply(lambda x: 0 if x < self.thresholds[p] else x)        return X_    def fit_transform(self, X, y):        return self.fit(X, y).transform(X)

然后更改你的X, y:

# 我们将目标附加到Xexample_x = example[['feat1', 'feat2', 'target']]example_y = example['target']

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注