Sklearn 特征工程
包含sklearn.feature_extraction(特征提取)、sklearn.feature_selection(特征选择)和sklearn.calibration(概率校准)。
📝 文本特征提取
1.CountVectorizer— 词频向量化 ⭐
fromsklearn.feature_extraction.textimportCountVectorizer vectorizer=CountVectorizer(input='content',# 'content','filename','file'encoding='utf-8',decode_error='strict',# 'strict','ignore','replace'strip_accents=None,# 'ascii','unicode',Nonelowercase=True,# 全部转为小写preprocessor=None,# 自定义预处理函数tokenizer=None,# 自定义分词函数stop_words=None,# 'english', list, Nonetoken_pattern=r'(?u)\b\w\w+\b',# 正则表达式ngram_range=(1,1),# (min_n, max_n)analyzer='word',# 'word','char','char_wb'max_df=1.0,# 文档频率上限(过滤高频词)min_df=1,# 文档频率下限(过滤低频词)max_features=None,# 最大词汇量vocabulary=None,# 预定义词汇表binary=False,# True=出现/不出现(非计数)dtype=np.int64)X=vectorizer.fit_transform(documents)# 关键属性print(vectorizer.vocabulary_)# 词→索引映射print(vectorizer.get_feature_names_out())# 特征名print(vectorizer.stop_words_)# 被去除的停用词print(vectorizer.fixed_vocabulary_)# 是否使用预定义词汇表# 查看词频term_freqs=X.sum(axis=0)# 每个词的总出现次数2.TfidfVectorizer— TF-IDF 向量化 ⭐
使用频率最高的文本向量化方法。
fromsklearn.feature_extraction.textimportTfidfVectorizer vectorizer=TfidfVectorizer(input='content',encoding='utf-8',lowercase=True,stop_words='english',ngram_range=(1,2),# uni-grams + bi-gramsmax_df=0.8,# 过滤出现在 80% 以上文档的词min_df=2,# 过滤出现少于 2 次的词max_features=5000,norm='l2',# 归一化: 'l1','l2',Noneuse_idf=True,# 是否使用 IDFsmooth_idf=True,# 平滑 IDF(防止除以 0)sublinear_tf=False,# 使用 1+log(tf)binary=False,vocabulary=None)X=vectorizer.fit_transform(documents)# 关键属性print(vectorizer.idf_)# IDF 向量print(vectorizer.vocabulary_)print(vectorizer.fixed_vocabulary_)3.TfidfTransformer— TF-IDF 变换器
将词频矩阵转换为 TF-IDF 矩阵。
fromsklearn.feature_extraction.textimportTfidfTransformer transformer=TfidfTransformer(norm='l2',use_idf=True,smooth_idf=True,sublinear_tf=False)X_tfidf=transformer.fit_transform(X_counts)print(transformer.idf_)CountVectorizer + TfidfTransformer = TfidfVectorizer(上面更简洁)
4.HashingVectorizer— 哈希向量化
使用特征哈希(Hashing Trick),无词汇表、内存高效。
fromsklearn.feature_extraction.textimportHashingVectorizer vectorizer=HashingVectorizer(n_features=2**20,# 哈希特征维度input='content',encoding='utf-8',lowercase=True,stop_words='english',ngram_range=(1,2),analyzer='word',norm='l2',alternate_sign=True,# 使用符号哈希binary=False,dtype=np.float64)X=vectorizer.fit_transform(documents)# 注意: 无 vocabulary_ 属性(不可逆)🖼️ 图像特征提取
fromsklearn.feature_extraction.imageimport(extract_patches_2d,# 提取 2D 图像块reconstruct_from_patches_2d,# 从块重建图像PatchExtractor,# 块提取器grid_to_graph,# 像素网格图img_to_graph,# 图像到图)fromsklearn.feature_extraction.imageimportextract_patches_2dimportnumpyasnp image=np.arange(16).reshape(4,4)# 提取所有 (2, 2) 的图像块patches=extract_patches_2d(image,patch_size=(2,2),max_patches=None,# None=所有, int=随机采样random_state=42)# patches.shape: (9, 2, 2) 对于 4x4 图像# 从块重建图像reconstructed=reconstruct_from_patches_2d(patches,image_size=(4,4))🗜️ 特征选择
1. 过滤法(Filter Methods)
VarianceThreshold— 方差阈值
fromsklearn.feature_selectionimportVarianceThreshold selector=VarianceThreshold(threshold=0.0)# 移除方差为 0 的特征X_selected=selector.fit_transform(X)print(selector.variances_)# 每个特征的方差print(selector.get_support())# 布尔掩码SelectKBest— 选最佳 K 个特征 ⭐
fromsklearn.feature_selectionimportSelectKBest,f_classif,chi2,mutual_info_classif# 分类: f_classif(F 检验), chi2(卡方), mutual_info_classif(互信息)selector=SelectKBest(score_func=f_classif,# 评分函数k=10# 保留的特征数)X_selected=selector.fit_transform(X,y)print(selector.scores_)# 每个特征的得分print(selector.pvalues_)# 每个特征的 p 值(部分函数)print(selector.get_support())# 被选中的特征# 回归对应的评分函数fromsklearn.feature_selectionimportf_regression,mutual_info_regression selector_reg=SelectKBest(score_func=f_regression,k=10)常用评分函数:
| 分类 | 回归 | 说明 |
|---|---|---|
f_classif | f_regression | F 检验 |
chi2 | — | 卡方检验(仅非负值) |
mutual_info_classif | mutual_info_regression | 互信息(捕获非线性) |
| — | r_regression | Pearson 相关系数 |
SelectPercentile— 按百分比选择
fromsklearn.feature_selectionimportSelectPercentile selector=SelectPercentile(score_func=f_classif,percentile=50# 保留前 50% 的特征)X_selected=selector.fit_transform(X,y)SelectFpr/SelectFdr/SelectFwe— 基于假设检验
fromsklearn.feature_selectionimportSelectFpr,SelectFdr,SelectFwe# 控制假阳性率selector=SelectFpr(score_func=f_classif,alpha=0.05)# 控制错误发现率selector=SelectFdr(score_func=f_classif,alpha=0.05)# 按家族错误率选择selector=SelectFwe(score_func=f_classif,alpha=0.05)2. 包装法(Wrapper Methods)
RFE— 递归特征消除 ⭐
fromsklearn.feature_selectionimportRFEfromsklearn.linear_modelimportLogisticRegression estimator=LogisticRegression(max_iter=1000)selector=RFE(estimator=estimator,n_features_to_select=10,# 或 float (0~1) 表示比例step=1,# 每次移除的特征数verbose=0,importance_getter='auto'# 'auto','coef_','feature_importances_')selector.fit(X,y)print(selector.support_)# 被选中特征的掩码print(selector.ranking_)# 特征的排名(1=最优)print(selector.n_features_)# 选中特征数print(selector.estimator_)# 训练好的最终估计器# 变换X_selected=selector.transform(X)RFECV— 带交叉验证的 RFE ⭐
fromsklearn.feature_selectionimportRFECVfromsklearn.svmimportSVC estimator=SVC(kernel='linear')selector=RFECV(estimator=estimator,step=1,min_features_to_select=1,cv=5,# 或 StratifiedKFold 等scoring='accuracy',verbose=0,n_jobs=-1,importance_getter='auto')selector.fit(X,y)print(selector.support_)print(selector.ranking_)print(selector.n_features_)# 最优特征数print(selector.cv_results_)# 各特征数的交叉验证结果print(selector.grid_scores_)# 已弃用,使用 cv_results_# 可视化importmatplotlib.pyplotasplt n_features=range(selector.min_features_to_select,len(selector.cv_results_['mean_test_score'])+1)plt.figure(figsize=(10,6))plt.errorbar(n_features,selector.cv_results_['mean_test_score'],yerr=selector.cv_results_['std_test_score'])plt.xlabel('Number of features')plt.ylabel('Cross-validation score')plt.title('RFECV: Optimal Number of Features')plt.axvline(selector.n_features_,color='r',linestyle='--',label=f'Optimal:{selector.n_features_}')plt.legend()plt.show()SequentialFeatureSelector— 顺序特征选择
fromsklearn.feature_selectionimportSequentialFeatureSelector selector=SequentialFeatureSelector(estimator=LogisticRegression(max_iter=1000),n_features_to_select=10,# 或 'auto'(用 tol 判断)tol=None,# 分数改善低于 tol 则停止direction='forward',# 'forward'(前向) 或 'backward'(后向)scoring='accuracy',cv=5,n_jobs=-1)selector.fit(X,y)print(selector.support_)print(selector.get_support())X_selected=selector.transform(X)3. 嵌入法(Embedded Methods)
SelectFromModel⭐
使用任何有coef_或feature_importances_属性的估计器选择特征。
fromsklearn.feature_selectionimportSelectFromModelfromsklearn.linear_modelimportLassoCVfromsklearn.ensembleimportRandomForestClassifier# 方式一: L1 正则化(Lasso)lasso=LassoCV(cv=5,random_state=42).fit(X,y)selector=SelectFromModel(estimator=lasso,threshold='median',# 或 'mean', '1.25*mean', floatprefit=True,# True=已拟合, False=先 fitnorm_order=1,# 系数范数max_features=None# 最大特征数)X_selected=selector.transform(X)# 方式二: 树模型特征重要性rf=RandomForestClassifier(n_estimators=100,random_state=42)selector=SelectFromModel(estimator=rf,threshold='0.5*mean',# 阈值为平均重要性的 0.5 倍prefit=False)X_selected=selector.fit_transform(X,y)# 属性print(selector.estimator_)# 训练好的估计器print(selector.threshold_)# 使用的阈值print(selector.get_support())# 选中的特征print(selector.max_features_)# 最大特征数📊 特征字典提取
DictVectorizer
将字典列表转换为特征矩阵(自动 One-Hot 编码类别值)。
fromsklearn.feature_extractionimportDictVectorizer data=[{'city':'Beijing','temp':25},{'city':'Shanghai','temp':28,'humidity':70},{'city':'Beijing','temp':22,'humidity':55}]vec=DictVectorizer(dtype=np.float64,separator='=',sparse=True)X=vec.fit_transform(data)# temp city=Beijing city=Shanghai humidity# 0 25.0 1.0 0.0 0.0# 1 28.0 0.0 1.0 70.0# 2 22.0 1.0 0.0 55.0print(vec.feature_names_)print(vec.vocabulary_)# 逆变换data_reconstructed=vec.inverse_transform(X)📝 特征特征(Feature Characterizer)
FeatureHasher— 特征哈希
fromsklearn.feature_extractionimportFeatureHasher hasher=FeatureHasher(n_features=2**10,# 输出特征维度input_type='dict',# 'dict','pair','string'dtype=np.float64,alternate_sign=True)X=hasher.fit_transform(feature_dicts)# 无 vocabulary_ — 不可逆🎯 概率校准
CalibratedClassifierCV— 概率校准 ⭐
让模型的概率估计更准确。
fromsklearn.calibrationimportCalibratedClassifierCVfromsklearn.svmimportSVC# 方法一: 包裹任意分类器base_model=SVC(probability=False)# 不一定要开启概率calibrated=CalibratedClassifierCV(estimator=base_model,method='sigmoid',# 'sigmoid'(Platt Scaling) 或 'isotonic'cv=5,# 'prefit' 或 int 或 cross-validatorn_jobs=None,ensemble=True# True=每个 fold 一个模型集成,False=单模型)calibrated.fit(X_train,y_train)y_prob=calibrated.predict_proba(X_test)y_pred=calibrated.predict(X_test)# 关键属性print(calibrated.calibrated_classifiers_)# 校准后的分类器列表print(calibrated.classes_)Platt Scaling vs Isotonic Regression:
| method | 适用场景 | 数据量 |
|---|---|---|
'sigmoid' | 默认,更稳定 | 较少数据也可 |
'isotonic' | 更灵活(非参数) | 需要更多数据(>1000) |
calibration_curve()— 校准曲线
fromsklearn.calibrationimportcalibration_curveimportmatplotlib.pyplotasplt prob_true,prob_pred=calibration_curve(y_true,y_prob,n_bins=10,strategy='uniform'# 'uniform' 或 'quantile')# 绘制plt.plot([0,1],[0,1],'k--',label='Perfectly calibrated')plt.plot(prob_pred,prob_true,'s-',label='Model')plt.xlabel('Mean predicted probability')plt.ylabel('Fraction of positives')plt.legend()plt.show()📝 完整特征工程 Pipeline 模板
fromsklearn.pipelineimportPipelinefromsklearn.composeimportColumnTransformerfromsklearn.preprocessingimportStandardScaler,OneHotEncoderfromsklearn.imputeimportSimpleImputerfromsklearn.feature_selectionimportSelectFromModelfromsklearn.ensembleimportRandomForestClassifier# 1. 预处理preprocessor=ColumnTransformer([('num',StandardScaler(),numerical_cols),('cat',OneHotEncoder(handle_unknown='ignore'),categorical_cols),])# 2. 特征选择feature_selector=SelectFromModel(RandomForestClassifier(n_estimators=100,random_state=42),threshold='median')# 3. 最终模型final_model=RandomForestClassifier(n_estimators=200,random_state=42)# 完整管道pipeline=Pipeline([('preprocessor',preprocessor),('feature_selection',feature_selector),('classifier',final_model)])pipeline.fit(X_train,y_train)print(f"Test accuracy:{pipeline.score(X_test,y_test):.3f}")print(f"Selected features:{pipeline.named_steps['feature_selection'].get_support().sum()}")[[sklearn-总览|← 返回总览]]