Python-sklearn-特征工程

Sklearn 特征工程

包含 sklearn.feature_extraction(特征提取)、sklearn.feature_selection(特征选择)和 sklearn.calibration(概率校准)。


📝 文本特征提取

1. CountVectorizer --- 词频向量化 ⭐

python 复制代码
from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer(
    input='content',             # 'content','filename','file'
    encoding='utf-8',
    decode_error='strict',       # 'strict','ignore','replace'
    strip_accents=None,          # 'ascii','unicode',None
    lowercase=True,              # 全部转为小写
    preprocessor=None,           # 自定义预处理函数
    tokenizer=None,              # 自定义分词函数
    stop_words=None,             # 'english', list, None
    token_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 向量化 ⭐

使用频率最高的文本向量化方法。

python 复制代码
from sklearn.feature_extraction.text import TfidfVectorizer

vectorizer = TfidfVectorizer(
    input='content',
    encoding='utf-8',
    lowercase=True,
    stop_words='english',
    ngram_range=(1, 2),          # uni-grams + bi-grams
    max_df=0.8,                  # 过滤出现在 80% 以上文档的词
    min_df=2,                    # 过滤出现少于 2 次的词
    max_features=5000,
    norm='l2',                   # 归一化: 'l1','l2',None
    use_idf=True,                # 是否使用 IDF
    smooth_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 矩阵。

python 复制代码
from sklearn.feature_extraction.text import TfidfTransformer

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),无词汇表、内存高效。

python 复制代码
from sklearn.feature_extraction.text import HashingVectorizer

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_ 属性(不可逆)

🖼️ 图像特征提取

python 复制代码
from sklearn.feature_extraction.image import (
    extract_patches_2d,       # 提取 2D 图像块
    reconstruct_from_patches_2d,  # 从块重建图像
    PatchExtractor,           # 块提取器
    grid_to_graph,            # 像素网格图
    img_to_graph,             # 图像到图
)

from sklearn.feature_extraction.image import extract_patches_2d
import numpy as np

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 --- 方差阈值
python 复制代码
from sklearn.feature_selection import VarianceThreshold

selector = VarianceThreshold(threshold=0.0)  # 移除方差为 0 的特征
X_selected = selector.fit_transform(X)

print(selector.variances_)      # 每个特征的方差
print(selector.get_support())   # 布尔掩码

SelectKBest --- 选最佳 K 个特征 ⭐
python 复制代码
from sklearn.feature_selection import SelectKBest, 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()) # 被选中的特征

# 回归对应的评分函数
from sklearn.feature_selection import f_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 --- 按百分比选择
python 复制代码
from sklearn.feature_selection import SelectPercentile

selector = SelectPercentile(
    score_func=f_classif,
    percentile=50             # 保留前 50% 的特征
)
X_selected = selector.fit_transform(X, y)

SelectFpr / SelectFdr / SelectFwe --- 基于假设检验
python 复制代码
from sklearn.feature_selection import SelectFpr, 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 --- 递归特征消除 ⭐
python 复制代码
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

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 ⭐
python 复制代码
from sklearn.feature_selection import RFECV
from sklearn.svm import SVC

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_

# 可视化
import matplotlib.pyplot as plt

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 --- 顺序特征选择
python 复制代码
from sklearn.feature_selection import SequentialFeatureSelector

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_ 属性的估计器选择特征。

python 复制代码
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LassoCV
from sklearn.ensemble import RandomForestClassifier

# 方式一: L1 正则化(Lasso)
lasso = LassoCV(cv=5, random_state=42).fit(X, y)
selector = SelectFromModel(
    estimator=lasso,
    threshold='median',     # 或 'mean', '1.25*mean', float
    prefit=True,            # True=已拟合, False=先 fit
    norm_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 编码类别值)。

python 复制代码
from sklearn.feature_extraction import DictVectorizer

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.0

print(vec.feature_names_)
print(vec.vocabulary_)

# 逆变换
data_reconstructed = vec.inverse_transform(X)

📝 特征特征(Feature Characterizer)

FeatureHasher --- 特征哈希

python 复制代码
from sklearn.feature_extraction import FeatureHasher

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 --- 概率校准 ⭐

让模型的概率估计更准确。

python 复制代码
from sklearn.calibration import CalibratedClassifierCV
from sklearn.svm import SVC

# 方法一: 包裹任意分类器
base_model = SVC(probability=False)  # 不一定要开启概率

calibrated = CalibratedClassifierCV(
    estimator=base_model,
    method='sigmoid',          # 'sigmoid'(Platt Scaling) 或 'isotonic'
    cv=5,                      # 'prefit' 或 int 或 cross-validator
    n_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() --- 校准曲线

python 复制代码
from sklearn.calibration import calibration_curve
import matplotlib.pyplot as plt

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 模板

python 复制代码
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestClassifier

# 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-总览\|← 返回总览\]

相关推荐
FlyWIHTSKY1 小时前
什么是ai智能体,智能体都有哪些部分组成,有那些实现框架
人工智能
mit6.8241 小时前
archived
后端·python·flask
船长@1 小时前
FastAPI 快速上手:从零基础到实操入门
python·ai·fastapi
环球科讯1 小时前
金融赋能焕新居——建行广东江门分行启动家装补贴季助力消费升温
大数据·人工智能·物联网
手写码匠1 小时前
华为云Flexus+DeepSeek征文|Agent 评测体系实战:用 DeepSeek-R1 当裁判,打造 Dify Agent 的自动化回归测试流水线
人工智能·深度学习·算法·aigc
用户298698530141 小时前
效率工具分享:3 款免费 Markdown 转 Word 在线转换器
人工智能·后端
吴声子夜歌1 小时前
正则指引——PHP
开发语言·正则表达式·php
河南博为智能科技有限公司1 小时前
配电站房智能辅控一体化监控方案——基于壁挂式边缘计算网关,实现无人值守!
人工智能·边缘计算
2601_962860152 小时前
智慧城市企业 2027 排期:LEAP East 香港站同时验证亚太与沙特需求
人工智能·智慧城市