第三章 线性代数--综合实例
第4节 揭秘数据:主成分分析的特征探险
主成分分析(PCA, Principal Component Analysis)是一种常用的数据降维技术,通过将高维数据投影到低维空间,保留数据中的主要特征和变异性。PCA不仅能够帮助我们理解数据结构,还能提升机器学习算法的效率和性能。本节将通过三个实际应用案例,深入探讨PCA在AI中的多种应用场景。
案例一:鸢尾花数据集的可视化与分类
案例描述
鸢尾花(Iris)数据集是机器学习领域的经典数据集,包含150个样本,每个样本有4个特征:花萼长度、花萼宽度、花瓣长度和花瓣宽度。通过主成分分析(PCA)对数据进行降维,可以将四维数据压缩到二维或三维,便于可视化和后续的分类任务。
案例分析
鸢尾花数据集中的四个特征具有一定的相关性,PCA可以有效地提取出数据中最具代表性的主成分,减少维度的同时保留尽可能多的信息。降维后的数据不仅更易于可视化,还能提高分类算法的运行速度和准确性。此外,PCA有助于消除特征间的多重共线性,提高模型的泛化能力。
案例算法步骤
- 数据加载与预处理:加载鸢尾花数据集,并检查数据的基本信息。
- 标准化特征:对数据进行标准化处理,使每个特征的均值为0,方差为1。
- 执行PCA降维:将四维数据降至二维或三维。
- 可视化主成分:绘制降维后的数据分布图,观察不同类别的分离情况。
- 训练分类器并评估性能:使用降维后的数据训练分类模型,评估其性能。
案例对应Python代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report, confusion_matrix
# 1. 数据加载与预处理
iris = load_iris()
X = iris.data # 特征矩阵
y = iris.target # 标签
# 2. 特征标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 3. 执行PCA降维
pca = PCA(n_components=2) # 降至二维
X_pca = pca.fit_transform(X_scaled)
print(f"解释的方差比例:{pca.explained_variance_ratio_}")
# 4. 可视化主成分
plt.figure(figsize=(8,6))
for target, color, label in zip([0, 1, 2], ['r', 'g', 'b'], iris.target_names):
plt.scatter(X_pca[y == target, 0], X_pca[y == target, 1],
color=color, label=label, edgecolor='k', s=50)
plt.xlabel('主成分1')
plt.ylabel('主成分2')
plt.title('鸢尾花数据集的PCA降维结果')
plt.legend()
plt.grid(True)
plt.show()
# 5. 训练分类器并评估性能
# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(
X_pca, y, test_size=0.2, random_state=42, stratify=y
)
# 创建KNN分类器
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train, y_train)
# 预测
y_pred = knn.predict(X_test)
# 评估
print("混淆矩阵:")
print(confusion_matrix(y_test, y_pred))
print("\n分类报告:")
print(classification_report(y_test, y_pred))
# 可视化决策边界(可选)
from matplotlib.colors import ListedColormap
def plot_decision_boundary(X, y, model):
h = .02 # 网格步长
cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF'])
cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.figure(figsize=(8,6))
plt.contourf(xx, yy, Z, alpha=0.3, cmap=cmap_light)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold, edgecolor='k', s=50)
plt.xlabel('主成分1')
plt.ylabel('主成分2')
plt.title('KNN分类决策边界')
plt.show()
plot_decision_boundary(X_pca, y, knn)
代码详解:
-
数据加载与预处理:
from sklearn.datasets import load_iris iris = load_iris() X = iris.data y = iris.target
使用 scikit-learn 自带的鸢尾花数据集,包含150个样本,每个样本有4个特征,目标变量
y
包含三个类别。 -
特征标准化:
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_scaled = scaler.fit_transform(X)
使用
StandardScaler
对特征进行标准化,使其均值为0,方差为1,有助于PCA的效果。 -
执行PCA降维:
from sklearn.decomposition import PCA pca = PCA(n_components=2) X_pca = pca.fit_transform(X_scaled) print(f"解释的方差比例:{pca.explained_variance_ratio_}")
将四维数据降至二维,
explained_variance_ratio_
显示每个主成分解释的方差比例。 -
可视化主成分:
import matplotlib.pyplot as plt plt.figure(figsize=(8,6)) for target, color, label in zip([0, 1, 2], ['r', 'g', 'b'], iris.target_names): plt.scatter(X_pca[y == target, 0], X_pca[y == target, 1], color=color, label=label, edgecolor='k', s=50) plt.xlabel('主成分1') plt.ylabel('主成分2') plt.title('鸢尾花数据集的PCA降维结果') plt.legend() plt.grid(True) plt.show()
绘制降维后的数据分布图,不同颜色代表不同类别,观察类别之间的分离情况。
-
训练分类器并评估性能:
from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import classification_report, confusion_matrix X_train, X_test, y_train, y_test = train_test_split( X_pca, y, test_size=0.2, random_state=42, stratify=y ) knn = KNeighborsClassifier(n_neighbors=5) knn.fit(X_train, y_train) y_pred = knn.predict(X_test) print("混淆矩阵:") print(confusion_matrix(y_test, y_pred)) print("\n分类报告:") print(classification_report(y_test, y_pred))
使用K-近邻(KNN)分类器进行训练和预测,评估分类性能。
-
可视化决策边界(可选):
from matplotlib.colors import ListedColormap def plot_decision_boundary(X, y, model): h = .02 cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF']) cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF']) x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) Z = model.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.figure(figsize=(8,6)) plt.contourf(xx, yy, Z, alpha=0.3, cmap=cmap_light) plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold, edgecolor='k', s=50) plt.xlabel('主成分1') plt.ylabel('主成分2') plt.title('KNN分类决策边界') plt.show() plot_decision_boundary(X_pca, y, knn)
绘制KNN分类器的决策边界,直观展示分类器在降维后的特征空间中的表现。
运行效果:
- 解释的方差比例:显示主成分1和主成分2分别解释了数据总方差的比例。
- PCA降维结果图:不同颜色的点清晰地分离了三种鸢尾花类别。
- 混淆矩阵与分类报告:展示分类器的准确性、精确率、召回率和F1分数。
- 损失曲线(如适用):展示模型训练过程中的损失变化情况。
案例二:面部识别中的PCA(Eigenfaces)
案例描述
面部识别是计算机视觉中的重要应用,PCA在面部识别中被广泛用于特征提取,通过提取主成分(Eigenfaces)来减少数据维度并保留主要面部特征,实现高效的面部识别系统。
案例分析
面部图像通常是高维数据,直接处理不仅计算量大,还容易受到噪声和光照变化的影响。PCA通过将高维图像数据降维到低维空间,提取出最具代表性的特征(Eigenfaces),可以有效地减少数据维度,同时保留面部的主要信息。这不仅提高了识别的效率,还增强了模型的鲁棒性。使用PCA进行面部识别,可以在保持较高准确率的同时,大幅降低存储和计算成本。
案例算法步骤
- 数据加载与预处理:加载面部图像数据集,并将图像转换为灰度图。
- 图像标准化:将图像数据转换为二维矩阵,并进行中心化处理。
- 执行PCA降维:计算协方差矩阵,提取主成分(Eigenfaces)。
- 重构图像与特征提取:使用主成分重构图像,并提取特征向量。
- 训练分类器并进行识别:使用提取的特征向量训练分类器,实现面部识别。
案例对应Python代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.datasets import fetch_lfw_people
from sklearn.preprocessing import StandardScaler
# 1. 数据加载与预处理
lfw = fetch_lfw_people(min_faces_per_person=70, resize=0.4)
X = lfw.data # 每张图像展平后的特征
y = lfw.target
target_names = lfw.target_names
n_classes = target_names.shape[0]
print(f"样本数量:{X.shape[0]}, 特征数量:{X.shape[1]}")
print(f"类别数量:{n_classes}")
# 2. 特征标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 3. 执行PCA降维
n_components = 150 # 保留150个主成分
pca = PCA(n_components=n_components, svd_solver='randomized', whiten=True, random_state=42)
X_pca = pca.fit_transform(X_scaled)
print(f"总方差解释比例:{np.sum(pca.explained_variance_ratio_):.2f}")
# 可视化前几个Eigenfaces
eigenfaces = pca.components_.reshape((n_components, lfw.images.shape[1], lfw.images.shape[2]))
fig, axes = plt.subplots(3, 5, figsize=(15, 9),
subplot_kw={'xticks': [], 'yticks': []})
for i, ax in enumerate(axes.flat):
ax.imshow(eigenfaces[i], cmap='gray')
ax.set_title(f"Eigenface {i+1}")
plt.suptitle("前15个Eigenfaces")
plt.show()
# 4. 重构图像与特征提取
# 使用前100个主成分
n_components_reconstruct = 100
pca_reconstruct = PCA(n_components=n_components_reconstruct, svd_solver='randomized', whiten=True, random_state=42)
X_pca_reconstruct = pca_reconstruct.fit_transform(X_scaled)
# 5. 训练分类器并进行识别
X_train, X_test, y_train, y_test = train_test_split(
X_pca_reconstruct, y, test_size=0.25, random_state=42, stratify=y
)
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
print("混淆矩阵:")
print(confusion_matrix(y_test, y_pred))
print("\n分类报告:")
print(classification_report(y_test, y_pred))
# 可视化部分识别结果
def plot_gallery(images, titles, h, w, n_row=3, n_col=4):
plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))
plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)
for i in range(n_row * n_col):
if i >= len(images):
break
plt.subplot(n_row, n_col, i + 1)
plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)
plt.title(titles[i], size=12)
plt.xticks(())
plt.yticks(())
def title(y_pred, y_test, target_names, i):
pred_name = target_names[y_pred[i]].rsplit(' ', 1)[-1]
true_name = target_names[y_test[i]].rsplit(' ', 1)[-1]
return f"Pred: {pred_name}\nTrue: {true_name}"
prediction_titles = [title(y_pred, y_test, target_names, i) for i in range(len(y_pred))]
plot_gallery(lfw.images[y_test], prediction_titles, lfw.images.shape[1], lfw.images.shape[2])
plt.show()
代码详解:
-
数据加载与预处理:
from sklearn.datasets import fetch_lfw_people lfw = fetch_lfw_people(min_faces_per_person=70, resize=0.4) X = lfw.data y = lfw.target target_names = lfw.target_names
使用
fetch_lfw_people
加载Labeled Faces in the Wild (LFW) 数据集,筛选出每个类别至少70张图像的面孔,调整图像大小为原来的40%。 -
特征标准化:
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_scaled = scaler.fit_transform(X)
对图像数据进行标准化,使每个特征均值为0,方差为1,有助于PCA的效果。
-
执行PCA降维:
from sklearn.decomposition import PCA pca = PCA(n_components=150, svd_solver='randomized', whiten=True, random_state=42) X_pca = pca.fit_transform(X_scaled) print(f"总方差解释比例:{np.sum(pca.explained_variance_ratio_):.2f}")
将高维图像数据降至150维,
explained_variance_ratio_
显示总方差解释比例。 -
可视化前几个Eigenfaces:
eigenfaces = pca.components_.reshape((n_components, lfw.images.shape[1], lfw.images.shape[2])) fig, axes = plt.subplots(3, 5, figsize=(15, 9), subplot_kw={'xticks': [], 'yticks': []}) for i, ax in enumerate(axes.flat): ax.imshow(eigenfaces[i], cmap='gray') ax.set_title(f"Eigenface {i+1}") plt.suptitle("前15个Eigenfaces") plt.show()
展示前15个Eigenfaces,直观了解PCA提取的主要面部特征。
-
重构图像与特征提取:
n_components_reconstruct = 100 pca_reconstruct = PCA(n_components=n_components_reconstruct, svd_solver='randomized', whiten=True, random_state=42) X_pca_reconstruct = pca_reconstruct.fit_transform(X_scaled)
使用前100个主成分进行重构和特征提取,以减少计算复杂度。
-
训练分类器并进行识别:
from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import classification_report, confusion_matrix X_train, X_test, y_train, y_test = train_test_split( X_pca_reconstruct, y, test_size=0.25, random_state=42, stratify=y ) knn = KNeighborsClassifier(n_neighbors=5) knn.fit(X_train, y_train) y_pred = knn.predict(X_test) print("混淆矩阵:") print(confusion_matrix(y_test, y_pred)) print("\n分类报告:") print(classification_report(y_test, y_pred))
使用K-近邻(KNN)分类器进行训练和预测,评估模型的分类性能。
-
可视化部分识别结果:
from matplotlib.colors import ListedColormap def plot_gallery(images, titles, h, w, n_row=3, n_col=4): plt.figure(figsize=(1.8 * n_col, 2.4 * n_row)) plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35) for i in range(n_row * n_col): if i >= len(images): break plt.subplot(n_row, n_col, i + 1) plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray) plt.title(titles[i], size=12) plt.xticks(()) plt.yticks(()) def title(y_pred, y_test, target_names, i): pred_name = target_names[y_pred[i]].rsplit(' ', 1)[-1] true_name = target_names[y_test[i]].rsplit(' ', 1)[-1] return f"Pred: {pred_name}\nTrue: {true_name}" prediction_titles = [title(y_pred, y_test, target_names, i) for i in range(len(y_pred))] plot_gallery(lfw.images[y_test], prediction_titles, lfw.images.shape[1], lfw.images.shape[2]) plt.show()
绘制部分测试样本的预测结果,与真实标签对比,直观展示模型的识别效果。
案例三:市场营销中的客户细分
案例描述
在市场营销中,理解客户的行为和特征对于制定有效的营销策略至关重要。通过主成分分析(PCA)对客户数据进行降维,可以揭示潜在的客户群体结构,实现精细化的客户细分,从而优化营销活动和资源分配。
案例分析
客户数据通常包含多个维度,如年龄、收入、消费习惯、产品偏好等。这些高维数据可能存在多重共线性,导致分析复杂且效果不佳。PCA通过提取主要成分,减少数据的维度,同时保留数据中的主要变异性,使得客户群体的结构更加清晰。降维后的数据不仅便于可视化,还能提升聚类算法的效率和准确性,从而实现更有效的客户细分。
案例算法步骤
- 数据收集与预处理:收集客户的多维度数据,处理缺失值和异常值。
- 特征标准化:对数据进行标准化,使每个特征的均值为0,方差为1。
- 执行PCA降维:计算主成分,选择解释足够方差的前k个主成分。
- 可视化与聚类:将降维后的数据进行可视化,并应用聚类算法(如K-Means)进行客户细分。
- 分析与应用:根据聚类结果分析不同客户群体的特征,制定相应的营销策略。
案例对应Python代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
# 1. 数据收集与预处理
# 示例数据集:假设我们有一个包含客户年龄、收入、支出、产品偏好等特征的数据集
data = {
'年龄': [25, 34, 45, 23, 35, 52, 46, 34, 28, 39, 41, 37, 29, 33, 50],
'收入': [50000, 60000, 80000, 45000, 62000, 90000, 85000, 70000, 48000, 75000, 82000, 69000, 52000, 68000, 88000],
'支出': [20000, 25000, 30000, 18000, 24000, 35000, 32000, 27000, 21000, 29000, 31000, 26000, 22000, 28000, 33000],
'产品偏好': [5, 3, 4, 2, 3, 5, 4, 3, 2, 4, 5, 3, 2, 4, 5]
}
df = pd.DataFrame(data)
print("原始客户数据:")
print(df)
# 2. 特征标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df)
# 3. 执行PCA降维
pca = PCA(n_components=2, random_state=42)
X_pca = pca.fit_transform(X_scaled)
print(f"解释的方差比例:{pca.explained_variance_ratio_}")
# 4. 可视化与聚类
plt.figure(figsize=(8,6))
plt.scatter(X_pca[:, 0], X_pca[:, 1], s=100)
plt.xlabel('主成分1')
plt.ylabel('主成分2')
plt.title('客户数据的PCA降维结果')
plt.grid(True)
plt.show()
# 应用K-Means聚类
k = 3 # 假设我们希望分为3个客户群体
kmeans = KMeans(n_clusters=k, random_state=42)
clusters = kmeans.fit_predict(X_pca)
# 可视化聚类结果
plt.figure(figsize=(8,6))
colors = ['r', 'g', 'b']
for i in range(k):
plt.scatter(X_pca[clusters == i, 0], X_pca[clusters == i, 1],
s=100, color=colors[i], label=f'群体 {i+1}', edgecolor='k')
plt.xlabel('主成分1')
plt.ylabel('主成分2')
plt.title('客户细分的PCA降维结果与聚类')
plt.legend()
plt.grid(True)
plt.show()
# 评估聚类效果
sil_score = silhouette_score(X_pca, clusters)
print(f"Silhouette 分数:{sil_score:.2f}")
# 将聚类结果添加到原始数据
df['群体'] = clusters + 1
print("\n带有群体标签的客户数据:")
print(df)
代码详解:
-
数据收集与预处理:
data = { '年龄': [25, 34, 45, 23, 35, 52, 46, 34, 28, 39, 41, 37, 29, 33, 50], '收入': [50000, 60000, 80000, 45000, 62000, 90000, 85000, 70000, 48000, 75000, 82000, 69000, 52000, 68000, 88000], '支出': [20000, 25000, 30000, 18000, 24000, 35000, 32000, 27000, 21000, 29000, 31000, 26000, 22000, 28000, 33000], '产品偏好': [5, 3, 4, 2, 3, 5, 4, 3, 2, 4, 5, 3, 2, 4, 5] } df = pd.DataFrame(data)
创建一个示例客户数据集,包含年龄、收入、支出和产品偏好等特征。
-
特征标准化:
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_scaled = scaler.fit_transform(df)
使用
StandardScaler
对特征进行标准化处理,确保每个特征的均值为0,方差为1。 -
执行PCA降维:
from sklearn.decomposition import PCA pca = PCA(n_components=2, random_state=42) X_pca = pca.fit_transform(X_scaled) print(f"解释的方差比例:{pca.explained_variance_ratio_}")
将高维数据降至二维,
explained_variance_ratio_
显示主成分解释的数据方差比例。 -
可视化与聚类:
import matplotlib.pyplot as plt plt.figure(figsize=(8,6)) plt.scatter(X_pca[:, 0], X_pca[:, 1], s=100) plt.xlabel('主成分1') plt.ylabel('主成分2') plt.title('客户数据的PCA降维结果') plt.grid(True) plt.show()
绘制降维后的客户数据分布图,观察数据的总体结构。
应用K-Means聚类:
from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score k = 3 # 假设我们希望分为3个客户群体 kmeans = KMeans(n_clusters=k, random_state=42) clusters = kmeans.fit_predict(X_pca) # 可视化聚类结果 plt.figure(figsize=(8,6)) colors = ['r', 'g', 'b'] for i in range(k): plt.scatter(X_pca[clusters == i, 0], X_pca[clusters == i, 1], s=100, color=colors[i], label=f'群体 {i+1}', edgecolor='k') plt.xlabel('主成分1') plt.ylabel('主成分2') plt.title('客户细分的PCA降维结果与聚类') plt.legend() plt.grid(True) plt.show() # 评估聚类效果 sil_score = silhouette_score(X_pca, clusters) print(f"Silhouette 分数:{sil_score:.2f}")
使用K-Means聚类算法对降维后的数据进行客户细分,并评估聚类效果。
-
分析与应用:
# 将聚类结果添加到原始数据 df['群体'] = clusters + 1 print("\n带有群体标签的客户数据:") print(df)
将聚类结果标签添加到原始数据中,便于后续分析和制定营销策略。
运行效果:
- 解释的方差比例:展示主成分1和主成分2分别解释了数据总方差的比例。
- PCA降维结果图:二维空间中不同客户的分布情况。
- 聚类结果图:不同颜色代表不同客户群体,展示客户细分的效果。
- Silhouette 分数:评估聚类的紧密性和分离度。
- 带有群体标签的客户数据:展示每个客户所属的群体,便于进一步分析。
通过以上三个案例,我们深入了解了主成分分析(PCA)在不同领域中的实际应用。从数据可视化与分类、面部识别到市场营销中的客户细分,PCA展示了其在揭示数据结构、降维和特征提取方面的强大能力。掌握这些方法不仅有助于理解线性代数在AI中的实际应用,还为设计高效、精准的数据分析和机器学习系统提供了坚实的数学基础。
标签:plt,AI,print,python,PCA,test,import,pca,线代 From: https://blog.csdn.net/l35633/article/details/145046416