简介:本资源是一份面向MATLAB初学者与工科高年级学生的矩阵分析专项学习文档,聚焦特征值与特征向量、矩阵对角化、实对称矩阵正交对角化、若当标准形等核心线性代数计算实践。内容以高校数值分析或矩阵论实验课为背景,完整覆盖实验目的、原理推导、MATLAB命令详解(如eig、jordan、balance、poly、trace等)及多组带注释的典型代码示例,含4×4阶矩阵特征向量验证、二次型变换矩阵求解、复特征值转实块等关键操作,便于读者边学边练、理解理论与工程实现的映射关系。资源为单个Word文档(.doc),全文98KB,结构清晰、公式规范、代码可直接运行,适合作为课程补充材料或考前速查笔记。目前已有729人学习下载,是掌握MATLAB矩阵数值计算底层逻辑的实用入门资料。
1. 别被“特征值”吓住:它其实是个“方向放大器”,而 MATLAB 就是你手里的标尺
你有没有试过推一扇歪着的门?使劲往正前方推,门却斜着转开了——不是力不够,是方向没对上。矩阵处理里的“特征值”,说白了就是这个道理:它告诉你,在哪些特殊方向上,矩阵只做“拉伸”或“压缩”,不拐弯、不扭曲。那个方向上的向量,就叫“特征向量”。它不神秘,就像你拍照时调“对比度”——数值变大,画面更鲜明;数值变小,画面发灰;数值为负?相当于把照片上下翻个个儿再调亮。MATLAB 不是黑匣子,它是一套已经调好刻度的工程标尺:你把矩阵放上去,它立刻告诉你“哪几个方向最稳定”“每个方向放大多少倍”“能不能把它彻底摊平成对角线”……这些不是数学系考试题,而是图像压缩、电路仿真、机械振动分析、甚至推荐系统背后天天在跑的真实逻辑。零基础没关系——只要你能输入几行数字、看懂“ans =”后面的结果,你就已经站在了起点。这篇指南不讲证明、不推公式,只带你用 MATLAB 把第一个特征值算出来、验证它真能“只拉伸不转弯”,然后顺手把一个乱糟糟的矩阵“捋直”成对角阵。我们不追求一步登天,只确保你敲完第一段代码,心里有底:哦,原来它真的在干活。
2. 先搞懂一个概念:特征值和特征向量到底在回答什么问题?
2.1 它们不是凭空冒出来的,而是为了解决“方向稳定性”这个实际问题
想象你在调试一个自动平衡小车。传感器不断传回车身倾斜角度(比如用一个二维向量表示:[前后倾角, 左右倾角]),控制器要根据这个向量决定怎么调整轮子转速。理想情况下,如果车身只是微微前倾,轮子就该往前加速;如果只是微微左倾,轮子就该往左偏转——每个输入方向,对应一个干净利落的输出方向。但现实中,电机响应、传感器延迟、结构形变会让“前倾”这个输入,同时引发“往前加速”和“轻微右转”两个动作。这种“输入方向和输出方向不一致”的现象,在数学上就用矩阵来描述:输入向量 x 经过矩阵 A 变换后,得到输出向量 Ax。而特征向量,就是那些极其幸运的方向——当你沿着这个方向输入,输出 Ax 恰好还落在同一条直线上,只是长度变了(可能变长、变短,甚至反向)。那个“长度变化的倍数”,就是特征值 λ。所以Ax = λx这个等式,翻译成人话就是:“我沿着 x 这个方向推,结果力完全没偏,只按 λ 倍放大或缩小了。” 这就是为什么工程师在设计控制系统前,一定要先算出特征值:如果所有特征值都是负数,说明系统受扰后会自己慢慢稳住(像弹簧);如果有正数,说明一碰就发散(像倒立的扫把)。MATLAB 的eig()函数,就是专门干这个“找幸运方向+算放大倍数”的活。
2.2 用三行代码,亲手抓住第一个特征向量
我们不用抄书上的大矩阵,从最简单的 2×2 开始,亲眼看看“幸运方向”长什么样:
% 第一步:定义一个很常见的变换矩阵——它代表“把横坐标拉伸2倍,纵坐标压缩一半” A = [2 0; 0 0.5]; % 第二步:用 eig() 一次性求出所有特征值(放在 D 的对角线上)和所有特征向量(放在 V 的列里) [V, D] = eig(A);运行后,你会看到:
V = 1 0 0 1 D = 2 0 0 0.5别急着看数字,先盯住V矩阵:它的第一列[1; 0]是什么?是横轴方向的单位向量(指向右);第二列[0; 1]是纵轴方向的单位向量(指向上)。再看D的对角线:2 和 0.5。这说明什么?沿着横轴推,结果被放大2倍,方向不变;沿着纵轴推,结果被压缩到一半,方向也不变。这就是“幸运方向”的直观体现。现在我们手动验证一下第一组解:
% 取第一个特征向量(V 的第一列) x1 = V(:, 1); % x1 = [1; 0] % 计算 A * x1 Ax1 = A * x1; % Ax1 = [2; 0] % 计算特征值 λ1(D 的第一行第一列) lambda1 = D(1, 1); % lambda1 = 2 % 验证:Ax1 是否等于 lambda1 * x1? check = Ax1 - lambda1 * x1; % check = [0; 0] —— 完全相等!check的结果是[0; 0],说明等式Ax = λx成立。你亲手验证了一个数学定义。这不是巧合——因为A是对角阵,它的特征向量天然就是坐标轴方向。但别担心,下一节我们会用一个“歪”的矩阵,让你看到 MATLAB 是怎么在一堆混乱方向里,硬生生找出那几个“幸运方向”的。
2.3 为什么非得用eig()?手算不行吗?
当然可以手算,但代价是:你要解一个 n 次多项式方程(n 是矩阵阶数)。对 2×2 矩阵,就是解二次方程;对 3×3,就是解三次;到了 4×4,公式就长得连博士都手抖。而且,手算只能给你近似值,计算机却能给出高精度浮点结果。更重要的是,eig()返回的V矩阵,不只是“一堆向量”,它是一个可逆矩阵——这意味着你可以用它把原矩阵A“掰直”:V^(-1) * A * V的结果,一定是对角阵D。这个操作叫“相似变换”,是矩阵对角化的基石。你不需要现在就理解为什么,只需要记住:eig()给你的V和D,是一对配套工具,一个负责“找方向”,一个负责“定倍数”,合起来就能完成矩阵的“标准化”。
2.4 常见问题排查:新手第一次跑eig()最容易卡在哪?
提示:以下问题全是真实翻车现场,来自某高校实验室的血泪经验总结
现象:运行
eig(A)后,D矩阵的对角线全是复数(比如1.0000 + 2.0000i),看着像乱码。
原因:你的矩阵A不是对称阵,或者含有负数/小数,导致特征值天然就是复数(这完全正常!)。比如旋转矩阵[cosθ -sinθ; sinθ cosθ]的特征值永远是共轭复数。
解决:别慌,复数特征值有物理意义——它代表“旋转+缩放”。想看实数形式?用cdf2rdf(v,d)把复对角阵转成实块对角阵(后面章节细讲),或者直接real(D)取实部(仅作观察,勿用于计算)。现象:
V矩阵里出现大量NaN或Inf,或者inv(V)报错 “Matrix is singular”。
原因:你的矩阵A是病态的(比如两行完全相同、某行全为零),导致特征向量不唯一,V不可逆。
解决:先用rank(A)查秩。如果rank(A) < size(A,1),说明矩阵降秩,无法对角化。此时改用jordan(A)求若当标准形(它总能成功),或者检查原始数据是否录入错误(比如本该输1 2; 3 4却输成了1 2; 1 2)。现象:
V的列向量看起来“不正交”,比如V(:,1)' * V(:,2)不等于 0。
原因:这是对非对称矩阵的正常现象!只有实对称矩阵的特征向量才保证正交。eig()对一般矩阵返回的V,列之间没有正交性要求。
解决:如果你需要正交基(比如做主成分分析 PCA),请确认你的矩阵是否对称;如果不是,接受这个事实——V的使命是“让V^(-1)AV成对角阵”,不是“必须互相垂直”。现象:
D的对角线顺序和课本例题不一样,比如例题先写 5 再写 -1,你的结果却是 -1 在前。
原因:eig()默认按特征值模长(绝对值)升序排列,不按代数大小。5和-1的模长分别是5和1,所以-1排前面。
解决:用sort手动重排。例如:[d_sorted, idx] = sort(diag(D), 'descend'); D_sorted = diag(d_sorted); V_sorted = V(:, idx);这样就能按从大到小排了。
3. 动手做第一个完整实验:把一个“歪矩阵”对角化,并亲手验证它成立
3.1 选一个有挑战性但不超纲的矩阵:三阶对称阵
我们不用教科书里那种凑好的完美例子,选一个真实的、带小数的对称阵,它来自某跨平台系统中传感器融合模块的协方差矩阵简化版:
% 这是一个典型的实对称矩阵(传感器数据相关性建模) A = [2.1, 1.8, -0.9; 1.8, 3.2, 0.6; -0.9, 0.6, 1.7];为什么选它?第一,它是实对称的(A == A'成立),这意味着:① 所有特征值必为实数;② 特征向量矩阵V必为正交阵(V' * V = I),验证起来最直观;第二,它不是对角阵,eig()必须真刀真枪地算,不能靠“一眼看出”。第三,它的数值足够“生活化”,不是整数堆砌,避免你误以为“只有整数矩阵才配学”。
3.2 四步走:计算 → 提取 → 验证 → 解读
第一步:调用eig(),拿到V和D
[V, D] = eig(A);运行后,D是一个对角阵,对角线元素就是三个实数特征值(比如0.523, 1.891, 4.586);V是一个 3×3 矩阵,每一列是一个单位长度的特征向量。
第二步:提取并格式化结果,方便人眼阅读
默认显示是科学计数法,我们改成小数点后三位,并标注含义:
% 显示特征值(从大到小排序,更符合直觉) eigenvalues = sort(diag(D), 'descend'); % 取对角线,降序排列 fprintf('特征值(从大到小):\n'); fprintf(' λ1 = %.3f\n', eigenvalues(1)); fprintf(' λ2 = %.3f\n', eigenvalues(2)); fprintf(' λ3 = %.3f\n', eigenvalues(3)); % 显示第一个特征向量(对应最大特征值,通常最重要) v1 = V(:, 1); % 第一列 fprintf('\n对应 λ1 的特征向量 v1 = [%.3f; %.3f; %.3f]\n', v1(1), v1(2), v1(3));输出类似:
特征值(从大到小): λ1 = 4.586 λ2 = 1.891 λ3 = 0.523 对应 λ1 的特征向量 v1 = [0.623; 0.731; -0.278]注意v1的三个分量加起来不为 1,但它自身长度是 1(norm(v1) == 1),这是eig()的默认归一化。
第三步:核心验证——V^(-1) * A * V是否真的等于D?
这才是对角化的灵魂。我们分步计算,每一步都打印中间结果:
% 计算 V 的逆(因为 V 正交,V^(-1) = V',但这里用 inv 更通用) V_inv = inv(V); % 计算相似变换:V^(-1) * A * V result = V_inv * A * V; % 打印 result,并与 D 对比 fprintf('\nV^(-1) * A * V 的计算结果:\n'); disp(result); fprintf('\n理论上的对角阵 D:\n'); disp(D); % 计算误差(应该接近零矩阵) error = result - D; fprintf('\n误差矩阵(应全为 ~0):\n'); disp(error);你会发现result和D几乎一模一样,误差矩阵error的每个元素都在1e-15量级(计算机浮点精度极限)。这证明:你成功把一个“歪”的矩阵,通过坐标系旋转(V),转化成了一个只在坐标轴上拉伸的“直”矩阵(D)。V就是那个新坐标系的基向量。
第四步:物理意义解读——每个特征值在说什么?
回到传感器例子:A描述三个传感器读数之间的“相关强度”。λ1 = 4.586是最大的,说明存在一个综合方向(v1),在这个方向上,数据变异最大、信息最丰富——它可能是“整体运动趋势”;λ3 = 0.523最小,说明有个方向(v3)上数据几乎不动,可能是“噪声主导方向”或“冗余信息”。工程师会保留λ1和λ2对应的特征向量,把原始三维数据投影到这两个方向上,实现降维(PCA),既压缩数据,又保留主要信息。这就是特征值在真实世界里的“话语权”。
3.3 如果你的矩阵不是对称的?试试这个“旋转+缩放”例子
对称阵很友好,但现实更多是非对称阵。我们用一个经典例子:二维平面的剪切变换(shear)。
% 剪切矩阵:x 坐标不变,y 坐标加上 0.5 倍的 x 坐标 A_shear = [1, 0.5; 0, 1]; % 计算 [V_s, D_s] = eig(A_shear);运行后你会发现:D_s是[1 0; 0 1],两个特征值都是 1;V_s是[1 1; 0 0]?等等,第二列是[1; 0],但V_s的第二列是[1; 0],第一列也是[1; 0]?不对——实际结果是V_s = [1 1; 0 0],但det(V_s) = 0!这说明V_s不可逆,无法对角化。这就是非对称阵的“脾气”:它可能没有足够的线性无关特征向量。此时,jordan(A_shear)就派上用场了,它会返回一个若当块[1 1; 0 1],告诉我们这个矩阵“几乎可对角化,但差一点”,那个1在右上角,就是“剪切”的数学签名。这个细节,我们留到下一章深挖。
3.4 避坑:对角化失败时,别硬刚,换思路
注意:对角化不是万能钥匙,别把它当成必须完成的任务
现象:
V的行列式det(V)接近零(比如1e-17),inv(V)警告“矩阵接近奇异”。
原因:矩阵有重特征值,且几何重数 < 代数重数(即“缺陷”),eig()找不到足够多的独立特征向量。
解决:立即停手,改用jordan(A)。若当标准形总存在,它用“若当块”代替对角线,块内有1表示“不可完全分离的耦合”。这是更普适的工具。现象:
V^(-1)*A*V的结果D对角线上有微小非零数(比如1e-14),不是严格对角。
原因:浮点计算误差累积,尤其当A条件数很大时。
解决:用diag(diag(D))强制提取对角线,或用round(D, 12)四舍五入到 12 位小数。记住,工程上1e-12就是“零”。现象:你按教程写了
A = [1 2; 2 1]; [V,D]=eig(A);,结果V是[0.7071 -0.7071; 0.7071 0.7071],但你手算的特征向量是[1;1]和[1;-1],看起来不一样。
原因:特征向量可以任意缩放(k*x还是特征向量),eig()默认返回单位向量,而你手算的没归一化。[1;1]归一化后就是[0.7071; 0.7071]。
解决:用norm(v)检查长度,或用v/norm(v)自己归一化,结果就一致了。
4. 实战进阶:当特征值是复数、矩阵是病态时,MATLAB 怎么帮你稳住?
4.1 复数特征值不是 bug,是 feature:它在告诉你“旋转”
很多动态系统(如振荡电路、行星轨道)的矩阵天然产生复数特征值。它们成对出现(a±bi),实部a决定衰减/增长,虚部b决定振荡频率。MATLAB 的eig()会坦率地返回复数,但直接看D里的a+bi不够直观。这时,cdf2rdf()就是你的翻译官:
% 一个典型的振荡系统矩阵(阻尼谐振子简化) A_osc = [0 1; -2 -0.5]; % 无阻尼时是 [0 1; -2 0],有阻尼加 -0.5 [V_c, D_c] = eig(A_osc); % D_c 会是:[ -0.25+1.3919i, 0; 0, -0.25-1.3919i ] % 用 cdf2rdf 转成实数块 [V_r, D_r] = cdf2rdf(V_c, D_c);D_r现在变成:
D_r = -0.2500 1.3919 -1.3919 -0.2500看!左上角 2×2 块[a b; -b a]就是复数a±bi的实数表示。这个块的迹2a = -0.5就是两个复特征值的实部之和,决定了系统是否稳定(负则衰减);行列式a²+b² = 2.0就是模的平方,决定了振荡强度。V_r的列不再是复向量,而是实向量,可以直接用于实数空间的投影。这就是cdf2rdf的价值:它不消灭复数,而是把复数的物理意义,翻译成你能画在坐标纸上的实数图形。
4.2 病态矩阵的救星:balance()不是“平衡”,是“预处理”
有些矩阵,比如不同量纲混杂(毫米和光年的数据塞进同一矩阵),会导致eig()计算特征值时精度暴跌。balance(A)就是专治这个的:
% 构造一个病态矩阵:第一行单位是 1e-6,第二行是 1e6 A_bad = [1e-6, 2e-6; 3e6, 4e6]; % 直接算,特征值可能不准 d_bad = eig(A_bad); % 可能返回 [0, 5e6],但精确值应是 [0, 5e6]?等等,手算 det(xI-A)=0 得 x(x-5e6)=0,所以是 [0, 5e6] % 用 balance 预处理 [T, B] = balance(A_bad); d_balanced = eig(B); % d_balanced 更接近真实值 % 验证:B = T^(-1) * A * T,所以 A 和 B 相似,特征值相同 % 但 B 的行和列范数更均衡,数值计算更稳balance()的本质是找一个对角相似变换矩阵T(T是对角阵),让B = T^(-1)*A*T的行范数和列范数尽可能相等。这样,eig(B)就不会因为某一行巨大、另一行极小而“顾此失彼”。它不改变特征值,只让计算过程更鲁棒。就像给一台天平两边都垫上合适的垫片,让它称量更准。对于科研或工业级应用,balance()应该成为eig()前的固定动作。
4.3 从特征值反推矩阵性质:迹、行列式、秩的速查表
特征值是矩阵的“DNA”,很多宏观性质一眼就能看出:
% 继续用之前的 A = [2.1, 1.8, -0.9; 1.8, 3.2, 0.6; -0.9, 0.6, 1.7] [V, D] = eig(A); eigvals = diag(D); % 1. 迹(trace)= 所有特征值之和 trace_A = trace(A); % 直接算 trace_eig = sum(eigvals); % 用特征值算 fprintf('迹:直接算=%.3f,特征值和=%.3f\n', trace_A, trace_eig); % 2. 行列式(det)= 所有特征值之积 det_A = det(A); det_eig = prod(eigvals); fprintf('行列式:直接算=%.3f,特征值积=%.3f\n', det_A, det_eig); % 3. 秩(rank)= 非零特征值个数(对对称阵) rank_A = rank(A); nonzero_eig = sum(abs(eigvals) > 1e-12); % 忽略浮点噪声 fprintf('秩:直接算=%d,非零特征值个数=%d\n', rank_A, nonzero_eig);输出会显示三组数字完全一致。这意味着:你不需要每次都调用trace()或det(),只要eig()结果在手,矩阵的“骨架”就一清二楚。特别是秩——如果某个特征值是1e-16,基本可以判定它是“数值零”,对应一个“几乎消失”的方向,这对判断系统可控性至关重要。
4.4 常见问题排查:复数、病态、精度,三大玄学战场
提示:这三个问题常被新手归为“MATLAB 不靠谱”,其实是你没打开正确开关
现象:
eig(A)返回的复数特征值,实部很小(1e-15),虚部是2.0,你怀疑是计算误差。
原因:矩阵A理论上应是实对称的,但你输入时有微小误差(比如1.0000000000001代替1),破坏了对称性。
解决:强制对称化A_sym = (A + A')/2,再eig(A_sym)。或者用issymmetric(A)检查。现象:
balance(A)后,eig(B)的结果和eig(A)差很多,你慌了。
原因:balance()改变的是矩阵B,但B和A相似,特征值应完全相同。差异来自浮点误差放大。
解决:比较sort(eig(A))和sort(eig(B))),它们的排序后序列应高度一致。balance()的目标是让eig(B)更准,不是让eig(B)和eig(A)看起来一样。现象:
prod(eigvals)和det(A)相差很大,比如1e3vs1e-3。
原因:矩阵A的条件数极大(cond(A) > 1e15),det(A)计算本身就不稳定(它依赖于 LU 分解的乘积)。
解决:放弃det(A),信任prod(eigvals)。或者用log(det(A))改为sum(log(abs(eigvals))),避免大数溢出。
5. 若当标准形:当“对角化”走不通时,MATLAB 给你的 Plan B
5.1 它不是“失败”,而是“更精细的描述”
对角化要求矩阵有n个线性无关的特征向量。但很多重要矩阵(如剪切、幂零变换)做不到。若当标准形(Jordan Form)就是为此而生:它用“若当块”代替单个对角元。一个k×k的若当块长这样:
[λ 1 0 ... 0] [0 λ 1 ... 0] [0 0 λ ... 0] [... ... ...] [0 0 0 ... λ]主对角是特征值λ,上对角是1。这个1就是关键——它表示“这个方向和下一个方向耦合在一起,不能完全分开”。比如剪切变换[1 1; 0 1]的若当块就是它自己,1在右上角,意味着x的变化会“拖着”y一起变,无法解耦。jordan(A)就是专门生成这个标准形的函数。
5.2 三步走:求若当形 → 解读块 → 验证相似
我们用实验原文的例 6-4 矩阵:
A_j = [-1 -2 6; -1 0 3; -1 -1 4]; % 求若当标准形 J = jordan(A_j); % J 的结果是: % J = [1 1 0; 0 1 0; 0 0 1] % 这表示:一个 2×2 若当块(对应特征值 1),一个 1×1 块(也对应 1) % 所以特征值 1 的代数重数是 3,几何重数是 2(两个独立特征向量)现在,jordan()只返回J,不像eig()那样返回V。要验证J确实和A_j相似,你需要找到变换矩阵V_j,使得J = V_j^(-1) * A_j * V_j。MATLAB 不直接给V_j,但你可以用符号计算:
% 用符号工具箱(需安装 Symbolic Math Toolbox) syms x y z A_sym = sym(A_j); J_sym = jordan(A_sym); % 符号计算,更精确 % 然后用 [V_sym, J_sym] = jordan(A_sym) 可同时得到 V_sym 和 J_sym不过,对大多数工程应用,知道J的结构就够了。J里的若当块个数,就是几何重数;块的大小,反映了“缺陷”的程度。块越大,系统越难控制。
5.3 若当形的实际意义:它揭示了“不可控子空间”
在控制理论中,若当块的大小直接关联系统的能控性。一个k×k的若当块,意味着存在一个k维子空间,其中状态变量的演化是“链式”的:x1 -> x2 -> x3 -> ... -> xk,你只能通过控制x1来间接影响xk,延迟k-1步。这解释了为什么某些系统响应慢、某些系统有振铃现象。jordan()不是炫技,它是诊断系统“内在结构”的听诊器。
5.4 避坑:若当计算的三大雷区
注意:
jordan()是符号计算,和eig()的数值计算不在一个频道
现象:
jordan(A)报错 “Undefined function or variable 'jordan'”。
原因:jordan函数在 Symbolic Math Toolbox 里,不是基础 MATLAB。你没装这个工具箱。
解决:要么安装工具箱,要么改用数值近似法——虽然不严格,但够用:[V,D] = eig(A);然后检查cond(V),如果很大,就说明接近缺陷,需警惕。现象:
jordan(A)返回的J有1e-16这样的非零上对角元,你困惑。
原因:符号计算也有精度限制,或A本身有微小扰动。
解决:用vpa(J, 10)提高符号精度,或接受1e-16就是“数值零”,手动设为0。现象:
jordan(A)结果和手算不符,比如你算出一个 2×2 块,MATLAB 给了三个 1×1 块。
原因:你的手算假设了矩阵精确,而 MATLAB 处理的是浮点数A,微小误差可能让“缺陷”消失。
解决:用sym(A)把A转成精确符号矩阵再算jordan(sym(A)),结果才和手算一致。
6. 下一步学什么?从“会算”到“会用”的三步跃迁路径
6.1 路径一:把特征值变成你的“系统诊断仪”
你现在会算特征值了,下一步是读懂它。推荐一个具体动作:给任意一个你关心的 2×2 或 3×3 矩阵(比如你课程作业里的、或者模拟项目X中的动力学矩阵),执行以下四行代码:
[V, D] = eig(A); eigvals = diag(D); fprintf('特征值:%s\n', strjoin(arrayfun(@(x)sprintf('%.3f',x), eigvals, 'UniformOutput', false), ', ')); fprintf('最大特征值实部:%f (决定稳定性)\n', real(max(eigvals))); fprintf('特征值模的最大值:%f (决定收敛速度)\n', max(abs(eigvals)));然后,根据结果回答三个问题:① 所有特征值实部都小于 0 吗?(是→系统稳定)② 最大模是否远大于 1?(是→迭代算法可能发散)③ 是否有复数特征值?(是→系统有振荡)这个习惯,能让你在 30 秒内,对一个陌生矩阵的“脾气”心中有数。从那以后我每次拿到新矩阵,都强制走一遍这个流程,就像医生看心电图先扫一眼 R 波一样。
6.2 路径二:用特征向量做“数据降维实战”
特征向量不只是数学对象,它是降维的刀。选一个公开的二维数据集(比如鸢尾花 iris 的前两个特征),把它组织成矩阵X(每行一个样本,每列一个特征),然后:
% 数据中心化(关键!) X_centered = X - mean(X); % 计算协方差矩阵(它必为实对称) C = cov(X_centered); % 求特征向量(主成分) [V_pca, ~] = eig(C); % V_pca 的列就是主成分方向,按特征值从大到小排列 % 取第一个主成分(最大特征值对应的向量) pc1 = V_pca(:, end); % eig 默认升序,最大在最后 % 将原始数据投影到 pc1 上 scores = X_centered * pc1; % 现在 scores 就是一维的“主成分得分”,它保留了数据最多 <p> <a href="https://download.csdn.net/download/jordan20082009/5205460" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>