{ "cells": [ { "cell_type": "markdown", "id": "73bd968b-d970-4a05-94ef-4e7abf990827", "metadata": {}, "source": [ "Chapter 24\n", "\n", "# 数据分解\n", "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" ] }, { "cell_type": "markdown", "id": "84c7e223-f9df-4575-a7d8-ab27812fea5c", "metadata": {}, "source": [ "这段代码对鸢尾花数据集的特征矩阵 $X$ 进行了多种矩阵操作和分解,以便分析数据的结构和特性。首先,代码计算了 $X$ 的 **Gram 矩阵** $G = X^T X$,展示了数据样本的内积关系。接着,基于 $G$ 构造了 **余弦相似度矩阵** $C$,通过对 $G$ 中的特征进行归一化处理,使得 $C$ 中的每个元素代表样本间的相似性。随后,代码计算数据的 **质心**(均值向量) $E(X)$ 并生成 **去均值数据矩阵** $X_c = X - E(X)$,使数据中心化,以便消除均值对数据的影响。\n", "\n", "代码进一步计算了 **协方差矩阵** $\\Sigma = \\frac{1}{N} X_c^T X_c$ 和 **相关矩阵** $\\rho$,分别表示特征间的协方差和标准化后的相关性。\n", "\n", "接下来,代码进行了多种矩阵分解,包括:\n", "\n", "1. **QR 分解**:将原始矩阵 $X$ 分解为一个正交矩阵 $Q$ 和一个上三角矩阵 $R$,满足 $X = QR$。\n", " \n", "2. **Cholesky 分解**:对 Gram 矩阵 $G$ 和协方差矩阵 $\\Sigma$ 进行分解,得到其对应的下三角矩阵 $L$,使得 $G = LL^T$ 和 $\\Sigma = LL^T$。\n", " \n", "3. **特征值分解**:对 Gram 矩阵 $G$、协方差矩阵 $\\Sigma$ 和相关矩阵 $\\rho$ 进行特征值分解,得到其特征值(对角化的 $\\Lambda$ 矩阵)和特征向量矩阵 $V$,满足 $G = V \\Lambda V^T$、$\\Sigma = V \\Lambda V^T$ 和 $\\rho = V \\Lambda V^T$。\n", "\n", "4. **奇异值分解(SVD)**:对原始数据 $X$、去均值数据 $X_c$ 和标准化数据 $Z_X$ 分别进行 SVD 分解,得到分解形式 $X = U S V^T$,其中 $U$ 和 $V$ 分别表示数据的左右奇异向量矩阵,$S$ 是包含奇异值的对角矩阵。SVD 提供了数据的主成分方向和大小,用于后续的主成分分析(PCA)或特征提取。\n", "\n", "通过这些分解和操作,代码全面分析了数据的相似性、协方差结构、相关性、主成分和特征方向,为理解数据的内在结构提供了重要参考。" ] }, { "cell_type": "code", "execution_count": 1, "id": "f95b3fca-b77f-4e10-a84d-62f6876de01a", "metadata": {}, "outputs": [], "source": [ "import numpy as np # 导入 numpy 进行数值计算\n", "import matplotlib.pyplot as plt # 导入 matplotlib 用于绘图\n", "import pandas as pd # 导入 pandas 进行数据操作\n", "from sklearn.datasets import load_iris # 从 sklearn 加载鸢尾花数据集" ] }, { "cell_type": "code", "execution_count": 2, "id": "c3ab92a3-7a2b-4655-b39f-41014f0bf0c3", "metadata": {}, "outputs": [], "source": [ "from numpy.linalg import inv # 导入 inv 函数用于矩阵求逆\n", "from scipy.stats import zscore # 导入 zscore 函数用于标准化\n", "from numpy.linalg import qr # 导入 qr 函数进行 QR 分解\n", "from numpy.linalg import cholesky as chol # 导入 cholesky 函数用于 Cholesky 分解\n", "from numpy.linalg import eig # 导入 eig 函数进行特征值分解\n", "from numpy.linalg import svd # 导入 svd 函数用于奇异值分解" ] }, { "cell_type": "markdown", "id": "c401295c-eabb-4713-94aa-2311ec8a972d", "metadata": {}, "source": [ "## 加载数据" ] }, { "cell_type": "code", "execution_count": 3, "id": "2397142d-b32e-465f-834f-65b06c127cea", "metadata": {}, "outputs": [], "source": [ "iris = load_iris() # 从 sklearn 加载鸢尾花数据集" ] }, { "cell_type": "code", "execution_count": 4, "id": "313bf88d-fcfd-4947-beb3-bcb2d7bc56e3", "metadata": {}, "outputs": [], "source": [ "X = iris.data # 特征矩阵 X\n", "y = iris.target # 目标标签 y" ] }, { "cell_type": "code", "execution_count": 5, "id": "91f49a78-e515-4201-9eb3-d8993b32471d", "metadata": {}, "outputs": [], "source": [ "feature_names = ['Sepal length, x1', 'Sepal width, x2',\n", " 'Petal length, x3', 'Petal width, x4'] # 特征名称" ] }, { "cell_type": "markdown", "id": "730bcf6c-1e64-4bda-85fe-80a14077e339", "metadata": {}, "source": [ "## 将特征矩阵 X 转换为 DataFrame 格式" ] }, { "cell_type": "code", "execution_count": 6, "id": "c86246d1-a83b-4495-a982-36e715eeae6e", "metadata": {}, "outputs": [], "source": [ "X_df = pd.DataFrame(X, columns=feature_names)" ] }, { "cell_type": "markdown", "id": "54cef963-570f-47c3-b5dd-222fdc550707", "metadata": {}, "source": [ "## 原始数据 X" ] }, { "cell_type": "code", "execution_count": 7, "id": "802ac1d9-148c-4e3b-b00f-9f1ee45648d1", "metadata": {}, "outputs": [], "source": [ "X = X_df.to_numpy() # 转换 DataFrame 为 numpy 数组" ] }, { "cell_type": "markdown", "id": "877eeaab-7719-4b83-b829-280143f81c5a", "metadata": {}, "source": [ "## Gram 矩阵 G" ] }, { "cell_type": "code", "execution_count": 8, "id": "775d5366-beec-4349-bae2-7726b9735f6e", "metadata": {}, "outputs": [], "source": [ "G = X.T @ X # 计算 Gram 矩阵,G = X^T X" ] }, { "cell_type": "markdown", "id": "967a5f97-96e3-43c5-9527-76d2879e8f03", "metadata": {}, "source": [ "## 余弦相似度矩阵 C" ] }, { "cell_type": "code", "execution_count": 9, "id": "3639f25d-1ad5-4646-bfd5-675cf79fd512", "metadata": {}, "outputs": [], "source": [ "# 使用特征范数计算相似度\n", "S_norm = np.diag(np.sqrt(np.diag(G))) # 生成缩放矩阵,对角线元素为每列特征的范数" ] }, { "cell_type": "code", "execution_count": 10, "id": "2052f952-8ee5-4914-9bb9-33bce33b92b5", "metadata": {}, "outputs": [], "source": [ "C = inv(S_norm) @ G @ inv(S_norm) # 计算余弦相似度矩阵 C" ] }, { "cell_type": "markdown", "id": "fa9f5362-0b41-4a6c-8ca1-2324672bd552", "metadata": {}, "source": [ "## 数据矩阵的质心 E(X)" ] }, { "cell_type": "code", "execution_count": 11, "id": "7e51dd81-5415-46ee-be03-9bbfba20be8a", "metadata": {}, "outputs": [], "source": [ "E_X = X_df.mean().to_frame().T # 计算 X 的均值,并转换为单行 DataFrame" ] }, { "cell_type": "markdown", "id": "83005aa2-ba44-4ee6-8bcd-c70f86d0c366", "metadata": {}, "source": [ "## 数据去均值处理 X_c" ] }, { "cell_type": "code", "execution_count": 12, "id": "e98077f7-6426-427d-a6f4-8a85bef517c4", "metadata": {}, "outputs": [], "source": [ "X_c = X_df.sub(X_df.mean()) # 每列减去其均值,得到去均值矩阵 X_c" ] }, { "cell_type": "markdown", "id": "3f96ef51-d242-4f3e-a95d-c4174d394d63", "metadata": {}, "source": [ "## 协方差矩阵 Sigma" ] }, { "cell_type": "code", "execution_count": 13, "id": "8aae2ef4-1803-4522-9d72-0749936c3bab", "metadata": {}, "outputs": [], "source": [ "SIGMA = X_df.cov() # 计算协方差矩阵 SIGMA" ] }, { "cell_type": "markdown", "id": "2aee8ac6-dd46-446f-82d7-4f953a3b03aa", "metadata": {}, "source": [ "## 相关矩阵 P" ] }, { "cell_type": "code", "execution_count": 14, "id": "b79c796e-be1e-4ace-be31-87af4c1daf84", "metadata": {}, "outputs": [], "source": [ "RHO = X_df.corr() # 计算相关矩阵 RHO" ] }, { "cell_type": "markdown", "id": "b087fa60-77ef-4280-8e20-d4efa134ba69", "metadata": {}, "source": [ "## 数据标准化 Z_X" ] }, { "cell_type": "code", "execution_count": 15, "id": "8b473969-650c-4c52-ae8d-f89ce7b9dce0", "metadata": {}, "outputs": [], "source": [ "Z_X = zscore(X_df) # 对 X 的每列标准化,使其均值为 0,标准差为 1" ] }, { "cell_type": "markdown", "id": "a70b1f17-e178-4f52-9346-e330986b22b0", "metadata": {}, "source": [ "## QR 分解" ] }, { "cell_type": "code", "execution_count": 16, "id": "fc15ec6d-931a-4472-b1d0-7d1aaa1285dd", "metadata": {}, "outputs": [], "source": [ "Q, R = qr(X_df, mode='reduced') # 对 X 进行 QR 分解,mode='reduced' 保留最小矩阵维度" ] }, { "cell_type": "markdown", "id": "d1977ba7-04d1-4d11-b9a4-dc5b0e1ff5c8", "metadata": {}, "source": [ "## Cholesky 分解" ] }, { "cell_type": "code", "execution_count": 17, "id": "7f129525-f4e7-48b7-ba19-bc49ad4515e3", "metadata": {}, "outputs": [], "source": [ "L_G = chol(G) # 对 Gram 矩阵 G 进行 Cholesky 分解,得到下三角矩阵 L_G" ] }, { "cell_type": "code", "execution_count": 18, "id": "293cfc24-8d6c-48b5-8b55-0fd2173f10de", "metadata": {}, "outputs": [], "source": [ "R_G = L_G.T # 上三角矩阵 R_G 为 L_G 的转置" ] }, { "cell_type": "markdown", "id": "44091d77-46f4-416f-8305-d66438fc9d62", "metadata": {}, "source": [ "## 协方差矩阵 Sigma 的 Cholesky 分解" ] }, { "cell_type": "code", "execution_count": 19, "id": "959d25e3-0ab4-40c1-b79d-f6388712b381", "metadata": {}, "outputs": [], "source": [ "L_Sigma = chol(SIGMA) # 对协方差矩阵 SIGMA 进行 Cholesky 分解" ] }, { "cell_type": "code", "execution_count": 20, "id": "94d8ce95-d99d-43a1-b244-402cf2e07f28", "metadata": {}, "outputs": [], "source": [ "R_Sigma = L_Sigma.T # 上三角矩阵 R_Sigma 为 L_Sigma 的转置" ] }, { "cell_type": "markdown", "id": "4f02b402-a8bc-464a-9006-4dca94b9b219", "metadata": {}, "source": [ "## Gram 矩阵 G 的特征值分解" ] }, { "cell_type": "code", "execution_count": 21, "id": "b63e3321-afb5-4b9e-ac92-a74c39537169", "metadata": {}, "outputs": [], "source": [ "Lambs_G, V_G = eig(G) # 对 G 进行特征值分解,得到特征值 Lambs_G 和特征向量 V_G" ] }, { "cell_type": "code", "execution_count": 22, "id": "40135be7-b292-4765-8a8b-866b4f22418f", "metadata": {}, "outputs": [], "source": [ "Lambs_G = np.diag(Lambs_G) # 将特征值转换为对角矩阵形式" ] }, { "cell_type": "markdown", "id": "559af984-f9b8-4f34-8c69-af3035dfb589", "metadata": {}, "source": [ "## 协方差矩阵 Sigma 的特征值分解" ] }, { "cell_type": "code", "execution_count": 23, "id": "0280dc12-1245-4b5d-8099-8fe3abc94ccc", "metadata": {}, "outputs": [], "source": [ "Lambs_sigma, V_sigma = eig(SIGMA) # 对 SIGMA 进行特征值分解" ] }, { "cell_type": "code", "execution_count": 24, "id": "7941e036-5e24-4a15-8612-20dfd3d60779", "metadata": {}, "outputs": [], "source": [ "Lambs_sigma = np.diag(Lambs_sigma) # 将特征值转换为对角矩阵形式" ] }, { "cell_type": "markdown", "id": "d387720b-43f9-4c24-a918-48eb686acb8a", "metadata": {}, "source": [ "## 相关矩阵 P 的特征值分解" ] }, { "cell_type": "code", "execution_count": 25, "id": "7227d988-df95-44f1-9986-bd3f0922d7da", "metadata": {}, "outputs": [], "source": [ "Lambs_P, V_P = eig(RHO) # 对相关矩阵 RHO 进行特征值分解" ] }, { "cell_type": "code", "execution_count": 26, "id": "a8a40ce6-cdde-4fea-be3e-1d34367b9aac", "metadata": {}, "outputs": [], "source": [ "Lambs_P = np.diag(Lambs_P) # 将特征值转换为对角矩阵形式" ] }, { "cell_type": "markdown", "id": "2891d64a-1faa-47a6-bcba-5c56611e96cf", "metadata": {}, "source": [ "## 原始数据 X 的 SVD 分解" ] }, { "cell_type": "code", "execution_count": 27, "id": "37ffec3a-f1ea-45dc-9fa0-be3e27bc15e7", "metadata": {}, "outputs": [], "source": [ "U_X, S_X_, V_X = svd(X_df, full_matrices=False) # 对 X 进行 SVD 分解" ] }, { "cell_type": "code", "execution_count": 28, "id": "472ff2d6-e2fe-4ba5-b341-cc13ebf416fe", "metadata": {}, "outputs": [], "source": [ "V_X = V_X.T # 转置 V_X" ] }, { "cell_type": "code", "execution_count": 29, "id": "fd6103a7-12b4-431f-9ad5-1d7d4a3c6564", "metadata": {}, "outputs": [], "source": [ "S_X = np.diag(S_X_) # 将奇异值转换为对角矩阵" ] }, { "cell_type": "markdown", "id": "93dc741b-c4b5-48ae-a32e-8b80bafa2ae6", "metadata": {}, "source": [ "## 去均值数据 X_c 的 SVD 分解" ] }, { "cell_type": "code", "execution_count": 30, "id": "58e1f3b8-6838-410e-bbfa-1b538b8713c1", "metadata": {}, "outputs": [], "source": [ "U_Xc, S_Xc, V_Xc = svd(X_c, full_matrices=False) # 对去均值后的数据 X_c 进行 SVD 分解" ] }, { "cell_type": "code", "execution_count": 31, "id": "98a5eb4a-8112-4021-9339-27779343347c", "metadata": {}, "outputs": [], "source": [ "V_Xc = V_Xc.T # 转置 V_Xc" ] }, { "cell_type": "code", "execution_count": 32, "id": "fb80d669-ea06-4ee3-a74e-1e3b8a00e954", "metadata": {}, "outputs": [], "source": [ "S_Xc = np.diag(S_Xc) # 将奇异值转换为对角矩阵" ] }, { "cell_type": "markdown", "id": "9b015450-0229-445f-bf61-487d53fa3efe", "metadata": {}, "source": [ "## 标准化数据 Z_X 的 SVD 分解" ] }, { "cell_type": "code", "execution_count": 33, "id": "689bb4cf-2b59-45ca-b8e4-acaf31d8e139", "metadata": {}, "outputs": [], "source": [ "U_Z, S_Z, V_Z = svd(Z_X, full_matrices=False) # 对标准化后的数据 Z_X 进行 SVD 分解" ] }, { "cell_type": "code", "execution_count": 34, "id": "a296884a-2df5-4b34-b1ad-ffec488c2f37", "metadata": {}, "outputs": [], "source": [ "V_Z = V_Z.T # 转置 V_Z" ] }, { "cell_type": "code", "execution_count": 35, "id": "a3bd573a-de20-4d7c-81a2-f88c2bcf0263", "metadata": {}, "outputs": [], "source": [ "S_Z = np.diag(S_Z) # 将奇异值转换为对角矩阵" ] }, { "cell_type": "code", "execution_count": null, "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.7" } }, "nbformat": 4, "nbformat_minor": 5 }