如何为管道中的异常值删除实现 Python 自定义类?
Posted
技术标签:
【中文标题】如何为管道中的异常值删除实现 Python 自定义类?【英文标题】:How to implement a Python custom class for outliers removal in pipeline? 【发布时间】: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'
。
如何解决?
此外,如果能够对污染参数进行调整,那就太好了。
【问题讨论】:
【参考方案1】:运行
grid_result = grid.fit(X, Y)
它给出了错误transform() missing 1 required positional argument: 'y'
尽管您没有提供grid
的完整回溯和实现细节,但我几乎可以肯定问题出在您的OutlierExtractor.transform
方法中。它不符合 scikit-learn 转换器 API,其中 transform
方法预计仅返回(修改的)样本 X
,但您同时返回 X
和 y
。错误可能是由其他原因引起的,您可能必须先解决这些问题。
如何解决?此外,如果能够对污染参数进行调整,那就太好了。
恐怕无法在 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())
【讨论】:
以上是关于如何为管道中的异常值删除实现 Python 自定义类?的主要内容,如果未能解决你的问题,请参考以下文章
Android:如何为 Android ListView 实现这样的操作?
如何为通过 SwiftUI 中的自定义结构传递的 @State 值设置动画