在机器学习领域,经常面临处理和存储大量数据的问题,这不仅耗时,而且难以解释。并非所有数据特征都对预测结果至关重要。这些噪声数据可能导致模型性能不佳和过拟合。本文将向介绍一种无监督学习技术——主成分分析(PCA),它可以帮助有效地解决这些问题,并提供更准确的预测结果。
拥有众多特征的数据可能存在相关性和冗余。因此,在获取数据后,首要步骤是通过删除不相关特征和应用特征工程技术来清理数据,这有时甚至能提供比原始特征更好的结果。
PCA是一种技术,通过它可以实现降维(现有属性的线性变换)和多变量分析。它具有多个优点,包括减少数据大小(从而加快执行速度)、更好的可视化效果、最大化方差、减少过拟合等。
首先,需要在训练阶段从不同角度找到主成分,从中挑选出重要且低相关的成分,忽略其余部分,从而降低复杂性。主成分的数量可以少于或等于属性的总数。
# 假设有两个特征列X和Y
X Y
1 4
2 3
3 4
4 6
5 8
# 均值
X' = 3, Y' = 5
# 协方差
cov(x,y) = Σ (Xi – X’) (Yi – Y’)/ n – 1 , where i = 1 to n
C = [ cov(x,x) cov (x,y) ]
[cov(y,x) cov(y,y) ]
对于更多特征,找到整个协方差矩阵,具有更多维度。进一步计算特征值、特征向量等,能够找到主成分。导入算法和使用精确的库可以更容易地识别这些成分,而无需手动计算/操作。请注意,特征值/特征向量的数量将告诉维度的数量以及与这些成分相关的方差量。
在使用PCA之前,必须对数据进行标准化(这也包括将分类变量转换为数值)。应用PCA后,独立特征变得不那么可解释,因为这些主成分也不是可读或可解释的。同时,也可能在PCA过程中丢失信息。
现在,让通过一个数据集来了解算法是如何实现的。将逐步带了解代码的每个部分。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
加载数据并显示特征和类别名称,以便理解。
data.info()
data.describe()
这里将数据分割为特征和目标变量,分别为X和y。使用shape方法,知道数据总共有150行和5列,其中1列是目标变量,其余4列是特征/属性。
x = data.iloc[:,:4] # 特征
y = data.iloc[:,4] # 目标
x.shape, y.shape
from sklearn.decomposition import PCA
pca = PCA()
X = pca.fit_transform(x)
pca.get_covariance()
explained_variance = pca.explained_variance_ratio_
explained_variance
with plt.style.context('dark_background'):
plt.figure(figsize=(6, 4))
plt.bar(range(4), explained_variance, alpha=0.5, align='center',
label='individual explained variance')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principal components')
plt.legend(loc='best')
plt.tight_layout()
从可视化中,得到直觉,主要只有3个成分具有显著的方差,因此选择3个主成分。
pca = PCA(n_components=3)
X = pca.fit_transform(x)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state=20, stratify=y)
训练测试分割是一种常见的训练和评估方法。通常,对训练数据本身的预测可能导致过拟合,从而对未知数据给出糟糕的结果。在这种情况下,通过将数据分割为训练集和测试集,可以在两个不同的数据集上训练和预测模型,从而解决过拟合问题。
from sklearn.neighbors import KNeighborsClassifier
model = KNeighborsClassifier(7)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
cm = confusion_matrix(y_test, y_pred)
print(cm)
print(accuracy_score(y_test, y_pred))