Sklearn TypeError求助:FeatureUnion组合特征需估计器实现fit和transform
解决FeatureUnion的TypeError问题:所有estimator必须实现fit和transform
这个错误的原因非常明确——你直接把已经计算好的特征值列表(比如train_set.dentisty_undictionary)放进了FeatureUnion的transformer_list里,但FeatureUnion要求每个元素都必须是符合sklearn接口的特征转换器(也就是必须有fit()和transform()方法的estimator),而普通列表显然不满足这个要求。
正确的做法:用转换器封装你的特征
根据你的特征类型,分情况处理:
1. 先定义通用列选择器(针对DataFrame场景)
如果你的train_set是pandas DataFrame,其中dentisty_undictionary、file_length是数值列,还有一个文本列(比如叫text)用来生成TF-IDF特征,先写一个自定义转换器提取指定列:
from sklearn.base import BaseEstimator, TransformerMixin class ColumnSelector(BaseEstimator, TransformerMixin): def __init__(self, column_name): self.column_name = column_name def fit(self, X, y=None): # 拟合阶段无需额外操作 return self def transform(self, X): # 返回二维数组(sklearn要求特征矩阵必须是二维格式) return X[[self.column_name]].values
2. 重新构建Pipeline和FeatureUnion
把每个特征用对应的转换器封装后加入FeatureUnion:
from sklearn.pipeline import Pipeline, FeatureUnion from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.svm import SVC process_features = Pipeline([ ('features', FeatureUnion(transformer_list=[ # 提取密度特征 ('dentisty_undictionary', ColumnSelector('dentisty_undictionary')), # 提取文件长度特征 ('file_length', ColumnSelector('file_length')), # 生成TF-IDF特征:先选文本列,再做TF-IDF转换 ('tdm', Pipeline([ ('text_selector', ColumnSelector('text')), ('tfidf', TfidfVectorizer()) ])) ])), ('svc', SVC(kernel='linear')) ])
3. 如果特征是独立列表(非DataFrame列)
如果dentisty_undictionary和file_length是单独的列表,可以用FunctionTransformer来封装:
from sklearn.preprocessing import FunctionTransformer # 定义返回二维数组的函数,满足sklearn特征格式要求 def get_density_feature(X): return [[x] for x in X.dentisty_undictionary] def get_file_length_feature(X): return [[x] for x in X.file_length] process_features = Pipeline([ ('features', FeatureUnion(transformer_list=[ ('dentisty_undictionary', FunctionTransformer(get_density_feature, validate=False)), ('file_length', FunctionTransformer(get_file_length_feature, validate=False)), # 注意:此处TfidfVectorizer需要接收文本数据,请确保输入X包含对应文本字段 ('tdm', TfidfVectorizer()) ])), ('svc', SVC(kernel='linear')) ])
关键提醒
- 所有放进
FeatureUnion的元素必须是能处理输入数据并返回特征矩阵的转换器,不能直接传原始特征值。 - sklearn的特征矩阵要求是二维数组(即使是单特征,也要转成
[[val1], [val2], ...]的形式),这也是我们在转换器里做格式转换的原因。
内容的提问来源于stack exchange,提问作者Lee Jack
相关产品推荐
相关产品推荐

