
上次笔记,完成了第十七章Numpy关于向量化运算的知识。
今天的学习内容,继续深入探索“向量运算”的知识点,不求学多,但求学深、学精细、学入脑。
--
温故知新:
⬆️视频强调:线性代数真的很有用;在学习这章内容时,遇到不懂的线性代数知识,可以稍微跳过,但对于人工智能,线性代数是无法越过的一道坎,作者非常建议我们及早掌握线性代数。
17.2 拆解矩阵
1. 核心代码:行向量的拆分(双括号),X[[ 1 - 1], :]

2. 单括号和双括号的数据结构区别:

3. 既然有行向量的提取,那么同样可以得到列向量的提取:都有双括号,把切片的位置改一改:X[ :, [ 1 - 1 ]] (也可以写成下面的形式,反正本质理解了就行)

-
提取列向量的话,和行向量不同。具体有什么不同呢?
以例子的鸢尾花数据为例,切一行,每一行有四个元素,相当于把面包打横切。
切一列,每一列有150个元素,相当于把面包打竖切,每个“片”都是长长长的一条(下图只是截取,实际上非常长的)。

--
继续温故知新:
17.3 向量运算(向量范数/模,单位向量,向量内积,向量夹角)
1. 从几何角度,再次看“向量”
上次笔记,我也利用过ai帮助理解,但因为只是简单问了ai,没有过脑子,所以转眼就忘记了😂。
这次,再次搬出“太奶奶”,让ai解释向量内积,以及它相关的术语:
①现实物体(花) → ②抽象为向量(特征列表)→ ③求模长知其大小 →④ 化为单位向量以聚焦纯方向/形状 → ⑤通过内积计算单位向量间的余弦相似度 → ⑥向量化批量生成所有相似度(格拉姆矩阵)。

进一步通俗解释向量:
心中有数,谓之向量:把事物拆成几个维度的数,有序地放一起,就是向量思维。
提纲挈领,谓之模长:不管细节多复杂,抓住主要矛盾,算个总长度,就知道大体量级。
去伪存真,谓之单位化:去掉大小规模的干扰,只留下最纯粹的方向本质,才好比“芯子”。
志同道合,谓之内积:方向越一致,内积值越高。是人是花,皆看“志趣”相投否。
批量作业,谓之向量化:一个一个是手艺,一批一批是工业。智慧在策略,力量在批量。

1️⃣向量范数/向量的模
1. 下面是求#向量模 (L2范数,相当于求三角形斜边),以及#单位向量 的代码:
# 代码17.3 计算向量的模,以及单位向量# 求向量的模(L2范数)(类似知道两个直角边,求斜边的长)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)print(norm_x_row_1)print(norm_x_row_2)print(norm_x_row_51)print(norm_x_row_101)# 求单位向量(单位向量就是用来)unit_x_row_1 = x_row_1 / norm_x_row_1unit_x_row_2 = x_row_1 / norm_x_row_2unit_x_row_51 = x_row_1 / norm_x_row_51unit_x_row_101 = x_row_1 / norm_x_row_101print(unit_x_row_1)print(unit_x_row_2)print(unit_x_row_51)print(unit_x_row_101)
2. 运行结果:

3. 求单位向量和向量模的意义:


2️⃣求向量内积:
1. 代码:
# 计算向量内积(inner product / scalar product / dot product)# 计算向量内积用numpy.dot()inner_prod_x_row_1_2 = np.dot( x_row_1[0], x_row_2[0])inner_prod_x_row_1_51 = np.dot( x_row_1[0], x_row_51[0])inner_prod_x_row_1_101 = np.dot( x_row_1[0], x_row_101[0])print(inner_prod_x_row_1_2)print(inner_prod_x_row_1_51)print(inner_prod_x_row_1_101)
2. 运行结果:

3. 向量内积结果的意义:




3️⃣求向量夹角:
1. 代码(示例)
dot_product_1_2 = np.dot(unit_x_row_1[0], unit_x_row_2[0])angle_1_2 = np.arccos(dot_product_1_2)#anglein radianangle_1_2 = np.rad2deg(angle_1_2)angle_1_2
2. 运行结果

3. 变式练习:求列夹角
(1)先理解行夹角和列夹角的区别:

(2)参考之前求行夹角的代码,一步步求列夹角:提取列向量(已有x_col_n),随后求(列)向量模、求(列)单位向量,再套用(列)夹角公式:

(3)完整代码如下:
X矩阵有四列,请大家分别计算列向量的模,列向量之间的夹角# 计算列向量的模(L2范数)norm_x_col_1 = np.linalg.norm(x_col_1)norm_x_col_2 = np.linalg.norm(x_col_2)norm_x_col_3 = np.linalg.norm(x_col_3)norm_x_col_4 = np.linalg.norm(x_col_4)# 计算列向量的单位向量unit_x_col_1 = x_col_1 / norm_x_col_1unit_x_col_2 = x_col_2 / norm_x_col_2unit_x_col_3 = x_col_3 / norm_x_col_3unit_x_col_4 = x_col_4 / norm_x_col_4# 计算列向量之间的内积# 注意:列向量是二维数组 (150, 1),需要展平或转置来计算点积inner_prod_col_1_2 = np.dot(x_col_1.flatten(), x_col_2.flatten())inner_prod_col_1_3 = np.dot(x_col_1.flatten(), x_col_3.flatten())inner_prod_col_1_4 = np.dot(x_col_1.flatten(), x_col_4.flatten())inner_prod_col_2_3 = np.dot(x_col_2.flatten(), x_col_3.flatten())inner_prod_col_2_4 = np.dot(x_col_2.flatten(), x_col_4.flatten())inner_prod_col_3_4 = np.dot(x_col_3.flatten(), x_col_4.flatten())# 计算列向量之间的夹角# 使用单位向量计算点积dot_product_col_1_2 = np.dot(unit_x_col_1.flatten(), unit_x_col_2.flatten())dot_product_col_1_3 = np.dot(unit_x_col_1.flatten(), unit_x_col_3.flatten())dot_product_col_1_4 = np.dot(unit_x_col_1.flatten(), unit_x_col_4.flatten())dot_product_col_2_3 = np.dot(unit_x_col_2.flatten(), unit_x_col_3.flatten())dot_product_col_2_4 = np.dot(unit_x_col_2.flatten(), unit_x_col_4.flatten())dot_product_col_3_4 = np.dot(unit_x_col_3.flatten(), unit_x_col_4.flatten())# 将点积限制在[-1, 1]范围内,防止数值误差导致arccos出错dot_product_col_1_2 = np.clip(dot_product_col_1_2, -1.0, 1.0)dot_product_col_1_3 = np.clip(dot_product_col_1_3, -1.0, 1.0)dot_product_col_1_4 = np.clip(dot_product_col_1_4, -1.0, 1.0)dot_product_col_2_3 = np.clip(dot_product_col_2_3, -1.0, 1.0)dot_product_col_2_4 = np.clip(dot_product_col_2_4, -1.0, 1.0)dot_product_col_3_4 = np.clip(dot_product_col_3_4, -1.0, 1.0)# 计算角度(弧度转角度)angle_col_1_2 = np.rad2deg(np.arccos(dot_product_col_1_2))angle_col_1_3 = np.rad2deg(np.arccos(dot_product_col_1_3))angle_col_1_4 = np.rad2deg(np.arccos(dot_product_col_1_4))angle_col_2_3 = np.rad2deg(np.arccos(dot_product_col_2_3))angle_col_2_4 = np.rad2deg(np.arccos(dot_product_col_2_4))angle_col_3_4 = np.rad2deg(np.arccos(dot_product_col_3_4))# 打印结果print(f"列向量1的模: {norm_x_col_1}")print(f"列向量2的模: {norm_x_col_2}")print(f"列向量3的模: {norm_x_col_3}")print(f"列向量4的模: {norm_x_col_4}")print()print(f"列向量1和2的夹角: {angle_col_1_2:.2f}度")print(f"列向量1和3的夹角: {angle_col_1_3:.2f}度")print(f"列向量1和4的夹角: {angle_col_1_4:.2f}度")print(f"列向量2和3的夹角: {angle_col_2_3:.2f}度")print(f"列向量2和4的夹角: {angle_col_2_4:.2f}度")print(f"列向量3和4的夹角: {angle_col_3_4:.2f}度")
重点:
1. 列向量用了“二维数组”来生成
2. 为了计算正确,需要用.flatten()把二维数组“压扁”成一维数组,就像把一卷画展开,计算起来就方便了。
(4)运行结果:

(5)报错过程修复和列向量夹角用处:



---
笔记写于:2026年4月1日18:02:53
结束于:2026年4月1日21:09:58
用时:约3小时(有中断)
--