当前位置:首页>python>我的Python100天打卡:65/100 掰开揉碎去理解格拉姆矩阵 | 矩阵运算

我的Python100天打卡:65/100 掰开揉碎去理解格拉姆矩阵 | 矩阵运算

  • 2026-09-02 19:09:03
我的Python100天打卡:65/100 掰开揉碎去理解格拉姆矩阵 | 矩阵运算

#鸢尾花数学大系

挑战100天持续练习Python
今天是第65天
---

上次笔记,复习了第十七章Numpy线性代数关于矩阵行/列向量拆解的方法;复习了向量运算,包括求向量的模linalg.norm()、单位向量、向量内积np.dot()、向量夹角弧度np.arccos(),角度np.rad2deg(),以及将二维向量“压扁”的方法np.dot(flatten())。

本次笔记将包括以下内容:

17.3 向量化运算、格拉姆矩阵(掰开揉碎详细版)

17.4 矩阵运算

---

今天笔记,从一之前有写笔记,但我还没认真展开思考的题开始:

【如果需要计算鸢尾花数据矩阵X,所有行向量之间的两两夹角,又要避免使用for循环,该怎么办?】

可以通过下图的“夹角角度矩阵”来求解。

需要注意的是:左边的矩形矩阵和右边“三角矩阵”实现的功能是完全相同的。右边只是将一些重复的矩阵计算空间省去而已。

但即使只做右边三角矩阵的运算,仍是很大计算量的工程。

如何才能更加快捷的去进行计算呢?就涉及到下面的“向量化运算”思想,以及重要的工具“格拉姆矩阵”了。

--

17.3 向量化运算、格拉姆矩阵(掰开揉碎详细版)

0. 先给出视频链接,以免后面我自己复习的时候找不到:

【Chapter 17 NumPy线性代数  | 49:09】

 https://www.bilibili.com/video/BV1VD421L7Hf/

1. 格拉姆矩阵的本质,还是向量化运算。向量化运算的关键,还是矩阵乘法。(所以我前后几条笔记,都在反反复复记录,绕不过去,本质上就是不理解这三者的关系,有点纠缠,现在把它们的层次关系理清,就清爽多了)

2. 书本提到的关系:矩阵乘法->格拉姆矩阵

作者就很形象,用“啪的一声”把两个表的相乘的动作表现出来了。

学术化一点表述,格拉姆矩阵是这样写的(G = X的T次方 · X):

(书本作者也说到,实际上本书写到这里,能理解以上意思即可。)

3. 格拉姆矩阵的代码(简略版,只保留核心要素)(详细版的见书本/视频/chapter17文档/上两条笔记)

# 计算格拉姆矩阵G = X.T @ Xfig,axs = plt.subplots(1,5,figsize = (8,3),                        gridspec_kw={'width_ratios': [3, 0.5, 3, 0.5, 3]})plt.sca(axs[0])ax = sns.heatmap(G, cmap = 'RdYlBu_r',                 vmax = 5000, vmin = 0,                 annot = False,                 fmt=".0f",                 cbar_kws = {'orientation':'horizontal'},                 xticklabels = False,                 yticklabels=False,                 square = 'equal')plt.title('$G$')plt.sca(axs[1])plt.title('=')plt.axis('off')# 绘制X转置plt.sca(axs[2])ax = sns.heatmap(X.T, cmap = 'RdYlBu_r',                 vmax = 0, vmin = 8,                 cbar_kws = {'orientation':'horizontal'},                 xticklabels = False,                 yticklabels = False,                 annot=False)plt.title('$X^T$')plt.sca(axs[3])plt.title('@')plt.axis('off')    # 绘制Xplt.sca(axs[4])ax = sns.heatmap(X, cmap = 'RdYlBu_r',                 vmax = 0, vmin = 8,                 cbar_kws = {'orientation':'horizontal'},                 xticklabels = False,                 yticklabels=False,                 annot=False)plt.title('$X$')fig.savefig('Figures/X的格拉姆矩阵.svg', format='svg')

3.1运行结果:

4. 其实还可以有第二个格拉姆矩阵(它们互为“伪逆”或“投影”关系),可以理解为:

4.1 专业描述为:(H = X · X的T次方 )(刚好和G的因数调换)

4.2 第二个格拉姆矩阵的代码(简化版):

# 第二个格拉姆矩阵H = X @ X.Tfig,axs = plt.subplots(1,5,figsize = (8,3),                        gridspec_kw={'width_ratios': [3, 0.5, 3, 0.5, 3]})plt.sca(axs[0])# 绘制格拉姆矩阵ax = sns.heatmap(H, cmap = 'RdYlBu_r',                 vmin = 0,                  vmax = 150,                 annot = False,                 fmt=".0f",                 cbar_kws = {'orientation':'horizontal'},                 xticklabels = False,                 yticklabels=False,                 square = 'equal')plt.title('$H$')plt.sca(axs[1])plt.title('=')plt.axis('off')# 绘制X转置plt.sca(axs[2])ax = sns.heatmap(X, cmap = 'RdYlBu_r',                 vmax = 0, vmin = 8,                 cbar_kws = {'orientation':'horizontal'},                 xticklabels = False,                 yticklabels = False,                 annot=False)plt.title('$X$')plt.sca(axs[3])plt.title('@')plt.axis('off')    # 绘制Xplt.sca(axs[4])ax = sns.heatmap(X.T, cmap = 'RdYlBu_r',                 vmax = 0, vmin = 8,                 cbar_kws = {'orientation':'horizontal'},                 xticklabels = False,                 yticklabels=False,                 annot=False)plt.title('$X^T$')fig.savefig('Figures/XT的格拉姆矩阵.svg', format='svg')

4.3 运行结果:

5. 矩阵的逆

其实有了前面格拉姆矩阵的铺垫,矩阵的逆也很好理解了:

更像是一种“可逆转”的矩阵,在某个方向上“拧一下”,拧为不同的方向,又从正相反的方向“拧回去”,诶,您猜怎么着,居然变回原来的矩阵了!

原本作者的比喻是“啪的一下拍扁”,ai认为不够严谨,因为“拍扁”意味着维度降低(不可逆),而“拧”意味着形变但保持维度(可逆)。

5.1 矩阵的逆的代码

# 计算格拉姆矩阵G的逆矩阵G_inv = np.linalg.inv(G)fig,axs = plt.subplots(1,5,figsize = (8,3),                        gridspec_kw={'width_ratios': [3, 0.5, 3, 0.5, 3]})plt.sca(axs[0])# 绘制格拉姆矩阵ax = sns.heatmap(np.eye(4), cmap = 'RdYlBu_r',                 annot = False,                 fmt=".0f",                 cbar_kws = {'orientation':'horizontal'},                 xticklabels = False,                 yticklabels=False,                 square = 'equal')plt.title('$I$')plt.sca(axs[1])plt.title('=')plt.axis('off')plt.sca(axs[2])ax = sns.heatmap(G, cmap = 'RdYlBu_r',                 cbar_kws = {'orientation':'horizontal'},                 xticklabels = False,                 yticklabels = False,                 annot=False)plt.title('$G$')plt.sca(axs[3])plt.title('@')plt.axis('off')    # 绘制Xplt.sca(axs[4])ax = sns.heatmap(G_inv, cmap = 'RdYlBu_r',                 cbar_kws = {'orientation':'horizontal'},                 xticklabels = False,                 yticklabels=False,                 annot=False)plt.title('$G^{-1}$')fig.savefig('Figures/格拉姆矩阵的逆.svg', format='svg')

5.2 矩阵的逆的可视化:

---

笔记写于:2026年4月16日15:00:43

结束于:2026年4月16日16:01:43

用时:1小时

--

#鸢尾花数学大系

#编程随记

最新文章

随机文章