本文目录导读:

我来介绍使用Scikit-learn进行特征提取的几种常用方法,包括具体的代码案例。
文本特征提取
1 词袋模型(Bag of Words)
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
# 示例文本数据
documents = [
"我喜欢机器学习",
"机器学习很有趣",
"Python是最好的编程语言",
"我喜欢用Python做数据分析"
]
# 创建词袋模型
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(documents)
# 查看特征名称
print("特征词列表:")
print(vectorizer.get_feature_names_out())
print("\n特征矩阵:")
print(X.toarray())
# 打印可读的表格
print("\n特征矩阵(可读版):")
print(f"{'文档':<40}", end="")
for word in vectorizer.get_feature_names_out():
print(f"{word:<10}", end="")
print()
for i, doc in enumerate(documents):
print(f"{doc[:38]:<40}", end="")
for val in X[i].toarray()[0]:
print(f"{str(val):<10}", end="")
print()
2 TF-IDF特征提取
from sklearn.feature_extraction.text import TfidfVectorizer
# 示例文本数据
documents = [
"机器学习深度学习自然语言处理",
"机器学习图像识别计算机视觉",
"Python数据分析数据可视化",
"深度学习自然语言处理机器翻译"
]
# 创建TF-IDF向量化器
tfidf_vectorizer = TfidfVectorizer()
X_tfidf = tfidf_vectorizer.fit_transform(documents)
# 查看结果
print("TF-IDF特征名称:")
print(tfidf_vectorizer.get_feature_names_out())
print("\nTF-IDF特征矩阵:")
print(X_tfidf.toarray())
# 显示每个文档中最重要的词汇
feature_names = tfidf_vectorizer.get_feature_names_out()
for i, doc in enumerate(documents):
tfidf_scores = X_tfidf[i].toarray()[0]
top_indices = tfidf_scores.argsort()[-3:][::-1]
top_features = [feature_names[idx] for idx in top_indices]
print(f"\n文档{i+1}最重要的3个特征: {top_features}")
图像特征提取
1 HOG特征提取
from skimage import data, feature, color
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
import numpy as np
# 加载示例图像
image = data.astronaut()
# 转换为灰度图像
gray_image = color.rgb2gray(image)
# 提取HOG特征
hog_features, hog_image = feature.hog(
gray_image,
orientations=9,
pixels_per_cell=(8, 8),
cells_per_block=(2, 2),
visualize=True,
block_norm='L2-Hys'
)
print(f"HOG特征向量维度: {hog_features.shape}")
print(f"HOG特征向量前10个值: {hog_features[:10]}")
# 可视化
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
ax1.imshow(gray_image, cmap='gray')
ax1.set_title('原始灰度图像')
ax2.imshow(hog_image, cmap='gray')
ax2.set_title('HOG特征图像')
plt.show()
# 特征标准化
scaler = StandardScaler()
hog_features_scaled = scaler.fit_transform(hog_features.reshape(-1, 1)).flatten()
print(f"\n标准化后的HOG特征前10个值: {hog_features_scaled[:10]}")
2 使用简单的颜色直方图特征
from skimage import io, color
import numpy as np
def extract_color_histogram(image, bins=32):
"""
提取颜色直方图特征
"""
# 将图像分割为RGB通道
hist_features = []
for channel in range(3):
hist = np.histogram(image[:, :, channel], bins=bins, range=(0, 256))[0]
hist_features.extend(hist)
return np.array(hist_features)
# 使用示例
from skimage import data
# 加载图像
image = data.astronaut()
# 提取颜色直方图特征
color_hist = extract_color_histogram(image, bins=16)
print(f"颜色直方图特征维度: {color_hist.shape}")
print(f"颜色直方图特征前10个值: {color_hist[:10]}")
数值特征提取与选择
1 PCA特征提取
from sklearn.decomposition import PCA
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
# 加载手写数字数据集
digits = load_digits()
X, y = digits.data, digits.target
print(f"原始特征维度: {X.shape[1]}")
# 应用PCA进行特征提取
pca = PCA(n_components=0.95) # 保留95%的方差
X_pca = pca.fit_transform(X)
print(f"PCA降维后的特征维度: {X_pca.shape[1]}")
print(f"各主成分解释的方差比例: {pca.explained_variance_ratio_[:5]}")
# 比较PCA前后的分类效果
# 原始数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
svm = SVC(kernel='rbf', random_state=42)
svm.fit(X_train, y_train)
y_pred_original = svm.predict(X_test)
print(f"\n原始数据分类准确率: {accuracy_score(y_test, y_pred_original):.3f}")
# PCA降维后
X_train_pca, X_test_pca, y_train, y_test = train_test_split(X_pca, y, test_size=0.2, random_state=42)
svm_pca = SVC(kernel='rbf', random_state=42)
svm_pca.fit(X_train_pca, y_train)
y_pred_pca = svm_pca.predict(X_test_pca)
print(f"PCA降维后分类准确率: {accuracy_score(y_test, y_pred_pca):.3f}")
2 特征选择方法
from sklearn.feature_selection import SelectKBest, chi2, f_classif, mutual_info_classif
from sklearn.datasets import load_iris
import pandas as pd
# 加载鸢尾花数据集
iris = load_iris()
X, y = iris.data, iris.target
feature_names = iris.feature_names
print("原始特征:", feature_names)
# 方法1:卡方检验特征选择
chi2_selector = SelectKBest(chi2, k=2)
X_chi2 = chi2_selector.fit_transform(X, y)
chi2_indices = chi2_selector.get_support(indices=True)
print(f"\n卡方检验选择的特征: {[feature_names[i] for i in chi2_indices]}")
# 方法2:ANOVA F值特征选择
f_selector = SelectKBest(f_classif, k=2)
X_f = f_selector.fit_transform(X, y)
f_indices = f_selector.get_support(indices=True)
print(f"ANOVA F值选择的特征: {[feature_names[i] for i in f_indices]}")
# 方法3:互信息特征选择
mi_selector = SelectKBest(mutual_info_classif, k=2)
X_mi = mi_selector.fit_transform(X, y)
mi_indices = mi_selector.get_support(indices=True)
print(f"互信息选择的特征: {[feature_names[i] for i in mi_indices]}")
# 显示特征重要性评分
print("\n特征重要性评分:")
for i, name in enumerate(feature_names):
chi2_score = chi2_selector.scores_[i]
f_score = f_selector.scores_[i]
mi_score = mi_selector.scores_[i]
print(f"{name:15s}: 卡方={chi2_score:6.2f}, F值={f_score:6.2f}, 互信息={mi_score:6.2f}")
完整案例:文本分类特征提取流程
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_selection import SelectPercentile, chi2
from sklearn.decomposition import TruncatedSVD
from sklearn.pipeline import Pipeline
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import cross_val_score
import numpy as np
# 准备数据
documents = [
"机器学习深度学习技术发展迅速",
"Python编程数据分析可视化",
"自然语言处理文本分类任务",
"计算机视觉图像识别应用",
"数据挖掘统计分析机器学习",
"深度学习神经网络Transformer模型",
"Python是数据分析的首选语言",
"文本分类是NLP的基本任务"
]
labels = [0, 1, 2, 3, 0, 0, 1, 2] # 0:ML, 1:Python, 2:NLP, 3:CV
# 创建特征提取和分类的Pipeline
pipeline = Pipeline([
('tfidf', TfidfVectorizer(max_features=100, ngram_range=(1, 2))),
('feature_selection', SelectPercentile(chi2, percentile=50)),
('svd', TruncatedSVD(n_components=5, random_state=42)),
('classifier', MultinomialNB())
])
# 交叉验证评估
scores = cross_val_score(pipeline, documents, labels, cv=3, scoring='accuracy')
print(f"交叉验证得分: {scores}")
print(f"平均得分: {scores.mean():.3f} (+/- {scores.std() * 2:.3f})")
# 查看Pipeline各步骤的效果
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(documents, labels, test_size=0.3, random_state=42)
# 提取中间特征
tfidf = TfidfVectorizer(max_features=100, ngram_range=(1, 2))
X_tfidf = tfidf.fit_transform(X_train)
print(f"\nTF-IDF特征矩阵形状: {X_tfidf.shape}")
print(f"词汇表大小: {len(tfidf.get_feature_names_out())}")
# 特征选择后
selector = SelectPercentile(chi2, percentile=50)
X_selected = selector.fit_transform(X_tfidf, y_train)
print(f"特征选择后形状: {X_selected.shape}")
# SVD降维后
svd = TruncatedSVD(n_components=5, random_state=42)
X_svd = svd.fit_transform(X_selected)
print(f"SVD降维后形状: {X_svd.shape}")
print(f"SVD各组分解释方差比例: {svd.explained_variance_ratio_}")
高级技巧:特征组合
from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.pipeline import FeatureUnion
from sklearn.base import BaseEstimator, TransformerMixin
import numpy as np
# 自定义特征提取器
class CustomFeatureExtractor(BaseEstimator, TransformerMixin):
def __init__(self, include_mean=True, include_std=True):
self.include_mean = include_mean
self.include_std = include_std
def fit(self, X, y=None):
return self
def transform(self, X):
n_samples, n_features = X.shape
features = []
if self.include_mean:
features.append(X.mean(axis=1).reshape(-1, 1))
if self.include_std:
features.append(X.std(axis=1).reshape(-1, 1))
return np.hstack(features)
# 创建特征组合pipeline
feature_union = FeatureUnion([
('original', 'passthrough'),
('poly', PolynomialFeatures(degree=2, include_bias=False)),
('custom', CustomFeatureExtractor())
])
# 示例数据
X_sample = np.random.randn(100, 5)
# 应用特征组合
X_combined = feature_union.fit_transform(X_sample)
print(f"原始特征数: {X_sample.shape[1]}")
print(f"组合后特征数: {X_combined.shape[1]}")
print(f"新特征维度: {X_combined.shape}")
这些案例涵盖了Scikit-learn中常用的特征提取方法,包括:
- 文本特征:词袋模型、TF-IDF
- 图像特征:HOG特征、颜色直方图
- 数值特征:PCA降维、特征选择、特征组合
- 完整Pipeline:链式处理流程
根据你的具体应用场景选择合适的方法,通常需要结合特征工程和模型调优来获得最佳结果。