
上次笔记,完成了第十七章的前两节内容。
继续学习第十七章Numpy关于线性代数的向量运算部分。
--
17.3 向量运算
(1)几何角度看向量
二维空间中可以用向量a表示一个有序的数对;向量a也可以用有向线段来表示,其中a1可以表示水平方向的投影,a2可以表示垂直方向的投影。
向量更可以用在三维空间的投影表示,见下图:

下面用代码17.3来表示如何使用Numpy计算向量模,以及单位向量:
# 代码17.3 计算向量模和单位向量# 向量模(L2范数)# 向量模的计算,相当于用.norm()这个工具作为单位,测量每个row_x的值norm_x_row_1 = np.linalg.norm(x_row_1)norm_x_row_2 = np.linalg.norm(x_row_2)norm_x_row_51 = np.linalg.norm(x_row_51)norm_x_row_101 = np.linalg.norm(x_row_101)norm_x_row_1# 计算单位向量# 单位向量的计算,相当于把不同的row等比例缩放,# 这样就方便进行统一的衡量和比较unit_x_row_1 = x_row_1 / norm_x_row_1unit_x_row_2 = x_row_2 / norm_x_row_2unit_x_row_51 = x_row_51 / norm_x_row_51unit_x_row_101 = x_row_101 / norm_x_row_101unit_x_row_1
运行结果:

由这段代码引申出的Numpy线性代数应用场景,以及它的意义:



(2)向量内积
1. 首先,求助AI:什么是向量内积?

2. 按照书本介绍,向量内积可以用np.dot()代入参数进行求解。

3. AI阐释这段使用Numpy求向量内积的代码意义:

4. 向量内积的其他应用:


(3)向量夹角
按照书本上的距离,x1、x2的夹角为3°,x1、x51的夹角为22°,x1、x101的夹角为31°。其实这就代表了1、2这两朵鸢尾花,都与51、101这些鸢尾花属于植物学中不同的“属”,因此夹角也会不一样。这就是向量夹角在机器学习中的一个应用
下面这段代码呈现了Numpy如何计算向量夹角:
# 代码17.4 计算向量夹角# 首先:要计算单位向量内积dot_product_1_51 = np.dot(unit_x_row_1[0],unit_x_row_51[0])# 第二步:将结果转化为弧度angle_1_51 = np.arccos(dot_product_1_51)# 第三步:将结果转化为角度angle_1_51 = np.rad2deg(angle_1_51)angle_1_51
运行结果:

(4)向量化运算(vectorization)和格拉姆矩阵(Gram matrix)
书中接下来介绍了这两个知识点。但太难了,我看不懂T T

因此通过以下步骤来了解:
1. 让AI帮忙解释:这两者是用于高效计算的重要工具:

2. 好了,知道了是什么之后,它们两个有什么用?


3. 利用下面的代码简单了解如何用Numpy进行向量化运算➕格拉姆矩阵
# 计算格拉姆矩阵G = X.T @ Xfig,axs = plt.subplots(1,5,figsize = (8,3),gridspec_kw={'width_ratios': [3, 0.5, 3, 0.5, 3]})# 这段代码使用Matplotlib库绘制了一个包含5个子图的图形窗口,# 每个子图的宽度比例分别为3:0.5:3:0.5:3。# 其中,plt.subplots(1,5)表示创建一个包含1行5列子图的Figure对象,# 并返回一个包含5个AxesSubplot对象的数组axs。# 参数figsize=(8,3)指定了整个图形窗口的大小为8英寸×3英寸,# gridspec_kw={'width_ratios': [3, 0.5, 3, 0.5, 3]}表示使用GridSpec布局,# 将子图宽度的比例分别设为3:0.5:3:0.5:3。# 这样设置可以使得子图的大小和位置能够按照比例分配,并且在整个图形窗口中居中对齐。# 最后,将返回的Figure对象和AxesSubplot数组保存到变量fig和axs中,以便后续使用。plt.sca(axs[0])# sca的含义为Set the current Axes to ax# plt.sca(axs[0]) 是Matplotlib库中的一个函数,# 用于将当前的AxesSubplot对象设置为参数指定的对象。# 在这个例子中,axs是一个包含5个子图的AxesSubplot数组,# plt.sca(axs[0])表示将当前的AxesSubplot对象设置为数组中的第一个子图,即axs[0]。# 这样设置后,所有后续的绘图操作都将作用在这个子图上,# 直到下一次调用plt.sca()将当前对象切换为其他的AxesSubplot对象。# 绘制格拉姆矩阵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')
运行结果:

--
今天的笔记先写到这里,轻松学习,保持节奏~
坦白说我也只是简单对线性代数的应用有点了解,具体的数学原理还是懵,但我重点不在于学习数学,而是掌握“线性代数能在机器学习领域做些什么”。
--
笔记写于:2026年2月28日20:04:30
结束于:2026年2月28日20:49:32
用时:约35分钟
--