我正在使用RandomForestClassifier实现一个具有二元结果的分类任务,我知道数据预处理的重要性,以提高准确率得分。特别是,我的数据集包含100多个特征和近4000个实例,我希望执行降维技术,以避免过度拟合,因为数据中存在高噪声。
对于这些任务,我通常使用经典的特征选择方法(过滤器、包装器、特征重要性),但我最近读到了关于组合主成分分析(PCA) (在第一步中),然后在转换后的数据集上进行特征选择的内容。
我的问题是:在对我的数据执行PCA之后,是否有特定的特征选择方法应该使用?特别是,我想了解的是,在我的数据上使用PCA是否会使某些特定特征选择技术的使用变得无用或效率较低。
发布于 2020-07-27 03:38:43
让我们从什么时候应该使用PCA开始?
当您不确定数据的哪个组成部分影响精度时,PCA最有用。
让我们考虑一下人脸识别任务。我们能一目了然地说出最关键的像素吗?
例如: Olivetti faces。40人,深色均匀背景,不同的照明,面部表情(睁/闭眼,微笑/不微笑),以及面部细节(戴眼镜/不戴眼镜)。
因此,如果我们看一下像素之间的相关性:
from sklearn.datasets import fetch_olivetti_faces
from numpy import corrcoef
from numpy import zeros_like
from numpy import triu_indices_from
from matplotlib.pyplot import figure
from matplotlib.pyplot import get_cmap
from matplotlib.pyplot import plot
from matplotlib.pyplot import colorbar
from matplotlib.pyplot import subplots
from matplotlib.pyplot import suptitle
from matplotlib.pyplot import imshow
from matplotlib.pyplot import xlabel
from matplotlib.pyplot import ylabel
from matplotlib.pyplot import savefig
from matplotlib.image import imread
import seaborn
olivetti = fetch_olivetti_faces()
X = olivetti.images # Train
y = olivetti.target # Labels
X = X.reshape((X.shape[0], X.shape[1] * X.shape[2]))
seaborn.set(font_scale=1.2)
seaborn.set_style("darkgrid")
mask = zeros_like(corrcoef(X_resp))
mask[triu_indices_from(mask)] = True
with seaborn.axes_style("white"):
f, ax = subplots(figsize=(20, 15))
ax = seaborn.heatmap(corrcoef(X),
annot=True,
mask=mask,
vmax=1,
vmin=0,
square=True,
cmap="YlGnBu",
annot_kws={"size": 1})
savefig('heatmap.png')

从上面你能告诉我哪些像素对分类最重要吗?
然而,如果我问你,“你能告诉我慢性肾脏疾病最重要的特征吗?”
你可以一目了然地告诉我:

如果我们从人脸识别任务开始,我们真的需要所有的像素来进行分类吗?
不,我们没有。

在上面你可以看到只有63个像素足以将一张脸识别为人类。
请注意,63个像素足以识别人脸,而不是人脸识别。你需要更多的像素来区分人脸。
所以我们要做的就是降低维数。您可能需要阅读有关Curse of dimensionality的更多信息
好的,我们决定使用PCA,因为我们不需要人脸图像的每个像素。我们必须降低维度。
为了让视觉上更容易理解,我使用了2维。
def projection(obj, x, x_label, y_label, title, class_num=40, sample_num=10, dpi=300):
x_obj = obj.transform(x)
idx_range = class_num * sample_num
fig = figure(figsize=(6, 3), dpi=dpi)
ax = fig.add_subplot(1, 1, 1)
c_map = get_cmap(name='jet', lut=class_num)
scatter = ax.scatter(x_obj[:idx_range, 0], x_obj[:idx_range, 1], c=y[:idx_range],
s=10, cmap=c_map)
ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
ax.set_title(title.format(class_num))
colorbar(mappable=scatter)
pca_obj = PCA(n_components=2).fit(X)
x_label = "First Principle Component"
y_label = "Second Principle Component"
title = "PCA Projection of {} people"
projection(obj=pca_obj, x=X, x_label=x_label, y_label=y_label, title=title)

如你所见,具有2个分量的PCA不足以区分。
那么你需要多少个组件呢?
def display_n_components(obj):
figure(1, figsize=(6,3), dpi=300)
plot(obj.explained_variance_, linewidth=2)
xlabel('Components')
ylabel('Explained Variaces')
pca_obj2 = PCA().fit(X)
display_n_components(pca_obj2)

你需要100个组件才能很好的辨别。
现在我们需要拆分训练集和测试集。
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.decomposition import PCA
from sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
X_train = X_train.reshape((X_train.shape[0], X.shape[1] * X.shape[2]))
X_test = X_test.reshape((X_test.shape[0], X.shape[1] * X.shape[2]))
pca = PCA(n_components=100).fit(X)
X_pca_tr = pca.transform(X_train)
X_pca_te = pca.transform(X_test)
forest1 = RandomForestClassifier(random_state=42)
forest1.fit(X_pca_tr, y_train)
y_pred = forest1.predict(X_pca_te)
print("\nAccuracy:{:,.2f}%".format(accuracy_score(y_true=y_test, y_pred=y_pred_)*100))准确率将是:

你可能会想,PCA是否提高了准确性?
答案是肯定的。
不使用PCA:

https://stackoverflow.com/questions/62851445
复制相似问题