【问题标题】:How to implement a Python custom class for outliers removal in pipeline?如何为管道中的异常值删除实现 Python 自定义类?
【发布时间】:2021-05-24 13:39:54
【问题描述】:

我正在尝试通过 Isolation Forest 算法实现一个 Python 自定义类,用于异常值检测和删除。我的计划是在GridSearchCV 中使用它来调整神经网络(回归)的超参数。这是我的代码,

class OutlierExtractor(BaseEstimator, TransformerMixin):
    def __init__(self, contamination):
        self.contamination = contamination
        self.mask = None

    def fit(self, X, y):
        iso = IsolationForest(contamination = self.contamination)
        yhat = iso.fit_predict(X)
        mask = yhat != -1
        self.mask = mask
        return self
    
    def transform(self, X, y):
        X = X[self.mask, :]
        y = y[self.mask]
        return (X, y)

和管道

estimator = Pipeline([
            ('outliers', OutlierExtractor(0.1)),...
            ]

但是,运行grid_result = grid.fit(X, Y) 会给出错误transform() missing 1 required positional argument: 'y'。 如何解决? 此外,如果能够对污染参数进行调整,那就太好了。

【问题讨论】:

    标签: python python-3.x scikit-learn deep-learning pipeline


    【解决方案1】:

    运行grid_result = grid.fit(X, Y) 它给出了错误transform() missing 1 required positional argument: 'y'

    尽管您没有提供grid 的完整回溯和实现细节,但我几乎可以肯定问题出在您的OutlierExtractor.transform 方法中。它不符合 scikit-learn 转换器 API,其中 transform 方法预计仅返回(修改的)样本 X,但您同时返回 Xy。错误可能是由其他原因引起的,您可能必须先解决这些问题。

    如何解决?此外,如果能够对污染参数进行调整,那就太好了。

    恐怕无法在 scikit-learn 管道中设置异常值检测。修复 transform 也无济于事。理想情况下,我们希望在Pipeline 中支持中间 异常值检测(我们有Pipeline.fit_predict 仅用于最后 步异常值检测,例如当IsolationForest是管道中的最终预测器)。但是,这还没有实现。如果我没记错的话,scikit-learn 的官方 github 存储库中有一个关于这个问题的问题。另外,这里有一个 scikit-learn 增强提案SLEP001,它也涉及异常值检测。

    为了在模型选择中包含IsolationForest,您需要手动为其创建一个参数网格,并为该网格的每个条目启动GridSearchCV。这是一个最小的例子:

    from sklearn.ensemble import IsolationForest
    from sklearn.model_selection import ParameterGrid  # or ParameterSampler
    from sklearn.model_selection import train_test_split, GridSearchCV
    
    X, y = # your data
    grid = GridSearchCV( # your model grid search )
    
    isolation_forest = IsolationForest()
    isolation_forest_params = {
        'max_features': (0.5, 0.75, 1.0),
        'bootstrap': (False, True),
        'contamination': (0.1, 0.2, 0.3),
    }
    isolation_forest_param_grid = ParameterGrid(isolation_forest_params)
    
    # Here we split data once but you might want to use
    # nested cross-validated grid search instead.
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1)
    
    best_score, best_params = 0, {}
    for params in isolation_forest_param_grid:
        isolation_forest.set_params(**params)
        outlier_mask = isolation_forest.fit_predict(X_train)
        X_inliers, y_inliers = X_train[outlier_mask == 1], y_train[outlier_mask == 1]
    
        grid.fit(X_inliers, y_inliers)
        score = grid.score(X_test, y_test)
        if score > best_score:
            best_score = score
            best_params = grid.best_params_
            # Prepending 'if' prefix so that parameter names will not overlap.
            best_params.update({f'if__{k}': v for k, v in params.items()})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-16
      • 1970-01-01
      • 2020-10-30
      • 2017-10-11
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      相关资源
      最近更新 更多