哈喽,我是小白~
今儿和大家分享的是特征选择方法!
特征选择可以降低模型复杂度,通过减少无关或冗余特征来提高模型的泛化能力,减少过拟合风险。能减少模型的训练时间和计算资源,同时提高模型的可解释性,使得特征对结果的影响更加清晰。正确的特征选择能够提升模型的预测性能,聚焦于对目标变量最相关的特征,增强模型的准确性和稳定性。
本篇文章给大家总结的十个特征选择方法有:
方差阈值法 相关系数法 单变量特征选择 L1正则化 嵌入法 顺序特征选择 相关系数法 主成分分析 互信息法 顺序特征选择
如果需要本文PDF版本的同学,文末获取~
另外,文末有总结性的干货~
一起来看下具体细化内容~
1. 方差阈值法
方差阈值法是一种简单的特征选择方法,通过移除方差低于某一阈值的特征,来减少特征数目。
原理
特征的方差小表示其在数据集中变化小,对模型的贡献可能较小,因此可以移除。
核心公式
其中, 是特征 , 是样本数, 是特征 的均值。
计算每个特征的方差,并与预设的阈值比较,方差小于阈值的特征将被移除。
Python案例
特征选择中的方差阈值法适用于过滤掉方差较低的特征,以减少数据中的噪声或不相关的特征。
我们生成一个带有一些高方差和低方差特征的示例数据集,然后应用方差阈值法进行特征选择。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.feature_selection import VarianceThreshold
# 生成示例数据
np.random.seed(0)
n_samples = 1000
n_features = 5
# 高方差特征
high_variance_data = np.random.normal(loc=0, scale=5, size=(n_samples, 2))
# 低方差特征
low_variance_data = np.random.normal(loc=0, scale=0.5, size=(n_samples, 3))
# 合并数据集
data = np.hstack((high_variance_data, low_variance_data))
# 添加噪声特征
noise = np.random.normal(loc=0, scale=0.1, size=(n_samples, 1))
data_with_noise = np.hstack((data, noise))
# 转换为DataFrame
columns = ['feat1', 'feat2', 'feat3', 'feat4', 'feat5', 'noise']
df = pd.DataFrame(data_with_noise, columns=columns)
# 方差阈值法选择特征
threshold = 0.1 # 设定方差阈值
selector = VarianceThreshold(threshold=threshold)
selected_features = selector.fit_transform(df)
# 打印选择的特征
selected_columns = df.columns[selector.get_support()]
print("选择的特征:", selected_columns)
# 画出数据分析图形
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
# 盒图展示各特征的分布
df.boxplot(ax=ax1)
ax1.set_title('Boxplot of Features')
# 相关性矩阵展示
corr_matrix = df.corr()
im = ax2.matshow(corr_matrix, cmap='coolwarm')
fig.colorbar(im, ax=ax2)
ax2.set_xticklabels([''] + list(df.columns))
ax2.set_yticklabels([''] + list(df.columns))
ax2.set_title('Correlation Matrix')
plt.tight_layout()
plt.show()
数据生成:
使用 numpy.random.normal
生成两组特征数据,一组具有较高的方差,另一组具有较低的方差,以及一些噪声特征。
特征选择:
使用 VarianceThreshold
类来选择方差大于设定阈值的特征。在这个例子中,阈值设定为0.1。
数据分析图形:
盒图 ( Boxplot
):展示了每个特征的数据分布情况,帮助观察特征之间的方差差异。相关性矩阵:展示了特征之间的相关性,利用颜色编码显示相关性的强度。
2. 相关系数法
相关系数法用来衡量特征与目标变量之间的线性关系。该方法适用于数值型特征与目标变量的关系分析。相关系数法通常用于特征筛选的早期阶段,以过滤掉与目标变量相关性较低的特征。
原理
相关系数(如皮尔逊相关系数)度量的是两个变量之间的线性相关性。值的范围从 -1 到 1,分别表示完全负相关和完全正相关,0 则表示无线性相关性。
核心公式
皮尔逊相关系数:
其中, 和 分别是特征 和目标变量 的样本值, 和 是它们的均值。
推导:
1. 计算均值:
首先,计算特征和目标变量的均值。
2. 协方差计算:
计算特征和目标变量之间的协方差。
3. 标准差计算:
计算特征 和目标变量 的标准差。
4. 相关系数计算:
最后,通过协方差和标准差的比值计算相关系数。选择相关系数较大的特征。
Python实现
生成一个包含多个特征的数据集,然后计算每个特征与目标变量的相关系数。
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import make_regression
from scipy.stats import pearsonr
# 设置随机种子以确保结果可复现
np.random.seed(42)
# 生成虚拟数据集
n_samples = 100
n_features = 6
# 创建一个具有相关性的回归数据集
X, y = make_regression(n_samples=n_samples, n_features=n_features, noise=0.1)
# 将数据集转换为DataFrame以便于处理
columns = [f'Feature_{i+1}' for i in range(n_features)]
df = pd.DataFrame(X, columns=columns)
df['Target'] = y
# 计算每个特征与目标变量的相关系数
correlations = {}
for col in columns:
corr, _ = pearsonr(df[col], df['Target'])
correlations[col] = corr
# 将相关系数结果转换为DataFrame
corr_df = pd.DataFrame.from_dict(correlations, orient='index', columns=['Correlation'])
# 绘制图形
plt.figure(figsize=(16, 10))
# 图1:相关系数矩阵的热图
plt.subplot(2, 1, 1)
corr_matrix = df.corr()
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1, linewidths=0.5)
plt.title('Correlation Matrix Heatmap', fontsize=16)
# 图2:特征与目标变量的散点图
plt.subplot(2, 1, 2)
colors = sns.color_palette('husl', n_features)
for i, col in enumerate(columns):
plt.scatter(df[col], df['Target'], color=colors[i], alpha=0.7, label=f'{col} (Corr: {correlations[col]:.2f})')
plt.xlabel('Feature Value', fontsize=12)
plt.ylabel('Target Value', fontsize=12)
plt.title('Scatter Plot of Features vs. Target', fontsize=16)
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
生成虚拟数据集:我们使用 make_regression
函数生成一个线性回归数据集,其中包含 100 个样本和 6 个特征。计算相关系数:使用 pearsonr
函数计算每个特征与目标变量之间的皮尔逊相关系数,并将结果存储在字典correlations
中。
图1:相关系数矩阵的热图展示了特征之间以及特征与目标变量之间的相关性。我们使用了 seaborn
库的heatmap
函数来实现,并选择了鲜艳的coolwarm
配色方案。图2:特征与目标变量的散点图展示了每个特征与目标变量之间的关系。通过为每个特征分配不同的颜色,使得图形更具可视化效果。
3. 单变量特征选择
单变量特征选择通过对每个特征单独进行统计测试,选择与目标变量显著相关的特征。
原理
使用统计检验(如卡方检验、F检验等)评估每个特征与目标变量的关系。
核心公式
以卡方检验为例:
其中, 是观察值, 是期望值。
通过卡方检验公式计算每个特征的卡方值,并与临界值比较,选择卡方值较大的特征。
Python案例
使用 scikit-learn
库中的 SelectKBest
进行特征选择,并使用 matplotlib
和 seaborn
库进行数据可视化。具体的案例是对鸢尾花数据集(Iris dataset)进行特征选择。
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest, f_classif
import pandas as pd
# 加载数据集
iris = load_iris()
X, y = iris.data, iris.target
feature_names = iris.feature_names
# 使用SelectKBest进行单变量特征选择
selector = SelectKBest(score_func=f_classif, k=2)
X_new = selector.fit_transform(X, y)
# 获取选择的特征的索引
selected_indices = selector.get_support(indices=True)
selected_features = [feature_names[i] for i in selected_indices]
# 将数据转换为DataFrame以便于可视化
df = pd.DataFrame(X, columns=feature_names)
df_selected = df.iloc[:, selected_indices]
df_selected['target'] = y
# 可视化1: 选择特征的盒须图(Boxplot)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.boxplot(x='target', y=selected_features[0], data=df_selected)
plt.title(f'Boxplot of {selected_features[0]} by Target')
plt.subplot(1, 2, 2)
sns.boxplot(x='target', y=selected_features[1], data=df_selected)
plt.title(f'Boxplot of {selected_features[1]} by Target')
plt.tight_layout()
plt.show()
# 可视化2: 选择特征的散点图(Scatter plot)
plt.figure(figsize=(10, 6))
sns.scatterplot(x=selected_features[0], y=selected_features[1], hue='target', palette='Set1', data=df_selected)
plt.title(f'Scatter Plot of {selected_features[0]} vs {selected_features[1]}')
plt.xlabel(selected_features[0])
plt.ylabel(selected_features[1])
plt.show()
# 可视化3: 选择特征的联合分布图(Joint plot)
sns.jointplot(x=selected_features[0], y=selected_features[1], hue='target', palette='Set1', data=df_selected)
plt.show()
加载数据集:首先加载鸢尾花数据集,并将特征矩阵 X
和目标变量y
分离。特征选择:使用 SelectKBest
和f_classif
评分函数选择前两个最佳特征。数据准备:将选择后的特征和目标变量组合成一个 DataFrame 以便于可视化。 可视化
盒须图:展示选择特征在不同类别下的分布情况。 散点图:展示选择特征之间的关系,并用不同颜色区分目标类别。 联合分布图:展示选择特征之间的联合分布,并用不同颜色区分目标类别。
4. L1正则化
Lasso回归是一种线性回归模型,通过在损失函数中加入L1正则化项,促使一些回归系数变为零,从而实现特征选择。Lasso的稀疏性特性使其在处理高维数据时特别有效。
原理
L1正则化会对回归系数施加一个稀疏性约束,使得部分系数被压缩为零。这意味着模型只会使用部分特征,从而实现特征选择的效果。
核心公式
其中, 是正则化强度, 是特征 的回归系数。
推导:
1. 最小化损失函数:目标是找到一组回归系数 ,使得损失函数最小化。
2. L1正则化引入:通过引入L1正则化项 ,在回归过程中自动选择特征。
3. 梯度下降法:通常使用梯度下降法进行优化。由于L1正则化的非光滑性,可以通过次梯度法或坐标下降法求解。
4. 特征选择:随着的增加,更多的将被压缩为零,从而选择出对模型贡献最大的特征。
Python实现
代码中生成一个包含不同特征的重要性图和模型系数的图,以及实际与预测值的比较图。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_regression
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# 生成虚拟数据集
np.random.seed(0)
X, y = make_regression(n_samples=1000, n_features=10, noise=0.1, random_state=0)
# 添加一些无关特征
X = np.hstack([X, np.random.randn(X.shape[0], 5)])
# 拆分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
# 设置Lasso回归模型
alphas = [0.01, 0.1, 1, 10, 100]
coefs = []
mse_train = []
mse_test = []
# 训练Lasso回归模型并记录系数和均方误差
for alpha in alphas:
model = Lasso(alpha=alpha, max_iter=10000)
model.fit(X_train, y_train)
coefs.append(model.coef_)
y_train_pred = model.predict(X_train)
y_test_pred = model.predict(X_test)
mse_train.append(mean_squared_error(y_train, y_train_pred))
mse_test.append(mean_squared_error(y_test, y_test_pred))
# 绘制结果图
plt.figure(figsize=(14, 7))
# 系数图
plt.subplot(1, 2, 1)
for i in range(len(alphas)):
plt.plot(coefs[i], label=f'Alpha={alphas[i]}', marker='o')
plt.xlabel('Feature Index')
plt.ylabel('Coefficient Value')
plt.title('Lasso Coefficients vs. Feature Index')
plt.legend()
plt.grid(True)
# 均方误差图
plt.subplot(1, 2, 2)
plt.plot(alphas, mse_train, label='Train MSE', marker='o', color='blue')
plt.plot(alphas, mse_test, label='Test MSE', marker='o', color='red')
plt.xscale('log')
plt.xlabel('Alpha (Regularization Strength)')
plt.ylabel('Mean Squared Error')
plt.title('MSE vs. Alpha')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
1. 数据生成:make_regression
生成虚拟回归数据,并添加一些无关特征。
2. 数据拆分:将数据集分为训练集和测试集。
3. 模型训练:对于不同的正则化强度(alpha
),训练Lasso回归模型,并记录系数和均方误差(MSE)。
系数图:展示了随着正则化强度增加,不同特征的系数如何变化。可以看到,正则化强度越大,很多特征的系数趋近于零。 均方误差图:展示了正则化强度对训练和测试均方误差的影响,帮助理解正则化对模型性能的影响。
5. 嵌入法
嵌入法在模型训练过程中自动选择特征,如 Lasso 回归和基于决策树的模型。
原理
嵌入法将特征选择嵌入到模型训练过程中,通过正则化或特征重要性分数来选择特征。
嵌入法依赖于具体的模型,如 Lasso 回归和树模型的特征重要性分数。
与 Lasso 回归和基于树模型的特征选择方法类似,嵌入法通过模型训练过程中的特征权重或重要性分数来选择特征。
Python案例
嵌入法(Embedded Method)是特征选择的一种方法,它通过在模型训练的过程中自动选择特征。一个常见的案例是使用逻辑回归模型来进行特征选择。下面我将演示一个嵌入法特征选择的案例,使用逻辑回归模型,并画出一些数据分析的图形。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.feature_selection import SelectFromModel
from sklearn.preprocessing import StandardScaler
# 加载乳腺癌数据集
data = load_breast_cancer()
X = data.data
y = data.target
# 将数据集分割为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 数据标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 初始化逻辑回归模型
model = LogisticRegression(max_iter=10000)
# 使用SelectFromModel来进行特征选择
sfm = SelectFromModel(estimator=model, threshold=None)
sfm.fit(X_train_scaled, y_train)
# 获取选择的特征
selected_features = np.array(data.feature_names)[sfm.get_support()]
# 打印选择的特征
print("Selected features:", selected_features)
# 绘制一个柱状图展示特征的重要性
plt.figure(figsize=(10, 6))
plt.bar(selected_features, np.abs(sfm.estimator_.coef_[0][sfm.get_support()]))
plt.xlabel('Feature')
plt.ylabel('Coefficient Magnitude')
plt.title('Coefficient Magnitude of Selected Features in Logistic Regression')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()
加载乳腺癌数据集,并进行数据预处理(标准化)。 使用逻辑回归模型并结合SelectFromModel进行特征选择。 绘制了特征系数的柱状图,展示了每个特征在逻辑回归模型中的重要性。 绘制了ROC曲线,评估模型的预测性能。
图形展示了嵌入法特征选择的过程中,模型如何自动选择特征,并且展示了选择的特征在模型中的重要性和模型预测性能的评估。
6. 顺序特征选择
顺序特征选择是一种贪心算法,逐步添加(前向选择)或删除(后向选择)特征,通过评估模型性能来找到性能最佳的特征子集。
原理
顺序特征选择通过不断地构建特征子集并评估其在模型中的表现,逐步构建起一个包含最优特征组合的子集。前向选择从空集开始逐步添加特征,而后向选择则从全特征集开始逐步移除特征。
核心公式
顺序特征选择不依赖于具体的数学公式,而是基于模型的性能度量(如准确性、AUC、F1分数等)来评价特征子集的优劣。
推导:
1. 初始化:
前向选择:从空特征集开始。 后向选择:从包含所有特征的集合开始。
2. 特征添加或删除:
前向选择:每轮选择一个
对模型性能提升最大的特征加入当前特征集。
后向选择:每轮移除一个对模型性能影响最小的特征。
3. 模型评估:每次特征添加或删除后,训练模型并评估其性能。
4. 终止条件:当模型性能不再显著提高或达到预设的特征数量时,终止特征选择。
Python实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.metrics import accuracy_score
# 生成虚拟数据集
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=2, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 定义分类模型
model = LogisticRegression()
# 顺序特征选择(向前选择)
selector_forward = SequentialFeatureSelector(model, n_features_to_select='auto', direction='forward', cv=5)
selector_forward.fit(X_train, y_train)
selected_features_forward = selector_forward.get_support()
# 顺序特征选择(向后选择)
selector_backward = SequentialFeatureSelector(model, n_features_to_select='auto', direction='backward', cv=5)
selector_backward.fit(X_train, y_train)
selected_features_backward = selector_backward.get_support()
# 训练并评估模型
model.fit(selector_forward.transform(X_train), y_train)
y_pred_forward = model.predict(selector_forward.transform(X_test))
accuracy_forward = accuracy_score(y_test, y_pred_forward)
model.fit(selector_backward.transform(X_train), y_train)
y_pred_backward = model.predict(selector_backward.transform(X_test))
accuracy_backward = accuracy_score(y_test, y_pred_backward)
# 绘图
plt.figure(figsize=(14, 6))
# 绘制特征选择过程中的特征重要性
plt.subplot(1, 2, 1)
plt.title('Feature Selection Process')
plt.bar(range(X.shape[1]), np.mean(X_train, axis=0), color='skyblue', label='Feature Importance')
plt.xticks(range(X.shape[1]), [f'Feature {i}' for i in range(X.shape[1])], rotation=90)
plt.ylabel('Feature Importance')
plt.legend()
# 绘制特征选择后的结果
plt.subplot(1, 2, 2)
plt.title('Feature Selection Results')
plt.plot(np.arange(1, len(selected_features_forward) + 1), [accuracy_forward] * len(selected_features_forward), 'o-', color='red', label='Forward Selection Accuracy')
plt.plot(np.arange(1, len(selected_features_backward) + 1), [accuracy_backward] * len(selected_features_backward), 'o-', color='blue', label='Backward Selection Accuracy')
plt.xlabel('Number of Selected Features')
plt.ylabel('Accuracy')
plt.legend()
plt.tight_layout()
plt.show()
1. 数据生成:使用make_classification
生成一个虚拟的数据集,具有10个特征,其中5个是信息性的,2个是冗余的。
2. 数据分割:将数据分割为训练集和测试集。
3. 模型定义:使用逻辑回归作为分类模型。
4. 特征选择:使用SequentialFeatureSelector
进行向前选择和向后选择,并获取所选择的特征。
5. 模型训练与评估:训练模型并计算每种选择方法的准确率。
特征选择过程:显示每个特征的相对重要性(此处简化为特征的均值)。 特征选择结果:显示选择不同数量特征后的模型准确率。
7. 相关系数法
通过计算特征与目标变量之间的相关系数,选择高相关性的特征。
原理
相关系数衡量两个变量之间的线性关系,值越大表示关系越强。
核心公式
皮尔逊相关系数公式为:
其中, 是 和 的协方差, 和 分别是 和 的标准差。
计算特征 和目标变量 的协方差。 计算特征 和目标变量 的标准差。 计算相关系数 并排序,选择相关系数较高的特征。
Python案例
使用一个模拟的数据集,其中包括多个特征和一个目标变量。我们将计算每个特征与目标变量之间的皮尔逊相关系数,并选择相关性较高的特征进行进一步分析。最后,我们将绘制相关系数的热图和散点图矩阵来可视化结果。
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import make_regression
# 生成模拟数据
np.random.seed(0)
X, y = make_regression(n_samples=100, n_features=10, noise=0.1)
feature_names = [f'feature_{i}' for i in range(X.shape[1])]
data = pd.DataFrame(X, columns=feature_names)
data['target'] = y
# 计算相关系数矩阵
correlation_matrix = data.corr()
# 选择与目标变量相关性较高的特征(绝对值大于0.5)
selected_features = correlation_matrix['target'].apply(lambda x: abs(x)).sort_values(ascending=False)
selected_features = selected_features[selected_features > 0.5]
selected_feature_names = selected_features.index.drop('target')
# 绘制相关系数热图
plt.figure(figsize=(12, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('Correlation Matrix Heatmap')
plt.show()
# 绘制散点图矩阵
sns.pairplot(data[selected_feature_names.to_list() + ['target']])
plt.suptitle('Pairplot of Selected Features and Target', y=1.02)
plt.show()
# 显示相关系数
print("Selected Features and Their Correlation with Target:")
print(selected_features)
数据生成:
使用 make_regression
函数生成包含100个样本和10个特征的回归数据集,并添加少量噪声。
相关系数计算:
将数据转换为 DataFrame
格式,并计算特征与目标变量之间的相关系数矩阵。
特征选择:
选择与目标变量相关性绝对值大于0.5的特征。
数据可视化:
绘制相关系数热图,显示所有特征与目标变量之间的相关性。 绘制选定特征与目标变量的散点图矩阵,显示特征之间以及与目标变量之间的关系。
可以清楚地看到哪些特征与目标变量之间具有较强的线性关系,并进一步分析这些特征之间的相互关系。相关系数热图和散点图矩阵可以帮助我们直观地理解数据的结构和特征的重要性。
8. 主成分分析
PCA 是一种常用的降维技术,通过线性变换将高维数据映射到低维空间,生成若干个互相正交的主成分。这些主成分解释了原始数据的主要方差。PCA 可以用来选择解释方差最大的几个主成分作为特征,从而实现特征选择。
原理
PCA 通过对协方差矩阵进行特征值分解,将原始数据投影到由特征向量定义的新坐标系中。特征值较大的方向代表数据的主要变化方向,因此这些方向对应的主成分被优先选择。
核心公式
其中, 是特征协方差矩阵, 是第 个样本的特征向量, 是特征均值向量。
推导:
1. 计算特征均值向量:
首先,计算所有样本特征的均值向量。
2. 计算协方差矩阵:
计算样本数据的协方差矩阵。
3. 特征值分解:
对协方差矩阵进行特征值分解,得到特征向量矩阵 和对角矩阵 (特征值矩阵)。
4. 排序和选择主成分:
根据特征值的大小对特征向量进行排序,并选择前k个特征值最大的主成分。
5. 映射到新空间:
将原始数据映射到由选定主成分定义的低维空间,得到降维后的特征集。
Python实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import make_blobs
# 生成虚拟数据集
n_samples = 1000
n_features = 5
n_classes = 3
X, y = make_blobs(n_samples=n_samples, n_features=n_features, centers=n_classes, cluster_std=1.0, random_state=42)
# 创建PCA对象
pca = PCA(n_components=2)
# 进行PCA降维
X_pca = pca.fit_transform(X)
# 画出原始数据散点图
plt.figure(figsize=(12, 8))
# 原始数据散点图
plt.subplot(2, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis', edgecolor='k', s=50)
plt.title('Original Data Scatter Plot')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
# 降维后的数据散点图
plt.subplot(2, 2, 2)
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='viridis', edgecolor='k', s=50)
plt.title('PCA Reduced Data Scatter Plot')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
# PCA主成分载荷图
plt.subplot(2, 2, 3)
components = pca.components_.T
plt.bar(range(components.shape[0]), components[:, 0], color='red', alpha=0.6, label='PC1')
plt.bar(range(components.shape[0]), components[:, 1], color='blue', alpha=0.6, label='PC2')
plt.xticks(range(components.shape[0]), [f'Feature {i+1}' for i in range(components.shape[0])])
plt.title('PCA Component Loadings')
plt.xlabel('Features')
plt.ylabel('Loading')
plt.legend()
# PCA主成分解释方差比例图
plt.subplot(2, 2, 4)
explained_variance_ratio = pca.explained_variance_ratio_
plt.bar(range(len(explained_variance_ratio)), explained_variance_ratio, color='orange', alpha=0.8)
plt.title('Explained Variance Ratio of PCA Components')
plt.xlabel('Principal Components')
plt.ylabel('Explained Variance Ratio')
plt.tight_layout()
plt.show()
1. 原始数据散点图:显示了数据集的前两个特征的散点图,颜色根据不同的类别标记。
2. PCA降维后的数据散点图:显示了经过PCA降维后的数据在前两个主成分上的散点图,颜色与类别相同。
3. PCA主成分载荷图:展示了前两个主成分的载荷(即每个原始特征对主成分的贡献)。
4. PCA主成分解释方差比例图:展示了每个主成分解释的方差比例,显示主成分的重要性。
9. 互信息法
通过计算特征与目标变量的互信息来选择重要特征。
原理
互信息衡量两个变量之间的依赖关系。
核心公式
互信息公式为:
其中, 是 和 的联合概率分布, 和 分别是 和 的边缘概率分布。
计算特征 和目标变量 的联合概率分布 。 计算特征 和目标变量 的边缘概率分布 和 。 计算互信息 并排序,选择互信息较高的特征。
Python案例
好的,让我们考虑一个分类问题的案例,使用互信息法来选择特征,并展示相关的数据分析图形。我们将使用UCI机器学习库中的鸢尾花数据集作为例子。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.feature_selection import mutual_info_classif
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# 加载数据集(鸢尾花数据集)
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# 计算各个特征与目标变量之间的互信息
mi_scores = mutual_info_classif(X, y)
mi_scores = pd.Series(mi_scores, name='MI Scores', index=X.columns)
# 排序并选择前几个互信息最高的特征
selected_features = mi_scores.sort_values(ascending=False).index[:2]
# 绘制互信息分数条形图
plt.figure(figsize=(10, 6))
mi_scores.plot(kind='bar')
plt.title('Mutual Information Scores for Iris Features')
plt.ylabel('MI Score')
plt.xlabel('Features')
plt.xticks(rotation=45)
plt.show()
# 使用选定特征训练分类模型并评估性能
X_selected = X[selected_features]
X_train, X_test, y_train, y_test = train_test_split(X_selected, y, test_size=0.2, random_state=42)
clf = RandomForestClassifier(random_state=42)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy with selected features: {accuracy:.2f}')
数据加载与准备:我们使用鸢尾花数据集作为示例数据,加载数据并分为特征(
X
)和目标变量(y
)。互信息计算:
mutual_info_classif
函数用于计算每个特征与目标变量之间的互信息分数。特征选择:根据互信息分数对特征进行排序,并选择互信息最高的前几个特征作为选定特征。
图形展示:条形图显示了每个特征与目标变量的互信息分数,帮助理解每个特征对分类目标的影响程度。
模型训练与评估:使用选定的特征训练随机森林分类器,并在测试集上评估模型性能(这里计算了分类准确率)。
以上案例展示了如何使用互信息法进行特征选择,并通过机器学习模型来验证选择特征的效果。条形图和分类准确率的计算帮助我们理解特征选择的过程及其对模型性能的影响。
10. 顺序特征选择
顺序特征选择是一种贪心算法,逐步添加(前向选择)或删除(后向选择)特征,通过评估模型性能来找到性能最佳的特征子集。
原理
顺序特征选择通过不断地构建特征子集并评估其在模型中的表现,逐步构建起一个包含最优特征组合的子集。前向选择从空集开始逐步添加特征,而后向选择则从全特征集开始逐步移除特征。
核心公式
顺序特征选择不依赖于具体的数学公式,而是基于模型的性能度量(如准确性、AUC、F1分数等)来评价特征子集的优劣。
推导:
1. 初始化:
前向选择:从空特征集开始。 后向选择:从包含所有特征的集合开始。
2. 特征添加或删除:
前向选择:每轮选择一个
对模型性能提升最大的特征加入当前特征集。
后向选择:每轮移除一个对模型性能影响最小的特征。
3. 模型评估:每次特征添加或删除后,训练模型并评估其性能。
4. 终止条件:当模型性能不再显著提高或达到预设的特征数量时,终止特征选择。
Python实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.metrics import accuracy_score
# 生成虚拟数据集
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=2, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 定义分类模型
model = LogisticRegression()
# 顺序特征选择(向前选择)
selector_forward = SequentialFeatureSelector(model, n_features_to_select='auto', direction='forward', cv=5)
selector_forward.fit(X_train, y_train)
selected_features_forward = selector_forward.get_support()
# 顺序特征选择(向后选择)
selector_backward = SequentialFeatureSelector(model, n_features_to_select='auto', direction='backward', cv=5)
selector_backward.fit(X_train, y_train)
selected_features_backward = selector_backward.get_support()
# 训练并评估模型
model.fit(selector_forward.transform(X_train), y_train)
y_pred_forward = model.predict(selector_forward.transform(X_test))
accuracy_forward = accuracy_score(y_test, y_pred_forward)
model.fit(selector_backward.transform(X_train), y_train)
y_pred_backward = model.predict(selector_backward.transform(X_test))
accuracy_backward = accuracy_score(y_test, y_pred_backward)
# 绘图
plt.figure(figsize=(14, 6))
# 绘制特征选择过程中的特征重要性
plt.subplot(1, 2, 1)
plt.title('Feature Selection Process')
plt.bar(range(X.shape[1]), np.mean(X_train, axis=0), color='skyblue', label='Feature Importance')
plt.xticks(range(X.shape[1]), [f'Feature {i}' for i in range(X.shape[1])], rotation=90)
plt.ylabel('Feature Importance')
plt.legend()
# 绘制特征选择后的结果
plt.subplot(1, 2, 2)
plt.title('Feature Selection Results')
plt.plot(np.arange(1, len(selected_features_forward) + 1), [accuracy_forward] * len(selected_features_forward), 'o-', color='red', label='Forward Selection Accuracy')
plt.plot(np.arange(1, len(selected_features_backward) + 1), [accuracy_backward] * len(selected_features_backward), 'o-', color='blue', label='Backward Selection Accuracy')
plt.xlabel('Number of Selected Features')
plt.ylabel('Accuracy')
plt.legend()
plt.tight_layout()
plt.show()
1. 数据生成:使用make_classification
生成一个虚拟的数据集,具有10个特征,其中5个是信息性的,2个是冗余的。
2. 数据分割:将数据分割为训练集和测试集。
3. 模型定义:使用逻辑回归作为分类模型。
4. 特征选择:使用SequentialFeatureSelector
进行向前选择和向后选择,并获取所选择的特征。
5. 模型训练与评估:训练模型并计算每种选择方法的准确率。
特征选择过程:显示每个特征的相对重要性(此处简化为特征的均值)。 特征选择结果:显示选择不同数量特征后的模型准确率。
最后