我需要创建一个自定义转换器作为评分器的输入。
评分器将一个字典列表传递给我的估计器的 predict 或 predict_proba 方法,而不是一个 DataFrame。这意味着模型必须能够处理这两种数据类型。因此,我需要提供一个自定义的 ColumnSelectTransformer 来替代 scikit-learn 自带的 ColumnTransformer。
这是我为自定义转换器编写的代码,旨在对提供的列中的空值进行填补。
from sklearn.impute import SimpleImputersimple_cols = ['BEDCERT', 'RESTOT', 'INHOSP', 'CCRC_FACIL', 'SFF', 'CHOW_LAST_12MOS', 'SPRINKLER_STATUS', 'EXP_TOTAL', 'ADJ_TOTAL']class ColumnSelectTransformer(BaseEstimator, TransformerMixin): def __init__(self, columns): self.columns = columns def fit(self, X, y=None): return self def transform(self, X): if not isinstance(X, pd.DataFrame): X = pd.DataFrame(X) return X[self.columns].values simple_features = Pipeline([ ('cst', ColumnSelectTransformer(simple_cols)), ('imputer', SimpleImputer(strategy='mean')),])
然后我的任务是创建一个新的管道并用一个估计器进行拟合,以下是我的尝试。
from sklearn.linear_model import LinearRegressionsimple_features_model = Pipeline([ ('simple', simple_features), ('linear', LinearRegression()),])simple_features_model.fit(data, fine_counts > 0)
管道成功生成
Pipeline(memory=None, steps=[('simple', Pipeline(memory=None, steps=[('cst', ColumnSelectTransformer(columns=['BEDCERT', 'RESTOT', 'INHOSP', 'CCRC_FACIL', 'SFF', 'CHOW_LAST_12MOS', 'SPRINKLER_STATUS', 'EXP_TOTAL', 'ADJ_TOTAL'])), ('imputer', SimpleImputer(add_indicator=False, copy=True, fill_value=None, missing_values=nan, strategy='mean', verbose=0))], verbose=False)), ('linear', LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False))], verbose=False)
然而,当我将我的 simple_features_model 传递给学校的评分器时
def positive_probability(model): def predict_proba(X): return model.predict_proba(X)[:, 1] return predict_probagrader.score.ml__simple_features(positive_probability(simple_features_model))
我得到了以下错误
AttributeError Traceback (most recent call last)<ipython-input-87-243f592b48ee> in <module>() 4 return predict_proba 5 ----> 6 grader.score.ml__simple_features(positive_probability(simple_features_model))/opt/conda/lib/python3.7/site-packages/static_grader/grader.py in func(*args, **kw) 92 def __getattr__(self, method): 93 def func(*args, **kw):---> 94 return self(method, *args, **kw) 95 return func 96 /opt/conda/lib/python3.7/site-packages/static_grader/grader.py in __call__(self, question_name, func) 88 return 89 test_cases = json.loads(resp.text)---> 90 test_cases_grading(question_name, func, test_cases) 91 92 def __getattr__(self, method):/opt/conda/lib/python3.7/site-packages/static_grader/grader.py in test_cases_grading(question_name, func, test_cases) 40 for test_case in test_cases: 41 if inspect.isroutine(func):---> 42 sub_res = func(*test_case['args'], **test_case['kwargs']) 43 elif not test_case['args'] and not test_case['kwargs']: 44 sub_res = func<ipython-input-87-243f592b48ee> in predict_proba(X) 1 def positive_probability(model): 2 def predict_proba(X):----> 3 return model.predict_proba(X)[:, 1] 4 return predict_proba 5 /opt/conda/lib/python3.7/site-packages/sklearn/utils/metaestimators.py in __get__(self, obj, type) 108 continue 109 else:--> 110 getattr(delegate, self.attribute_name) 111 break 112 else:AttributeError: 'LinearRegression' object has no attribute 'predict_proba'
回答:
线性回归模块确实没有 predict_proba
属性(请查看文档),原因非常简单:概率估计仅适用于分类模型,而不适用于回归(即数值预测)模型,如线性回归。
由于你的帖子中没有明确说明你是进行回归还是分类操作:
- 如果你是进行回归操作,只需将
predict_proba
替换为predict
即可。 - 如果你是进行分类操作,你不能使用线性回归 – 请尝试使用逻辑回归(尽管名称如此,它是一种分类算法),它确实具有
predict_proba
属性(再次查看文档)。