├── Book4_Ch00_正文前__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch01_Python_Codes └── Streamlit_Bk4_Ch01_01.py ├── Book4_Ch01_向量__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch02_Python_Codes ├── Bk4_Ch02_01.ipynb ├── Bk4_Ch02_02.ipynb ├── Bk4_Ch02_03.ipynb ├── Bk4_Ch02_04.ipynb ├── Bk4_Ch02_05.ipynb ├── Bk4_Ch02_06.ipynb ├── Bk4_Ch02_07.ipynb ├── Bk4_Ch02_08.ipynb ├── Bk4_Ch02_09.ipynb ├── Bk4_Ch02_10.ipynb ├── Bk4_Ch02_11.ipynb ├── Bk4_Ch02_12.ipynb ├── Bk4_Ch02_13.ipynb └── Streamlit_Bk4_Ch02_13.py ├── Book4_Ch02_向量运算__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch03_Python_Codes ├── Bk4_Ch03_01.ipynb ├── Bk4_Ch03_02.ipynb ├── Streamlit_Bk4_Ch03_01.py └── Streamlit_Bk4_Ch03_03.py ├── Book4_Ch03_向量范数__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch04_Python_Codes ├── Bk4_Ch04_01.ipynb ├── Bk4_Ch04_02.ipynb ├── Bk4_Ch04_03.ipynb ├── Bk4_Ch04_04.ipynb ├── Bk4_Ch04_05.ipynb ├── Bk4_Ch04_06.ipynb ├── Bk4_Ch04_07.ipynb ├── Bk4_Ch04_08.ipynb ├── Bk4_Ch04_09.ipynb ├── Bk4_Ch04_10.ipynb ├── Bk4_Ch04_11.ipynb ├── Bk4_Ch04_12.ipynb ├── Bk4_Ch04_13.ipynb ├── Bk4_Ch04_14.ipynb ├── Bk4_Ch04_15.ipynb └── Streamlit_Bk4_Ch04_16.py ├── Book4_Ch04_矩阵__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch05_Python_Codes └── Bk4_Ch05_01.ipynb ├── Book4_Ch05_矩阵乘法__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch06_Python_Codes ├── Bk4_Ch06_01.ipynb └── Bk4_Ch06_02.ipynb ├── Book4_Ch06_分块矩阵__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch07_Python_Codes ├── Streamlit_Bk4_Ch07_01.py └── Streamlit_Bk4_Ch07_02.py ├── Book4_Ch07_向量空间__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch08_Python_Codes ├── Bk4_Ch08_01.ipynb ├── Streamlit_Bk4_Ch08_02.py └── Streamlit_Bk4_Ch08_03.py ├── Book4_Ch08_几何变换__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch09_Python_Codes ├── Bk4_Ch09_01.ipynb └── Bk4_Ch09_02.ipynb ├── Book4_Ch09_正交投影__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch10_Python_Codes ├── Bk4_Ch10_01.ipynb └── Streamlit_Bk4_Ch10_01.py ├── Book4_Ch10_数据投影__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch11_Python_Codes ├── Bk4_Ch11_01.ipynb └── Bk4_Ch11_02.ipynb ├── Book4_Ch11_矩阵分解__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch12_Cholesky分解__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch12_Python_Codes └── Bk4_Ch12_01.ipynb ├── Book4_Ch13_Python_Codes ├── Bk4_Ch13_01.ipynb ├── Bk4_Ch13_02.ipynb ├── Bk4_Ch13_03.ipynb └── Streamlit_Bk4_Ch13_04.py ├── Book4_Ch13_特征值分解__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch14_Python_Codes ├── Bk4_Ch14_01.ipynb ├── Bk4_Ch14_02.ipynb ├── Streamlit_Bk4_Ch14_02.py └── Streamlit_Bk4_Ch14_03.py ├── Book4_Ch14_深入特征值分解__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch15_Python_Codes ├── Bk4_Ch15_01.ipynb └── Bk4_Ch15_02.ipynb ├── Book4_Ch15_奇异值分解__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch16_Python_Codes ├── Bk4_Ch16_01.ipynb └── Streamlit_Bk4_Ch16_01.py ├── Book4_Ch16_深入奇异值分解__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch17_Python_Codes ├── Bk4_Ch17_01.ipynb ├── Bk4_Ch17_02.ipynb └── Streamlit_Bk4_Ch17_01.py ├── Book4_Ch17_多元函数微分__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch18_拉格朗日乘子法__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch19_Python_Codes └── Bk4_Ch19_01.ipynb ├── Book4_Ch19_直线到超平面__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch20_Python_Codes ├── Bk4_Ch20_01.ipynb └── Streamlit_Bk4_Ch20_02.py ├── Book4_Ch20_再谈圆锥曲线__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch21_Python_Codes ├── Bk4_Ch21_01.ipynb ├── Bk4_Ch21_02.ipynb ├── Streamlit_Bk4_Ch21_02.py └── Streamlit_Bk4_Ch21_03.py ├── Book4_Ch21_曲面和正定性__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch22_Python_Codes └── Bk4_Ch22_01.ipynb ├── Book4_Ch22_数据与统计__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch23_数据空间__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch24_Python_Codes └── Bk4_Ch24_01.ipynb ├── Book4_Ch24_数据分解__矩阵力量__从加减乘除到机器学习.pdf ├── Book4_Ch25_数据应用__矩阵力量__从加减乘除到机器学习.pdf ├── README.md └── 鸢尾花书_整体布局.pdf /Book4_Ch00_正文前__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch00_正文前__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch01_Python_Codes/Streamlit_Bk4_Ch01_01.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | ## 导入必要的库 10 | import streamlit as st # 引入Streamlit库,用于创建交互式Web应用 11 | import plotly.express as px # 引入Plotly Express库,用于绘图 12 | 13 | ## 加载鸢尾花数据 14 | df = px.data.iris() # 使用Plotly自带的数据集加载鸢尾花数据 15 | 16 | features = df.columns.to_list()[:-2] # 获取数据集中特征列的名称(排除最后两列) 17 | with st.sidebar: # 创建侧边栏 18 | st.write('2D scatter plot') # 显示文本“2D散点图” 19 | x_feature = st.radio('Horizontal axis', # 创建单选按钮,选择X轴的特征 20 | features) # 单选按钮的选项为特征列名称 21 | y_feature = st.radio('Vertical axis', # 创建单选按钮,选择Y轴的特征 22 | features) # 单选按钮的选项为特征列名称 23 | 24 | ## 原始数据展示 25 | with st.expander('Original data'): # 创建可展开的部分,标题为“原始数据” 26 | st.write(df) # 显示数据框df的内容 27 | 28 | ## 热力图展示 29 | with st.expander('Heatmap'): # 创建可展开的部分,标题为“热力图” 30 | fig_1 = px.imshow(df.iloc[:, 0:4], # 使用前四列数据绘制热力图 31 | color_continuous_scale='RdYlBu_r') # 选择颜色映射为红黄蓝反转 32 | st.plotly_chart(fig_1) # 在Streamlit中显示热力图 33 | 34 | ## 二维散点图展示 35 | with st.expander('2D scatter plot'): # 创建可展开的部分,标题为“二维散点图” 36 | fig_2 = px.scatter(df, x=x_feature, y=y_feature, color="species") # 根据用户选择的特征绘制二维散点图,按种类着色 37 | st.plotly_chart(fig_2) # 在Streamlit中显示散点图 38 | 39 | ## 三维散点图展示 40 | with st.expander('3D scatter plot'): # 创建可展开的部分,标题为“三维散点图” 41 | fig_3 = px.scatter_3d(df, # 绘制三维散点图 42 | x='sepal_length', # X轴为花萼长度 43 | y='sepal_width', # Y轴为花萼宽度 44 | z='petal_width', # Z轴为花瓣宽度 45 | color='species') # 按种类着色 46 | st.plotly_chart(fig_3) # 在Streamlit中显示三维散点图 47 | 48 | ## 配对散点图展示 49 | with st.expander('Pairwise scatter plot'): # 创建可展开的部分,标题为“配对散点图” 50 | fig_4 = px.scatter_matrix(df, # 绘制配对散点图 51 | dimensions=["sepal_width", 52 | "sepal_length", 53 | "petal_width", 54 | "petal_length"], # 指定绘图的维度 55 | color="species") # 按种类着色 56 | st.plotly_chart(fig_4) # 在Streamlit中显示配对散点图 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Book4_Ch01_向量__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch01_向量__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch02_Python_Codes/Bk4_Ch02_02.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 02\n", 9 | "\n", 10 | "# L2范数\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "ab88dee3-1a2e-4357-b6b5-136abf3073c5", 17 | "metadata": {}, 18 | "source": [ 19 | "此代码定义了两个二维列向量 `a` 和 `b`,并计算它们的L2范数。L2范数也称为欧几里得范数,用于测量向量的长度。公式如下:\n", 20 | "\n", 21 | "$$\n", 22 | "\\| a \\|_2 = \\sqrt{a_1^2 + a_2^2}\n", 23 | "$$ \n", 24 | "\n", 25 | "对于向量 `a` 和 `b`,L2范数分别为:\n", 26 | "\n", 27 | "$$\n", 28 | "\\| a \\|_2 = \\sqrt{4^2 + 3^2} = 5\n", 29 | "$$\n", 30 | "\n", 31 | "$$\n", 32 | "\\| b \\|_2 = \\sqrt{(-3)^2 + 4^2} = 5\n", 33 | "$$" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "id": "2a36cd49-a4e6-4321-a7e8-7f9a34c6aaef", 39 | "metadata": {}, 40 | "source": [ 41 | "## 导入所需库" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 1, 47 | "id": "01a128eb-3998-4172-bd8a-ec95a23bbc83", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "import numpy as np # 导入NumPy库,用于数值计算" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "id": "8ad8b4b0-856b-47a7-adb8-b020180d0c30", 57 | "metadata": {}, 58 | "source": [ 59 | "## 定义两个列向量" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 2, 65 | "id": "212d3a51-f2c6-4785-8c9a-40fa93ae0566", 66 | "metadata": {}, 67 | "outputs": [ 68 | { 69 | "data": { 70 | "text/plain": [ 71 | "array([[4],\n", 72 | " [3]])" 73 | ] 74 | }, 75 | "execution_count": 2, 76 | "metadata": {}, 77 | "output_type": "execute_result" 78 | } 79 | ], 80 | "source": [ 81 | "a = np.array([[4], [3]]) # 定义向量a,值为[4, 3]\n", 82 | "a" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 3, 88 | "id": "8d5f6350-fddc-4633-946e-f21797b6f5e8", 89 | "metadata": {}, 90 | "outputs": [ 91 | { 92 | "data": { 93 | "text/plain": [ 94 | "array([[-3],\n", 95 | " [ 4]])" 96 | ] 97 | }, 98 | "execution_count": 3, 99 | "metadata": {}, 100 | "output_type": "execute_result" 101 | } 102 | ], 103 | "source": [ 104 | "b = np.array([[-3], [4]]) # 定义向量b,值为[-3, 4]\n", 105 | "b" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "id": "a3ba8142-26a8-43d6-b777-685207499ca9", 111 | "metadata": {}, 112 | "source": [ 113 | "## 计算L2范数" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 4, 119 | "id": "1954434f-cb3e-44d3-b985-45b73af8a815", 120 | "metadata": {}, 121 | "outputs": [ 122 | { 123 | "data": { 124 | "text/plain": [ 125 | "5.0" 126 | ] 127 | }, 128 | "execution_count": 4, 129 | "metadata": {}, 130 | "output_type": "execute_result" 131 | } 132 | ], 133 | "source": [ 134 | "a_L2_norm = np.linalg.norm(a) # 计算向量a的L2范数\n", 135 | "a_L2_norm" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 5, 141 | "id": "8110a0d6-c941-4825-bf60-bc989324f592", 142 | "metadata": {}, 143 | "outputs": [ 144 | { 145 | "data": { 146 | "text/plain": [ 147 | "5.0" 148 | ] 149 | }, 150 | "execution_count": 5, 151 | "metadata": {}, 152 | "output_type": "execute_result" 153 | } 154 | ], 155 | "source": [ 156 | "b_L2_norm = np.linalg.norm(b) # 计算向量b的L2范数\n", 157 | "b_L2_norm" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": null, 163 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": null, 171 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [] 175 | } 176 | ], 177 | "metadata": { 178 | "kernelspec": { 179 | "display_name": "Python 3 (ipykernel)", 180 | "language": "python", 181 | "name": "python3" 182 | }, 183 | "language_info": { 184 | "codemirror_mode": { 185 | "name": "ipython", 186 | "version": 3 187 | }, 188 | "file_extension": ".py", 189 | "mimetype": "text/x-python", 190 | "name": "python", 191 | "nbconvert_exporter": "python", 192 | "pygments_lexer": "ipython3", 193 | "version": "3.12.7" 194 | } 195 | }, 196 | "nbformat": 4, 197 | "nbformat_minor": 5 198 | } 199 | -------------------------------------------------------------------------------- /Book4_Ch02_Python_Codes/Bk4_Ch02_04.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 02\n", 9 | "\n", 10 | "# 向量加减法\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "5727cda1-e9bd-4483-b50f-9b9ef36574ae", 17 | "metadata": {}, 18 | "source": [ 19 | "这段代码定义了两个二维列向量 $a$ 和 $b$,并计算了它们的加法与减法。具体来说,向量 $a$ 定义为:\n", 20 | "\n", 21 | "$$\n", 22 | "a = \\begin{bmatrix} -2 \\\\ 5 \\end{bmatrix}\n", 23 | "$$\n", 24 | "\n", 25 | "向量 $b$ 定义为:\n", 26 | "\n", 27 | "$$\n", 28 | "b = \\begin{bmatrix} 5 \\\\ -1 \\end{bmatrix}\n", 29 | "$$\n", 30 | "\n", 31 | "代码首先计算了 $a$ 和 $b$ 的向量加法,得到结果向量 $a + b$,其计算过程为:\n", 32 | "\n", 33 | "$$\n", 34 | "a + b = \\begin{bmatrix} -2 \\\\ 5 \\end{bmatrix} + \\begin{bmatrix} 5 \\\\ -1 \\end{bmatrix} = \\begin{bmatrix} 3 \\\\ 4 \\end{bmatrix}\n", 35 | "$$\n", 36 | "\n", 37 | "此外,代码还展示了向量减法 $a - b$ 和 $b - a$,分别为:\n", 38 | "\n", 39 | "$$\n", 40 | "a - b = \\begin{bmatrix} -2 \\\\ 5 \\end{bmatrix} - \\begin{bmatrix} 5 \\\\ -1 \\end{bmatrix} = \\begin{bmatrix} -7 \\\\ 6 \\end{bmatrix}\n", 41 | "$$\n", 42 | "\n", 43 | "$$\n", 44 | "b - a = \\begin{bmatrix} 5 \\\\ -1 \\end{bmatrix} - \\begin{bmatrix} -2 \\\\ 5 \\end{bmatrix} = \\begin{bmatrix} 7 \\\\ -6 \\end{bmatrix}\n", 45 | "$$\n", 46 | "\n", 47 | "代码中分别使用了直接运算(如 `a + b`)和 `NumPy` 函数 `np.add` 与 `np.subtract` 来完成加法和减法操作。这种处理方式展示了向量的基本线性代数操作。" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "id": "88825576-ff58-4b2e-8a6b-770f593c57bb", 53 | "metadata": {}, 54 | "source": [ 55 | "## 导入所需库" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 1, 61 | "id": "61e4349a-f354-4e33-a9a0-0b43ab26eb3b", 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "import numpy as np # 导入NumPy库,用于数值计算" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "id": "ea419dfa-5bf7-4c35-b465-8ff0416ce120", 71 | "metadata": {}, 72 | "source": [ 73 | "## 定义两个列向量" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 2, 79 | "id": "ee8dadac-372a-43a9-8a21-f2e54d27b4c6", 80 | "metadata": {}, 81 | "outputs": [ 82 | { 83 | "data": { 84 | "text/plain": [ 85 | "array([[-2],\n", 86 | " [ 5]])" 87 | ] 88 | }, 89 | "execution_count": 2, 90 | "metadata": {}, 91 | "output_type": "execute_result" 92 | } 93 | ], 94 | "source": [ 95 | "a = np.array([[-2], [5]]) # 定义向量a,值为[-2, 5]\n", 96 | "a" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 3, 102 | "id": "1749cae5-c1ac-491b-ba00-0e93066130ac", 103 | "metadata": {}, 104 | "outputs": [ 105 | { 106 | "data": { 107 | "text/plain": [ 108 | "array([[ 5],\n", 109 | " [-1]])" 110 | ] 111 | }, 112 | "execution_count": 3, 113 | "metadata": {}, 114 | "output_type": "execute_result" 115 | } 116 | ], 117 | "source": [ 118 | "b = np.array([[5], [-1]]) # 定义向量b,值为[5, -1]\n", 119 | "b" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "id": "68440eab-d48e-450b-ad71-43adcc4c30b3", 125 | "metadata": {}, 126 | "source": [ 127 | "## 计算向量加法" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 4, 133 | "id": "7c6885fd-59eb-457b-967f-fbeebee26a96", 134 | "metadata": {}, 135 | "outputs": [ 136 | { 137 | "data": { 138 | "text/plain": [ 139 | "array([[3],\n", 140 | " [4]])" 141 | ] 142 | }, 143 | "execution_count": 4, 144 | "metadata": {}, 145 | "output_type": "execute_result" 146 | } 147 | ], 148 | "source": [ 149 | "a_plus_b = a + b # 使用直接加法计算a和b的和\n", 150 | "a_plus_b" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 5, 156 | "id": "2bbd2e21-91c4-43b5-b18d-597011c73214", 157 | "metadata": {}, 158 | "outputs": [ 159 | { 160 | "data": { 161 | "text/plain": [ 162 | "array([[3],\n", 163 | " [4]])" 164 | ] 165 | }, 166 | "execution_count": 5, 167 | "metadata": {}, 168 | "output_type": "execute_result" 169 | } 170 | ], 171 | "source": [ 172 | "a_plus_b_2 = np.add(a, b) # 使用np.add函数计算a和b的和\n", 173 | "a_plus_b_2" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "id": "54f2167f-edeb-48f4-81e4-89e27e459fd8", 179 | "metadata": {}, 180 | "source": [ 181 | "## 计算向量减法" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 6, 187 | "id": "f6e97112-bfc4-44e9-9a9d-d168d4ba030e", 188 | "metadata": {}, 189 | "outputs": [ 190 | { 191 | "data": { 192 | "text/plain": [ 193 | "array([[-7],\n", 194 | " [ 6]])" 195 | ] 196 | }, 197 | "execution_count": 6, 198 | "metadata": {}, 199 | "output_type": "execute_result" 200 | } 201 | ], 202 | "source": [ 203 | "a_minus_b = a - b # 计算a减去b的差\n", 204 | "a_minus_b" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 7, 210 | "id": "a1b483cd-6bfc-450c-a883-d86a89ea897b", 211 | "metadata": {}, 212 | "outputs": [ 213 | { 214 | "data": { 215 | "text/plain": [ 216 | "array([[-7],\n", 217 | " [ 6]])" 218 | ] 219 | }, 220 | "execution_count": 7, 221 | "metadata": {}, 222 | "output_type": "execute_result" 223 | } 224 | ], 225 | "source": [ 226 | "a_minus_b_2 = np.subtract(a, b) # 使用np.subtract函数计算a减去b的差\n", 227 | "a_minus_b_2" 228 | ] 229 | }, 230 | { 231 | "cell_type": "code", 232 | "execution_count": 8, 233 | "id": "b1b4beab-4cab-48b1-b90d-065ee5971e9e", 234 | "metadata": {}, 235 | "outputs": [ 236 | { 237 | "data": { 238 | "text/plain": [ 239 | "array([[ 7],\n", 240 | " [-6]])" 241 | ] 242 | }, 243 | "execution_count": 8, 244 | "metadata": {}, 245 | "output_type": "execute_result" 246 | } 247 | ], 248 | "source": [ 249 | "b_minus_a = b - a # 计算b减去a的差\n", 250 | "b_minus_a" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 9, 256 | "id": "2a010763-e0f1-457f-acf9-e8e0182d271d", 257 | "metadata": {}, 258 | "outputs": [ 259 | { 260 | "data": { 261 | "text/plain": [ 262 | "array([[ 7],\n", 263 | " [-6]])" 264 | ] 265 | }, 266 | "execution_count": 9, 267 | "metadata": {}, 268 | "output_type": "execute_result" 269 | } 270 | ], 271 | "source": [ 272 | "b_minus_a_2 = np.subtract(b, a) # 使用np.subtract函数计算b减去a的差\n", 273 | "b_minus_a_2" 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": null, 279 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 280 | "metadata": {}, 281 | "outputs": [], 282 | "source": [] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": null, 287 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 288 | "metadata": {}, 289 | "outputs": [], 290 | "source": [] 291 | } 292 | ], 293 | "metadata": { 294 | "kernelspec": { 295 | "display_name": "Python 3 (ipykernel)", 296 | "language": "python", 297 | "name": "python3" 298 | }, 299 | "language_info": { 300 | "codemirror_mode": { 301 | "name": "ipython", 302 | "version": 3 303 | }, 304 | "file_extension": ".py", 305 | "mimetype": "text/x-python", 306 | "name": "python", 307 | "nbconvert_exporter": "python", 308 | "pygments_lexer": "ipython3", 309 | "version": "3.12.7" 310 | } 311 | }, 312 | "nbformat": 4, 313 | "nbformat_minor": 5 314 | } 315 | -------------------------------------------------------------------------------- /Book4_Ch02_Python_Codes/Bk4_Ch02_05.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 02\n", 9 | "\n", 10 | "# 标量乘法\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "9fcf085a-8ecf-4003-b0b1-76f2e95c1063", 17 | "metadata": {}, 18 | "source": [ 19 | "\n", 20 | "\n", 21 | "此代码定义了一个二维列向量 $a$,其值为:\n", 22 | "\n", 23 | "$$\n", 24 | "a = \\begin{bmatrix} 2 \\\\ 2 \\end{bmatrix}\n", 25 | "$$\n", 26 | "\n", 27 | "接下来,代码通过数乘操作生成两个新向量 $b$ 和 $c$。具体而言,$b$ 是 $a$ 的 2 倍:\n", 28 | "\n", 29 | "$$\n", 30 | "b = 2 \\times a = 2 \\times \\begin{bmatrix} 2 \\\\ 2 \\end{bmatrix} = \\begin{bmatrix} 4 \\\\ 4 \\end{bmatrix}\n", 31 | "$$\n", 32 | "\n", 33 | "$c$ 是 $a$ 的 $-1.5$ 倍:\n", 34 | "\n", 35 | "$$\n", 36 | "c = -1.5 \\times a = -1.5 \\times \\begin{bmatrix} 2 \\\\ 2 \\end{bmatrix} = \\begin{bmatrix} -3 \\\\ -3 \\end{bmatrix}\n", 37 | "$$\n", 38 | "\n", 39 | "此过程展示了向量的数乘操作,通过将标量与向量相乘来改变向量的大小和方向。" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "id": "7f2b0f70-8b54-49c7-a58c-736dd1838f39", 45 | "metadata": {}, 46 | "source": [ 47 | "## 导入所需库" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 1, 53 | "id": "457dd7c5-1ef8-4272-9608-01802512d831", 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "import numpy as np # 导入NumPy库,用于数值计算" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "id": "a2882d5b-db0c-4d22-96ba-76123168e589", 63 | "metadata": {}, 64 | "source": [ 65 | "## 定义一个列向量" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 2, 71 | "id": "dc48b150-34ed-4cc8-a5c3-ae59f58fbcdf", 72 | "metadata": {}, 73 | "outputs": [ 74 | { 75 | "data": { 76 | "text/plain": [ 77 | "array([[2],\n", 78 | " [2]])" 79 | ] 80 | }, 81 | "execution_count": 2, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "a = np.array([[2], [2]]) # 定义向量a,值为[2, 2]\n", 88 | "a" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "id": "0e89b43f-c8e1-4af6-a3aa-eb966479608b", 94 | "metadata": {}, 95 | "source": [ 96 | "## 进行向量的数乘" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 3, 102 | "id": "352700c8-fc4c-4b7c-8f8b-2ee1a5905878", 103 | "metadata": {}, 104 | "outputs": [ 105 | { 106 | "data": { 107 | "text/plain": [ 108 | "array([[4],\n", 109 | " [4]])" 110 | ] 111 | }, 112 | "execution_count": 3, 113 | "metadata": {}, 114 | "output_type": "execute_result" 115 | } 116 | ], 117 | "source": [ 118 | "b = 2 * a # 计算b,为向量a的2倍\n", 119 | "b" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 4, 125 | "id": "a7e94dac-9695-4bcc-b09b-3dc7e823fe3b", 126 | "metadata": {}, 127 | "outputs": [ 128 | { 129 | "data": { 130 | "text/plain": [ 131 | "array([[-3.],\n", 132 | " [-3.]])" 133 | ] 134 | }, 135 | "execution_count": 4, 136 | "metadata": {}, 137 | "output_type": "execute_result" 138 | } 139 | ], 140 | "source": [ 141 | "c = -1.5 * a # 计算c,为向量a的-1.5倍\n", 142 | "c" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 149 | "metadata": {}, 150 | "outputs": [], 151 | "source": [] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [] 160 | } 161 | ], 162 | "metadata": { 163 | "kernelspec": { 164 | "display_name": "Python 3 (ipykernel)", 165 | "language": "python", 166 | "name": "python3" 167 | }, 168 | "language_info": { 169 | "codemirror_mode": { 170 | "name": "ipython", 171 | "version": 3 172 | }, 173 | "file_extension": ".py", 174 | "mimetype": "text/x-python", 175 | "name": "python", 176 | "nbconvert_exporter": "python", 177 | "pygments_lexer": "ipython3", 178 | "version": "3.12.7" 179 | } 180 | }, 181 | "nbformat": 4, 182 | "nbformat_minor": 5 183 | } 184 | -------------------------------------------------------------------------------- /Book4_Ch02_Python_Codes/Bk4_Ch02_06.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 02\n", 9 | "\n", 10 | "# 向量内积\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "90d57742-54b5-4967-9de6-2b97f3ff13ce", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码定义了两个二维向量 $a$ 和 $b$,并计算它们的内积。向量 $a$ 和 $b$ 的定义分别为:\n", 20 | "\n", 21 | "$$\n", 22 | "a = \\begin{bmatrix} 4 & 3 \\end{bmatrix}, \\quad b = \\begin{bmatrix} 5 & -2 \\end{bmatrix}\n", 23 | "$$\n", 24 | "\n", 25 | "代码首先通过 `np.inner` 函数计算行向量的内积,其计算公式为:\n", 26 | "\n", 27 | "$$\n", 28 | "a \\cdot b = 4 \\cdot 5 + 3 \\cdot (-2) = 20 - 6 = 14\n", 29 | "$$\n", 30 | "\n", 31 | "接着,代码将 $a$ 和 $b$ 定义为列向量形式 $a_2$ 和 $b_2$,并通过矩阵转置与矩阵乘法计算内积:\n", 32 | "\n", 33 | "$$\n", 34 | "a_2^T \\cdot b_2 = \\begin{bmatrix} 4 & 3 \\end{bmatrix} \\cdot \\begin{bmatrix} 5 \\\\ -2 \\end{bmatrix} = 14\n", 35 | "$$\n", 36 | "\n", 37 | "该过程展示了内积计算的不同实现方式,包括使用 `np.inner` 和转置矩阵乘法。" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "id": "a869bcd3-b5b0-48a6-8473-e1af9efa124c", 43 | "metadata": {}, 44 | "source": [ 45 | "## 导入所需库" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 1, 51 | "id": "52854f8c-f415-452c-8b0f-ba216cedb4a3", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "import numpy as np # 导入NumPy库,用于数值计算" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "id": "a895dedd-943b-4b5e-a9d8-6c958e1ec18e", 61 | "metadata": {}, 62 | "source": [ 63 | "## 定义两个行向量" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 2, 69 | "id": "13d6cc5a-824f-4537-8d80-5e4a0c6146a7", 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "a = np.array([[4, 3]]) # 定义向量a,值为[4, 3]" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 3, 79 | "id": "89d1799e-2c61-4410-83fd-401db971b8fd", 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "b = np.array([[5, -2]]) # 定义向量b,值为[5, -2]" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "id": "3277e077-e975-4354-b79a-5bc9e77d5666", 89 | "metadata": {}, 90 | "source": [ 91 | "## 计算内积" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 4, 97 | "id": "e4008c0e-94ff-4cb5-8139-432ed0048692", 98 | "metadata": {}, 99 | "outputs": [ 100 | { 101 | "data": { 102 | "text/plain": [ 103 | "array([[14]])" 104 | ] 105 | }, 106 | "execution_count": 4, 107 | "metadata": {}, 108 | "output_type": "execute_result" 109 | } 110 | ], 111 | "source": [ 112 | "a_dot_b = np.inner(a, b) # 使用np.inner计算a和b的内积\n", 113 | "a_dot_b" 114 | ] 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "id": "b6a1c7e0-b5e4-4303-b2a8-19e7a0d72cbb", 119 | "metadata": {}, 120 | "source": [ 121 | "## 定义两个列向量" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 5, 127 | "id": "c30e546b-1f82-43c7-b4d5-163394f406c3", 128 | "metadata": {}, 129 | "outputs": [], 130 | "source": [ 131 | "a_2 = np.array([[4], [3]]) # 定义列向量a_2,值为[4, 3]" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": 6, 137 | "id": "41ee49f6-1d62-4f0e-895e-671ae32ad301", 138 | "metadata": {}, 139 | "outputs": [], 140 | "source": [ 141 | "b_2 = np.array([[5], [-2]]) # 定义列向量b_2,值为[5, -2]" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "id": "d6a74fd1-5de1-486c-98fb-ff21a16d5158", 147 | "metadata": {}, 148 | "source": [ 149 | "## 计算转置后内积" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 7, 155 | "id": "ce1247f9-be4e-40aa-be27-9b9b4d8f9b03", 156 | "metadata": {}, 157 | "outputs": [], 158 | "source": [ 159 | "a_dot_b_2 = a_2.T @ b_2 # 使用矩阵乘法计算a_2转置和b_2的内积" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 8, 165 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 166 | "metadata": {}, 167 | "outputs": [ 168 | { 169 | "data": { 170 | "text/plain": [ 171 | "array([[14]])" 172 | ] 173 | }, 174 | "execution_count": 8, 175 | "metadata": {}, 176 | "output_type": "execute_result" 177 | } 178 | ], 179 | "source": [ 180 | "a_dot_b_2" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": null, 186 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 187 | "metadata": {}, 188 | "outputs": [], 189 | "source": [] 190 | } 191 | ], 192 | "metadata": { 193 | "kernelspec": { 194 | "display_name": "Python 3 (ipykernel)", 195 | "language": "python", 196 | "name": "python3" 197 | }, 198 | "language_info": { 199 | "codemirror_mode": { 200 | "name": "ipython", 201 | "version": 3 202 | }, 203 | "file_extension": ".py", 204 | "mimetype": "text/x-python", 205 | "name": "python", 206 | "nbconvert_exporter": "python", 207 | "pygments_lexer": "ipython3", 208 | "version": "3.12.7" 209 | } 210 | }, 211 | "nbformat": 4, 212 | "nbformat_minor": 5 213 | } 214 | -------------------------------------------------------------------------------- /Book4_Ch02_Python_Codes/Bk4_Ch02_07.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 02\n", 9 | "\n", 10 | "# 矩阵乘积\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "98f9659f-671c-40ba-bf01-26b02f299f65", 17 | "metadata": {}, 18 | "source": [ 19 | "\n", 20 | "\n", 21 | "此代码定义了两个 $2 \\times 2$ 的矩阵 $A$ 和 $B$,并计算它们的矩阵乘积。矩阵 $A$ 和 $B$ 的定义分别为:\n", 22 | "\n", 23 | "$$\n", 24 | "A = \\begin{bmatrix} 2 & 3 \\\\ 3 & 4 \\end{bmatrix}, \\quad B = \\begin{bmatrix} 3 & 4 \\\\ 5 & 6 \\end{bmatrix}\n", 25 | "$$\n", 26 | "\n", 27 | "矩阵乘积 $A @ B$ 的计算公式是:\n", 28 | "\n", 29 | "$$\n", 30 | "A @ B = \\begin{bmatrix} 2 \\cdot 3 + 3 \\cdot 5 & 2 \\cdot 4 + 3 \\cdot 6 \\\\ 3 \\cdot 3 + 4 \\cdot 5 & 3 \\cdot 4 + 4 \\cdot 6 \\end{bmatrix} = \\begin{bmatrix} 21 & 26 \\\\ 29 & 38 \\end{bmatrix}\n", 31 | "$$\n" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "id": "b7d099d5-b19e-4dc1-bcbc-c6f27ff10d63", 37 | "metadata": {}, 38 | "source": [ 39 | "## 导入所需库" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 1, 45 | "id": "fe40fe29-6b65-47eb-a82d-c9739d4f17b1", 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "import numpy as np # 导入NumPy库,用于数值计算" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "id": "972ceb2f-dfc9-406b-aa4d-759d8a3c5ceb", 55 | "metadata": {}, 56 | "source": [ 57 | "## 定义两个矩阵" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 2, 63 | "id": "022dfa07-a9e4-4ba6-9456-f7dd6b861bcd", 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "A = np.array([[2, 3], # 定义矩阵A\n", 68 | " [3, 4]])" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 3, 74 | "id": "eba046cd-9051-403b-86a4-5586226e9c86", 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "B = np.array([[3, 4], # 定义矩阵B\n", 79 | " [5, 6]])" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "id": "97150b17-9793-47aa-b9c1-aa61baf34bde", 85 | "metadata": {}, 86 | "source": [ 87 | "## 计算矩阵点积" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 4, 93 | "id": "dec0b7d8-6d24-4d13-8bf2-0786a4d1e8e6", 94 | "metadata": {}, 95 | "outputs": [ 96 | { 97 | "data": { 98 | "text/plain": [ 99 | "array([[21, 26],\n", 100 | " [29, 36]])" 101 | ] 102 | }, 103 | "execution_count": 4, 104 | "metadata": {}, 105 | "output_type": "execute_result" 106 | } 107 | ], 108 | "source": [ 109 | "A_dot_B = np.dot(A, B) # 使用np.dot计算A和B的矩阵乘积\n", 110 | "A_dot_B" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 5, 116 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 117 | "metadata": {}, 118 | "outputs": [ 119 | { 120 | "data": { 121 | "text/plain": [ 122 | "array([[21, 26],\n", 123 | " [29, 36]])" 124 | ] 125 | }, 126 | "execution_count": 5, 127 | "metadata": {}, 128 | "output_type": "execute_result" 129 | } 130 | ], 131 | "source": [ 132 | "# 可以直接用A @ B作为矩阵乘法的简写\n", 133 | "A @ B" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": null, 139 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 140 | "metadata": {}, 141 | "outputs": [], 142 | "source": [] 143 | } 144 | ], 145 | "metadata": { 146 | "kernelspec": { 147 | "display_name": "Python 3 (ipykernel)", 148 | "language": "python", 149 | "name": "python3" 150 | }, 151 | "language_info": { 152 | "codemirror_mode": { 153 | "name": "ipython", 154 | "version": 3 155 | }, 156 | "file_extension": ".py", 157 | "mimetype": "text/x-python", 158 | "name": "python", 159 | "nbconvert_exporter": "python", 160 | "pygments_lexer": "ipython3", 161 | "version": "3.12.7" 162 | } 163 | }, 164 | "nbformat": 4, 165 | "nbformat_minor": 5 166 | } 167 | -------------------------------------------------------------------------------- /Book4_Ch02_Python_Codes/Bk4_Ch02_08.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 02\n", 9 | "\n", 10 | "# 向量化内积\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "6f5b0126-e220-42a5-9c76-10b5c77dd35c", 17 | "metadata": {}, 18 | "source": [ 19 | "此代码定义了两个 $2 \\times 2$ 的矩阵 $A$ 和 $B$,并使用 `np.vdot` 计算它们的向量化内积。`np.vdot` 会将矩阵元素展平成一维向量,然后执行逐元素的内积计算。\n", 20 | "\n", 21 | "矩阵 $A$ 和 $B$ 展开后为:\n", 22 | "\n", 23 | "$$\n", 24 | "A = \\begin{bmatrix} 1 & 2 & 3 & 4 \\end{bmatrix}, \\quad B = \\begin{bmatrix} 3 & 4 & 5 & 6 \\end{bmatrix}\n", 25 | "$$\n", 26 | "\n", 27 | "因此,内积的计算为:\n", 28 | "\n", 29 | "$$\n", 30 | "1 \\cdot 3 + 2 \\cdot 4 + 3 \\cdot 5 + 4 \\cdot 6 = 3 + 8 + 15 + 24 = 50\n", 31 | "$$\n", 32 | "\n", 33 | "代码使用 `np.vdot` 执行此向量化的内积计算,而不仅是逐元素矩阵乘法。" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "id": "004f7421-698b-4eb3-9d22-1517683ab9bc", 39 | "metadata": {}, 40 | "source": [ 41 | "## 导入所需库" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 1, 47 | "id": "f0b0c3a1-f413-487e-9f5f-9d8a1a37248f", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "import numpy as np # 导入NumPy库,用于数值计算" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "id": "f3ab1198-85f2-47d5-9425-46145141e92e", 57 | "metadata": {}, 58 | "source": [ 59 | "## 定义两个矩阵" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 2, 65 | "id": "138d24b7-39e5-4ccc-9d5c-f554db5c2eb9", 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "A = np.array([[1, 2], # 定义矩阵A\n", 70 | " [3, 4]])" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 3, 76 | "id": "c79531e6-89d7-4c4c-91ae-afe500cec8bb", 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "B = np.array([[3, 4], # 定义矩阵B\n", 81 | " [5, 6]])" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "id": "438b8825-fda5-4905-890a-6f690b7c11dd", 87 | "metadata": {}, 88 | "source": [ 89 | "## 计算矩阵的向量内积" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 4, 95 | "id": "8505b1bc-d105-424b-a163-25205e0f5e94", 96 | "metadata": {}, 97 | "outputs": [ 98 | { 99 | "data": { 100 | "text/plain": [ 101 | "50" 102 | ] 103 | }, 104 | "execution_count": 4, 105 | "metadata": {}, 106 | "output_type": "execute_result" 107 | } 108 | ], 109 | "source": [ 110 | "A_dot_B = np.vdot(A, B) # 使用np.vdot计算A和B的向量内积\n", 111 | "A_dot_B\n", 112 | "# [1,2,3,4]*[3,4,5,6].T # 向量化的点积计算" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 119 | "metadata": {}, 120 | "outputs": [], 121 | "source": [] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": null, 126 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 127 | "metadata": {}, 128 | "outputs": [], 129 | "source": [] 130 | } 131 | ], 132 | "metadata": { 133 | "kernelspec": { 134 | "display_name": "Python 3 (ipykernel)", 135 | "language": "python", 136 | "name": "python3" 137 | }, 138 | "language_info": { 139 | "codemirror_mode": { 140 | "name": "ipython", 141 | "version": 3 142 | }, 143 | "file_extension": ".py", 144 | "mimetype": "text/x-python", 145 | "name": "python", 146 | "nbconvert_exporter": "python", 147 | "pygments_lexer": "ipython3", 148 | "version": "3.12.7" 149 | } 150 | }, 151 | "nbformat": 4, 152 | "nbformat_minor": 5 153 | } 154 | -------------------------------------------------------------------------------- /Book4_Ch02_Python_Codes/Bk4_Ch02_09.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 02\n", 9 | "\n", 10 | "# 向量夹角\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "8bb390c4-26af-44db-bf6a-d0edb2d14b1e", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码定义了两个二维列向量 $a$ 和 $b$,并计算了它们之间夹角的余弦值、弧度和度数。\n", 20 | "\n", 21 | "### 计算公式\n", 22 | "\n", 23 | "向量 $a$ 和 $b$ 分别为:\n", 24 | "\n", 25 | "$$\n", 26 | "a = \\begin{bmatrix} 4 \\\\ 3 \\end{bmatrix}, \\quad b = \\begin{bmatrix} 5 \\\\ -2 \\end{bmatrix}\n", 27 | "$$\n", 28 | "\n", 29 | "余弦夹角公式为:\n", 30 | "\n", 31 | "$$\n", 32 | "\\cos \\theta = \\frac{a \\cdot b}{\\|a\\|_2 \\|b\\|_2} = \\frac{a^T b}{\\|a\\|_2 \\|b\\|_2}\n", 33 | "$$\n", 34 | "\n", 35 | "接着,使用反余弦函数计算角度的弧度值:\n", 36 | "\n", 37 | "$$\n", 38 | "\\theta = \\arccos(\\cos \\theta)\n", 39 | "$$\n", 40 | "\n", 41 | "最后将弧度值转换为角度:\n", 42 | "\n", 43 | "$$\n", 44 | "\\theta_{\\text{degree}} = \\theta \\times \\frac{180}{\\pi}\n", 45 | "$$\n", 46 | "\n", 47 | "代码中的运算展示了向量间夹角的计算方法,包括余弦、弧度和度数转换。" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "id": "01c7be45-8810-4f12-aca9-ecc099054269", 53 | "metadata": {}, 54 | "source": [ 55 | "## 导入所需库" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 1, 61 | "id": "53d8013b-3c6e-40da-bc98-e5787ed25f79", 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "import numpy as np # 导入NumPy库,用于数值计算" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "id": "6c657ddd-c8a1-4ddc-825f-e9e82bcade44", 71 | "metadata": {}, 72 | "source": [ 73 | "## 定义两个列向量" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 2, 79 | "id": "8e262906-50d0-44ee-b31b-4d6569b1b5b9", 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "a, b = np.array([[4], [3]]), np.array([[5], [-2]]) # 定义向量a和b" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "id": "ff9561ac-02f3-4b67-82e7-be3dddfb4460", 89 | "metadata": {}, 90 | "source": [ 91 | "## 计算余弦值" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 3, 97 | "id": "50fba935-3aa3-41f7-8aed-f29544822233", 98 | "metadata": {}, 99 | "outputs": [ 100 | { 101 | "data": { 102 | "text/plain": [ 103 | "array([[0.51994695]])" 104 | ] 105 | }, 106 | "execution_count": 3, 107 | "metadata": {}, 108 | "output_type": "execute_result" 109 | } 110 | ], 111 | "source": [ 112 | "cos_theta = (a.T @ b) / (np.linalg.norm(a, 2) * np.linalg.norm(b, 2)) \n", 113 | "# 计算向量a和b之间夹角的余弦值\n", 114 | "cos_theta" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "id": "d65329e6-0d9e-4005-b6b0-a8c46fdb2c04", 120 | "metadata": {}, 121 | "source": [ 122 | "## 计算夹角的弧度值" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 4, 128 | "id": "a94cfe3e-0338-4fb4-99d2-0b2e5e08d198", 129 | "metadata": {}, 130 | "outputs": [ 131 | { 132 | "data": { 133 | "text/plain": [ 134 | "array([[1.02400749]])" 135 | ] 136 | }, 137 | "execution_count": 4, 138 | "metadata": {}, 139 | "output_type": "execute_result" 140 | } 141 | ], 142 | "source": [ 143 | "cos_radian = np.arccos(cos_theta) # 计算余弦值对应的弧度\n", 144 | "cos_radian" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "id": "56bc6d0e-831a-4f2f-ab59-9ff9fd558a41", 150 | "metadata": {}, 151 | "source": [ 152 | "## 将弧度转换为度数" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 5, 158 | "id": "f018e489-013e-4f38-bdb4-291023e46179", 159 | "metadata": {}, 160 | "outputs": [ 161 | { 162 | "data": { 163 | "text/plain": [ 164 | "array([[58.67130713]])" 165 | ] 166 | }, 167 | "execution_count": 5, 168 | "metadata": {}, 169 | "output_type": "execute_result" 170 | } 171 | ], 172 | "source": [ 173 | "cos_degree = cos_radian * (180 / np.pi) # 将弧度转换为度数\n", 174 | "cos_degree" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": null, 180 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 181 | "metadata": {}, 182 | "outputs": [], 183 | "source": [] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": null, 188 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 189 | "metadata": {}, 190 | "outputs": [], 191 | "source": [] 192 | } 193 | ], 194 | "metadata": { 195 | "kernelspec": { 196 | "display_name": "Python 3 (ipykernel)", 197 | "language": "python", 198 | "name": "python3" 199 | }, 200 | "language_info": { 201 | "codemirror_mode": { 202 | "name": "ipython", 203 | "version": 3 204 | }, 205 | "file_extension": ".py", 206 | "mimetype": "text/x-python", 207 | "name": "python", 208 | "nbconvert_exporter": "python", 209 | "pygments_lexer": "ipython3", 210 | "version": "3.12.7" 211 | } 212 | }, 213 | "nbformat": 4, 214 | "nbformat_minor": 5 215 | } 216 | -------------------------------------------------------------------------------- /Book4_Ch02_Python_Codes/Bk4_Ch02_11.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 02\n", 9 | "\n", 10 | "# 向量积\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "873da06f-c90c-4a2a-abd3-7f8711feca02", 17 | "metadata": {}, 18 | "source": [ 19 | "此代码定义了两个三维向量 $a$ 和 $b$,并计算了它们的叉积(向量积)。首先定义了行向量形式的 $a$ 和 $b$,然后分别计算了行向量和列向量的叉积。\n", 20 | "\n", 21 | "### 叉积公式\n", 22 | "对于三维向量 $a = \\begin{bmatrix} a_1 \\\\ a_2 \\\\ a_3 \\end{bmatrix}$ 和 $b = \\begin{bmatrix} b_1 \\\\ b_2 \\\\ b_3 \\end{bmatrix}$,叉积定义为:\n", 23 | "\n", 24 | "$$\n", 25 | "a \\times b = \\begin{bmatrix} a_2 b_3 - a_3 b_2 \\\\ a_3 b_1 - a_1 b_3 \\\\ a_1 b_2 - a_2 b_1 \\end{bmatrix}\n", 26 | "$$\n", 27 | "\n", 28 | "代码中计算了行向量和列向量形式的叉积。结果表示两个向量的垂直方向,并可用于三维空间中的法向量计算。" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "id": "4e369506-697f-450e-a731-76945415ed9c", 34 | "metadata": {}, 35 | "source": [ 36 | "## 导入所需库" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 1, 42 | "id": "dbb6f14c-fcb4-499f-9618-d6ca9c8b36ab", 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "import numpy as np # 导入NumPy库,用于数值计算" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "id": "5d9fa082-6e75-4a30-9ff1-b119c73a3a25", 52 | "metadata": {}, 53 | "source": [ 54 | "## 定义两个行向量" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 2, 60 | "id": "081b4fe5-be16-4854-914b-5c795f937fa8", 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "a = np.array([-2, 1, 1]) # 定义向量a" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 3, 70 | "id": "9a902aa8-799a-4461-a5c0-459f2550272a", 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "b = np.array([1, -2, -1]) # 定义向量b" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "id": "b04a2e40-0ae4-44f1-a6bd-e691ee781d18", 80 | "metadata": {}, 81 | "source": [ 82 | "## 计算行向量的叉积" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 4, 88 | "id": "95ea922a-d94c-42c3-8459-d8fc755b8df3", 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [ 92 | "a_cross_b = np.cross(a, b) # 计算a和b的叉积" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "id": "6de6f635-f9e9-4667-a12a-884ccaeb26f3", 98 | "metadata": {}, 99 | "source": [ 100 | "## 定义两个列向量" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": 5, 106 | "id": "0d9f2b40-f6a0-4ca6-a70b-3910b69a9706", 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "a_col = np.array([[-2], [1], [1]]) # 定义列向量a_col" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 6, 116 | "id": "66e48d3a-7fa8-41a8-bf8b-61cfdf250200", 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "b_col = np.array([[1], [-2], [-1]]) # 定义列向量b_col" 121 | ] 122 | }, 123 | { 124 | "cell_type": "markdown", 125 | "id": "c19ed8a3-f8e7-4c42-b6f7-bac01f31e016", 126 | "metadata": {}, 127 | "source": [ 128 | "## 计算列向量的叉积" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 7, 134 | "id": "9c019178-15f5-41f6-93d5-ceea5505684f", 135 | "metadata": {}, 136 | "outputs": [ 137 | { 138 | "data": { 139 | "text/plain": [ 140 | "array([[ 1],\n", 141 | " [-1],\n", 142 | " [ 3]])" 143 | ] 144 | }, 145 | "execution_count": 7, 146 | "metadata": {}, 147 | "output_type": "execute_result" 148 | } 149 | ], 150 | "source": [ 151 | "a_cross_b_col = np.cross(a_col, b_col, axis=0) # 计算a_col和b_col的叉积,沿axis=0进行计算\n", 152 | "a_cross_b_col" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 159 | "metadata": {}, 160 | "outputs": [], 161 | "source": [] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": null, 166 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 167 | "metadata": {}, 168 | "outputs": [], 169 | "source": [] 170 | } 171 | ], 172 | "metadata": { 173 | "kernelspec": { 174 | "display_name": "Python 3 (ipykernel)", 175 | "language": "python", 176 | "name": "python3" 177 | }, 178 | "language_info": { 179 | "codemirror_mode": { 180 | "name": "ipython", 181 | "version": 3 182 | }, 183 | "file_extension": ".py", 184 | "mimetype": "text/x-python", 185 | "name": "python", 186 | "nbconvert_exporter": "python", 187 | "pygments_lexer": "ipython3", 188 | "version": "3.12.7" 189 | } 190 | }, 191 | "nbformat": 4, 192 | "nbformat_minor": 5 193 | } 194 | -------------------------------------------------------------------------------- /Book4_Ch02_Python_Codes/Bk4_Ch02_12.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 02\n", 9 | "\n", 10 | "# 逐项积\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "ce4a4893-3f8c-402f-92c3-79d73b81d380", 17 | "metadata": {}, 18 | "source": [ 19 | "\n", 20 | "此代码定义了两个三维向量 $a$ 和 $b$,并计算了它们的逐元素积(即对应元素相乘)。代码中既使用了行向量形式也使用了列向量形式的 $a$ 和 $b$ 来演示逐元素乘法的计算。\n", 21 | "\n", 22 | "### 逐元素乘法公式\n", 23 | "对于两个向量 $a = \\begin{bmatrix} a_1 \\\\ a_2 \\\\ a_3 \\end{bmatrix}$ 和 $b = \\begin{bmatrix} b_1 \\\\ b_2 \\\\ b_3 \\end{bmatrix}$,逐元素积定义为:\n", 24 | "\n", 25 | "$$\n", 26 | "a \\odot b = \\begin{bmatrix} a_1 \\cdot b_1 \\\\ a_2 \\cdot b_2 \\\\ a_3 \\cdot b_3 \\end{bmatrix}\n", 27 | "$$\n", 28 | "\n", 29 | "代码中的计算展示了逐元素乘法的两种实现方式:使用 `np.multiply` 函数和直接使用 `*` 操作符。结果得到一个新向量,其中每个元素为对应元素相乘的值。" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "id": "370c070f-d704-40b0-90c9-ef2e2bee22ce", 35 | "metadata": {}, 36 | "source": [ 37 | "## 导入所需库" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 1, 43 | "id": "b92befcd-0d09-4301-aecc-cb3172ce2cd9", 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "import numpy as np # 导入NumPy库,用于数值计算" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "id": "25572211-3dd7-487d-ab16-d62682d66f56", 53 | "metadata": {}, 54 | "source": [ 55 | "## 定义两个行向量" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 2, 61 | "id": "04b0208a-df81-48a4-8e85-f2ef347708c1", 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "a = np.array([-2, 1, 1]) # 定义向量a" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 3, 71 | "id": "557a8b24-f13d-4995-9bc2-c8bc3fa19389", 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "b = np.array([1, -2, -1]) # 定义向量b" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "id": "4a95a30f-b3fc-4e2f-b2e7-ccd49cc48ed1", 81 | "metadata": {}, 82 | "source": [ 83 | "## 计算行向量的逐元素积" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 4, 89 | "id": "29eca8ec-ed59-4e60-90bf-8405a4a084e3", 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "data": { 94 | "text/plain": [ 95 | "array([-2, -2, -1])" 96 | ] 97 | }, 98 | "execution_count": 4, 99 | "metadata": {}, 100 | "output_type": "execute_result" 101 | } 102 | ], 103 | "source": [ 104 | "a_times_b = np.multiply(a, b) # 计算a和b的逐元素积\n", 105 | "a_times_b" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 5, 111 | "id": "91a581bf-ca56-44b2-8d21-8ae4a19ee309", 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "data": { 116 | "text/plain": [ 117 | "array([-2, -2, -1])" 118 | ] 119 | }, 120 | "execution_count": 5, 121 | "metadata": {}, 122 | "output_type": "execute_result" 123 | } 124 | ], 125 | "source": [ 126 | "a_times_b_2 = a * b # 使用*操作符计算a和b的逐元素积\n", 127 | "a_times_b_2" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "id": "65964628-e9f9-4626-9a49-adc10d2f4ecf", 133 | "metadata": {}, 134 | "source": [ 135 | "## 定义两个列向量" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 6, 141 | "id": "42eec7be-ccdc-4a9a-be68-0e074793c2a4", 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "a_col = np.array([[-2], [1], [1]]) # 定义列向量a_col" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 7, 151 | "id": "b8757d8c-776a-400c-be13-0b7cac7ffdac", 152 | "metadata": {}, 153 | "outputs": [], 154 | "source": [ 155 | "b_col = np.array([[1], [-2], [-1]]) # 定义列向量b_col" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "id": "2269b17d-2fc2-47dc-b7eb-4f4ec992502f", 161 | "metadata": {}, 162 | "source": [ 163 | "## 计算列向量的逐元素积" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": 8, 169 | "id": "c9f74e22-8432-4c40-bb9b-36f0a2d5e064", 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "data": { 174 | "text/plain": [ 175 | "array([[-2],\n", 176 | " [-2],\n", 177 | " [-1]])" 178 | ] 179 | }, 180 | "execution_count": 8, 181 | "metadata": {}, 182 | "output_type": "execute_result" 183 | } 184 | ], 185 | "source": [ 186 | "a_times_b_col = np.multiply(a_col, b_col) # 计算a_col和b_col的逐元素积\n", 187 | "a_times_b_col" 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 9, 193 | "id": "7cd5c6c6-b2e3-4027-8eaa-7656594db66b", 194 | "metadata": {}, 195 | "outputs": [ 196 | { 197 | "data": { 198 | "text/plain": [ 199 | "array([[-2],\n", 200 | " [-2],\n", 201 | " [-1]])" 202 | ] 203 | }, 204 | "execution_count": 9, 205 | "metadata": {}, 206 | "output_type": "execute_result" 207 | } 208 | ], 209 | "source": [ 210 | "a_times_b_col_2 = a_col * b_col # 使用*操作符计算a_col和b_col的逐元素积\n", 211 | "a_times_b_col_2" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": null, 217 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 218 | "metadata": {}, 219 | "outputs": [], 220 | "source": [] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": null, 225 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 226 | "metadata": {}, 227 | "outputs": [], 228 | "source": [] 229 | } 230 | ], 231 | "metadata": { 232 | "kernelspec": { 233 | "display_name": "Python 3 (ipykernel)", 234 | "language": "python", 235 | "name": "python3" 236 | }, 237 | "language_info": { 238 | "codemirror_mode": { 239 | "name": "ipython", 240 | "version": 3 241 | }, 242 | "file_extension": ".py", 243 | "mimetype": "text/x-python", 244 | "name": "python", 245 | "nbconvert_exporter": "python", 246 | "pygments_lexer": "ipython3", 247 | "version": "3.12.7" 248 | } 249 | }, 250 | "nbformat": 4, 251 | "nbformat_minor": 5 252 | } 253 | -------------------------------------------------------------------------------- /Book4_Ch02_Python_Codes/Streamlit_Bk4_Ch02_13.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | 10 | ## 导入必要的库 11 | import streamlit as st # 引入Streamlit库,用于创建交互式Web应用 12 | import numpy as np # 引入Numpy库,用于数值计算 13 | from plotly.subplots import make_subplots # 引入Plotly的子图模块,用于创建复杂布局 14 | import plotly.graph_objects as go # 引入Plotly的图形对象模块,用于绘图 15 | import plotly.express as px # 引入Plotly Express模块,用于快速绘图 16 | 17 | ## 定义自定义函数 bmatrix 18 | # 该函数将一个numpy数组转换为LaTeX格式的bmatrix矩阵 19 | def bmatrix(a): 20 | """返回一个LaTeX格式的bmatrix矩阵表示形式 21 | 22 | :a: numpy数组 23 | :returns: 返回字符串形式的LaTeX bmatrix矩阵 24 | """ 25 | if len(a.shape) > 2: # 如果数组维度大于2,抛出异常 26 | raise ValueError('bmatrix最多只能展示二维数据') 27 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 移除括号并分行 28 | rv = [r'\begin{bmatrix}'] # LaTeX矩阵开始标记 29 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 拼接矩阵中的元素 30 | rv += [r'\end{bmatrix}'] # LaTeX矩阵结束标记 31 | return '\n'.join(rv) # 返回完整的LaTeX矩阵字符串 32 | 33 | ## 侧边栏设置 34 | with st.sidebar: # 创建侧边栏 35 | # 创建滑块以选择a的行数,范围为3到6,默认值为3 36 | num_a = st.slider('Number of rows, a:', 3, 6, step=1) 37 | # 创建滑块以选择b的行数,范围为3到6,默认值为3 38 | num_b = st.slider('Number of rows, b:', 3, 6, step=1) 39 | 40 | # 随机生成矩阵a,值在0到1之间,形状为(num_a, 1) 41 | a = np.random.uniform(0, 1, num_a).reshape((-1, 1)) 42 | a = np.round(a, 1) # 将矩阵a的值保留一位小数 43 | # 随机生成矩阵b,值在0到1之间,形状为(num_b, 1) 44 | b = np.random.uniform(0, 1, num_b).reshape((-1, 1)) 45 | b = np.round(b, 1) # 将矩阵b的值保留一位小数 46 | 47 | show_number = False # 初始化显示数值的变量为False 48 | with st.sidebar: # 在侧边栏中添加复选框 49 | # 创建复选框用于控制是否显示矩阵数值 50 | show_number = st.checkbox('Display values') 51 | 52 | # 计算a与b转置的张量积 53 | tensor_a_b = a @ b.T 54 | 55 | ## 数据可视化部分 56 | # 在Streamlit中以LaTeX格式展示矩阵a 57 | st.latex('a = ' + bmatrix(a)) 58 | # 在Streamlit中以LaTeX格式展示矩阵b 59 | st.latex('b = ' + bmatrix(b)) 60 | # 展示张量积公式 61 | st.latex('a \\otimes b = ab^{T}') 62 | # 展示矩阵a与b的张量积计算结果 63 | st.latex(bmatrix(a) + '@' + bmatrix(b.T) + ' = ' + bmatrix(tensor_a_b)) 64 | 65 | # 创建三个列布局 66 | col1, col2, col3 = st.columns(3) 67 | 68 | # 在第一列展示矩阵a的热图 69 | with col1: 70 | fig_a = px.imshow(a, text_auto=show_number, # 绘制热图,并根据show_number显示数值 71 | color_continuous_scale='viridis', # 设置颜色映射 72 | aspect='equal') # 设置宽高比为1:1 73 | fig_a.update_layout(height=400, width=300) # 设置图形大小 74 | fig_a.layout.coloraxis.showscale = False # 隐藏颜色条 75 | st.plotly_chart(fig_a) # 在Streamlit中显示图形 76 | 77 | # 在第二列展示矩阵b的热图 78 | with col2: 79 | fig_b = px.imshow(b, text_auto=show_number, # 绘制热图,并根据show_number显示数值 80 | color_continuous_scale='viridis', # 设置颜色映射 81 | aspect='equal') # 设置宽高比为1:1 82 | fig_b.update_layout(height=400, width=300) # 设置图形大小 83 | fig_b.layout.coloraxis.showscale = False # 隐藏颜色条 84 | st.plotly_chart(fig_b) # 在Streamlit中显示图形 85 | 86 | # 在第三列展示张量积矩阵的热图 87 | with col3: 88 | fig_ab = px.imshow(tensor_a_b, text_auto=show_number, # 绘制热图,并根据show_number显示数值 89 | color_continuous_scale='viridis', # 设置颜色映射 90 | aspect='equal') # 设置宽高比为1:1 91 | fig_ab.update_layout(height=400, width=400) # 设置图形大小 92 | fig_ab.layout.coloraxis.showscale = False # 隐藏颜色条 93 | st.plotly_chart(fig_ab) # 在Streamlit中显示图形 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Book4_Ch02_向量运算__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch02_向量运算__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch03_Python_Codes/Streamlit_Bk4_Ch03_01.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | ## 导入必要的库 10 | import streamlit as st # 引入Streamlit库,用于创建交互式Web应用 11 | import plotly.graph_objects as go # 引入Plotly图形对象模块,用于绘图 12 | import numpy as np # 引入NumPy库,用于数值计算 13 | 14 | ## 定义网格数据 15 | x1 = np.linspace(-2.5, 2.5, num=101) # 生成x1的线性等间距数组,范围为-2.5到2.5,共101个点 16 | x2 = x1 # 定义x2与x1相同 17 | xx1, xx2 = np.meshgrid(x1, x2) # 使用meshgrid生成二维网格数据 18 | 19 | ## 创建侧边栏以选择参数p 20 | with st.sidebar: # 在侧边栏中设置参数 21 | st.write('Note: Lp norm, p >= 1') # 显示提示信息:Lp范数,p >= 1 22 | p = st.slider('p', # 创建滑块选择p值 23 | min_value=-20.0, # p值的最小值为-20.0 24 | max_value=20.0, # p值的最大值为20.0 25 | step=0.2) # p值的步长为0.2 26 | 27 | ## 计算Lp范数的二维数据 28 | zz = ((np.abs((xx1))**p) + (np.abs((xx2))**p))**(1. / p) # 根据Lp范数公式计算二维数据zz 29 | 30 | ## 创建二维等高线图 31 | fig_1 = go.Figure(data= 32 | go.Contour(z=zz, # 设置z轴数据为zz 33 | x=x1, # 设置x轴数据为x1 34 | y=x2, # 设置y轴数据为x2 35 | colorscale='RdYlBu_r')) # 设置颜色映射为红黄蓝反转 36 | 37 | fig_1.update_layout( # 更新图形布局 38 | autosize=False, # 关闭自动调整大小 39 | width=500, # 设置图形宽度为500 40 | height=500, # 设置图形高度为500 41 | margin=dict( # 设置图形边距 42 | l=50, # 左边距为50 43 | r=50, # 右边距为50 44 | b=50, # 底边距为50 45 | t=50)) # 顶边距为50 46 | 47 | ## 创建三维表面图 48 | fig_2 = go.Figure( 49 | go.Surface( 50 | x=x1, # 设置x轴数据为x1 51 | y=x2, # 设置y轴数据为x2 52 | z=zz, # 设置z轴数据为zz 53 | colorscale='RdYlBu_r')) # 设置颜色映射为红黄蓝反转 54 | 55 | ## 展示二维等高线图 56 | with st.expander('2D contour'): # 创建可展开部分,标题为“2D contour” 57 | st.plotly_chart(fig_1) # 在Streamlit中显示二维等高线图 58 | 59 | ## 展示三维表面图 60 | with st.expander('3D surface'): # 创建可展开部分,标题为“3D surface” 61 | st.plotly_chart(fig_2) # 在Streamlit中显示三维表面图 62 | -------------------------------------------------------------------------------- /Book4_Ch03_Python_Codes/Streamlit_Bk4_Ch03_03.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | ## 导入必要的库 10 | import plotly.graph_objects as go # 引入Plotly库,用于绘图 11 | import streamlit as st # 引入Streamlit库,用于创建交互式Web应用 12 | import numpy as np # 引入NumPy库,用于数值计算 13 | import plotly.express as px # 引入Plotly Express库,用于快速绘图 14 | import pandas as pd # 引入Pandas库,用于数据操作 15 | import sympy # 引入Sympy库,用于符号计算 16 | from scipy.spatial import distance # 引入SciPy库中的距离模块 17 | 18 | ## 定义距离计算函数 19 | # 定义计算Minkowski距离的函数 20 | # 如果设置Chebychev为True,则计算Chebychev距离,否则根据参数p计算Minkowski距离 21 | def fcn_Minkowski(xx, yy, mu, p=2, Chebychev=False): 22 | if Chebychev: # 如果选择Chebychev距离 23 | zz = np.maximum(np.abs(xx - mu[0]), np.abs(yy - mu[1])) # 计算Chebychev距离 24 | else: # 否则计算Minkowski距离 25 | zz = ((np.abs((xx - mu[0]))**p) + (np.abs((yy - mu[1]))**p))**(1. / p) # 计算公式 26 | return zz # 返回计算结果 27 | 28 | # 定义计算Mahalanobis距离的函数 29 | # 可以选择是否标准化Sigma矩阵 30 | 31 | def fcn_mahal(xx, yy, mu, Sigma, standardized=False): 32 | if standardized: # 如果选择标准化 33 | D = np.diag(np.diag(Sigma)) # 提取对角线元素 34 | Sigma_inv = np.linalg.inv(D) # 计算逆矩阵 35 | else: # 否则直接计算Sigma的逆矩阵 36 | Sigma_inv = np.linalg.inv(Sigma) 37 | xy_ = np.stack((xx.flatten(), yy.flatten())).T # 将输入数组展平并堆叠 38 | zz = np.diag(np.sqrt(np.dot(np.dot((xy_ - mu), Sigma_inv), (xy_ - mu).T))) # 计算Mahalanobis距离 39 | zz = np.reshape(zz, xx.shape) # 重塑计算结果为网格形状 40 | return zz # 返回计算结果 41 | 42 | ## 加载数据集 43 | # 使用Plotly自带的鸢尾花数据集 44 | 45 | df = px.data.iris() 46 | 47 | ## 创建侧边栏 48 | with st.sidebar: # 定义侧边栏区域 49 | dist_type = st.radio('Choose a type of distance: ', # 添加单选按钮选择距离类型 50 | options=['Euclidean', 'City block', 'Minkowski', 'Chebychev', 'Mahalanobis', 'Standardized Euclidean']) 51 | if dist_type == 'Minkowski': # 如果选择Minkowski距离 52 | with st.sidebar: # 添加滑块以选择p值 53 | p = st.slider('Specify a p value:', 1.0, 20.0, step=0.5) 54 | 55 | ## 计算距离 56 | X = df[['sepal_length', 'petal_length']] # 提取鸢尾花数据集中感兴趣的特征 57 | mu = X.mean().to_numpy() # 计算特征的均值 58 | Sigma = X.cov().to_numpy() # 计算特征的协方差矩阵 59 | x_array = np.linspace(0, 10, 101) # 定义x轴网格点 60 | y_array = np.linspace(0, 10, 101) # 定义y轴网格点 61 | xx, yy = np.meshgrid(x_array, y_array) # 创建二维网格 62 | 63 | if dist_type == 'Minkowski': # 如果选择Minkowski距离 64 | zz = fcn_Minkowski(xx, yy, mu, p) # 计算Minkowski距离 65 | elif dist_type == 'Euclidean': # 如果选择欧几里得距离 66 | zz = fcn_Minkowski(xx, yy, mu, 2) # 使用p=2计算Minkowski距离 67 | elif dist_type == 'Chebychev': # 如果选择Chebychev距离 68 | zz = fcn_Minkowski(xx, yy, mu, Chebychev=True) # 调用函数计算Chebychev距离 69 | elif dist_type == 'Mahalanobis': # 如果选择Mahalanobis距离 70 | zz = fcn_mahal(xx, yy, mu, Sigma) # 调用函数计算Mahalanobis距离 71 | elif dist_type == 'City block': # 如果选择曼哈顿距离 72 | zz = fcn_Minkowski(xx, yy, mu, 1) # 使用p=1计算Minkowski距离 73 | elif dist_type == 'Standardized Euclidean': # 如果选择标准化欧几里得距离 74 | zz = fcn_mahal(xx, yy, mu, Sigma, True) # 调用函数计算标准化欧几里得距离 75 | 76 | ## 数据可视化 77 | st.title(dist_type + ' distance') # 设置标题 78 | fig_2 = px.scatter(df, x='sepal_length', y='petal_length') # 绘制散点图 79 | fig_2.add_trace(go.Contour( # 添加等高线 80 | x=x_array, # 设置x轴网格点 81 | y=y_array, # 设置y轴网格点 82 | z=zz, # 设置计算的距离数据 83 | contours_coloring='lines', # 等高线的样式 84 | showscale=False)) # 不显示颜色条 85 | fig_2.add_traces( 86 | px.scatter(X.mean().to_frame().T, # 绘制均值点 87 | x='sepal_length', # x轴为花萼长度 88 | y='petal_length').update_traces( 89 | marker_size=20, # 设置标记大小 90 | marker_color="red", # 设置标记颜色 91 | marker_symbol='x').data) 92 | fig_2.update_layout(yaxis_range=[0, 10]) # 设置y轴范围 93 | fig_2.update_layout(xaxis_range=[0, 10]) # 设置x轴范围 94 | fig_2.add_hline(y=mu[1]) # 添加水平线 95 | fig_2.add_vline(x=mu[0]) # 添加垂直线 96 | fig_2.update_yaxes( 97 | scaleratio=1, # 设置y轴比例 98 | ) 99 | fig_2.update_layout(width=600, height=600) # 设置图形尺寸 100 | st.plotly_chart(fig_2) # 在Streamlit中显示图形 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /Book4_Ch03_向量范数__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch03_向量范数__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_01.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# NumPy数组\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "e8ae51ee-958b-484b-8ddc-fa7aad6bd2a5", 17 | "metadata": {}, 18 | "source": [ 19 | "这段代码演示了如何在 NumPy 中定义不同维度的数组和矩阵,并输出每种数据结构的形状和类型。首先定义一个 $2 \\times 2$ 的二维矩阵 $A_{\\text{matrix}}$:\n", 20 | "\n", 21 | "$$\n", 22 | "A_{\\text{matrix}} = \\begin{bmatrix} 2 & 4 \\\\ 6 & 8 \\end{bmatrix}\n", 23 | "$$\n", 24 | "\n", 25 | "其类型为 `np.matrix`,形状为 $(2, 2)$。\n", 26 | "\n", 27 | "接下来,定义了一维数组 $A_{\\text{1d}} = [2, 4]$,其形状为 $(2,)$,类型为 `np.ndarray`。然后定义一个二维数组 $A_{\\text{2d}}$,与 $A_{\\text{matrix}}$ 具有相同的数据内容和形状 $(2, 2)$,类型为 `np.ndarray`:\n", 28 | "\n", 29 | "$$\n", 30 | "A_{\\text{2d}} = \\begin{bmatrix} 2 & 4 \\\\ 6 & 8 \\end{bmatrix}\n", 31 | "$$\n", 32 | "\n", 33 | "最后,通过三个 $2 \\times 2$ 数组 $A1$、$A2$ 和 $A3$ 构建了一个三维数组 $A_{\\text{3d}}$:\n", 34 | "\n", 35 | "$$\n", 36 | "A_{\\text{3d}} = \\begin{bmatrix} \\begin{bmatrix} 2 & 4 \\\\ 6 & 8 \\end{bmatrix}, \\begin{bmatrix} 1 & 3 \\\\ 5 & 7 \\end{bmatrix}, \\begin{bmatrix} 1 & 0 \\\\ 0 & 1 \\end{bmatrix} \\end{bmatrix}\n", 37 | "$$\n", 38 | "\n", 39 | "三维数组的形状为 $(3, 2, 2)$,类型为 `np.ndarray`。这些定义展示了 NumPy 中矩阵和数组在一维、二维和三维空间的不同表示方式及其对应的形状信息。" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "id": "361fb77e-857e-4843-bfed-2b91753d3173", 45 | "metadata": {}, 46 | "source": [ 47 | "## 导入所需库" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 1, 53 | "id": "99f7bc75-95de-4ac9-8641-2f2d6446d5de", 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "import numpy as np # 导入NumPy库,用于数值计算" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "id": "3dad65f7-ba8f-4402-bbfc-379396517927", 63 | "metadata": {}, 64 | "source": [ 65 | "## 定义二维矩阵" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 2, 71 | "id": "ce746ee1-6041-49c9-964c-4ebc513ceda0", 72 | "metadata": {}, 73 | "outputs": [ 74 | { 75 | "data": { 76 | "text/plain": [ 77 | "matrix([[2, 4],\n", 78 | " [6, 8]])" 79 | ] 80 | }, 81 | "execution_count": 2, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "A_matrix = np.matrix([[2, 4], # 定义矩阵A_matrix\n", 88 | " [6, 8]])\n", 89 | "A_matrix" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 3, 95 | "id": "5eb2aa30-3537-48b7-9cd8-375b126ece82", 96 | "metadata": {}, 97 | "outputs": [ 98 | { 99 | "name": "stdout", 100 | "output_type": "stream", 101 | "text": [ 102 | "(2, 2)\n" 103 | ] 104 | } 105 | ], 106 | "source": [ 107 | "print(A_matrix.shape) # 输出矩阵的形状" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 4, 113 | "id": "28d1ad2b-e3e0-47c3-9e45-e47eaebf38e7", 114 | "metadata": {}, 115 | "outputs": [ 116 | { 117 | "name": "stdout", 118 | "output_type": "stream", 119 | "text": [ 120 | "\n" 121 | ] 122 | } 123 | ], 124 | "source": [ 125 | "print(type(A_matrix)) # 输出矩阵的类型" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "id": "8c571ccc-746f-4da0-9a4e-1b9868033465", 131 | "metadata": {}, 132 | "source": [ 133 | "## 定义一维数组" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 5, 139 | "id": "96121e32-ab22-4c8e-882e-698348bdd152", 140 | "metadata": {}, 141 | "outputs": [ 142 | { 143 | "data": { 144 | "text/plain": [ 145 | "array([2, 4])" 146 | ] 147 | }, 148 | "execution_count": 5, 149 | "metadata": {}, 150 | "output_type": "execute_result" 151 | } 152 | ], 153 | "source": [ 154 | "A_1d = np.array([2, 4]) # 定义一维数组A_1d\n", 155 | "A_1d" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 6, 161 | "id": "730a99d6-1623-4078-8cf2-90b22f28d966", 162 | "metadata": {}, 163 | "outputs": [ 164 | { 165 | "name": "stdout", 166 | "output_type": "stream", 167 | "text": [ 168 | "(2,)\n" 169 | ] 170 | } 171 | ], 172 | "source": [ 173 | "print(A_1d.shape) # 输出数组的形状" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 7, 179 | "id": "56457d26-1eca-4cec-b29b-7896f99ec064", 180 | "metadata": {}, 181 | "outputs": [ 182 | { 183 | "name": "stdout", 184 | "output_type": "stream", 185 | "text": [ 186 | "\n" 187 | ] 188 | } 189 | ], 190 | "source": [ 191 | "print(type(A_1d)) # 输出数组的类型" 192 | ] 193 | }, 194 | { 195 | "cell_type": "markdown", 196 | "id": "367612cb-9b72-405f-a55e-2fb950889246", 197 | "metadata": {}, 198 | "source": [ 199 | "## 定义二维数组" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 8, 205 | "id": "3196ea94-71bd-44a6-8079-812dd3c3757c", 206 | "metadata": {}, 207 | "outputs": [ 208 | { 209 | "data": { 210 | "text/plain": [ 211 | "array([[2, 4],\n", 212 | " [6, 8]])" 213 | ] 214 | }, 215 | "execution_count": 8, 216 | "metadata": {}, 217 | "output_type": "execute_result" 218 | } 219 | ], 220 | "source": [ 221 | "A_2d = np.array([[2, 4], # 定义二维数组A_2d\n", 222 | " [6, 8]])\n", 223 | "A_2d" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 9, 229 | "id": "b61ac04b-4060-44fb-ad4d-a171536b5411", 230 | "metadata": {}, 231 | "outputs": [ 232 | { 233 | "name": "stdout", 234 | "output_type": "stream", 235 | "text": [ 236 | "(2, 2)\n" 237 | ] 238 | } 239 | ], 240 | "source": [ 241 | "print(A_2d.shape) # 输出数组的形状" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 10, 247 | "id": "3a011d02-b22c-42a5-97e7-b652bc543ec0", 248 | "metadata": {}, 249 | "outputs": [ 250 | { 251 | "name": "stdout", 252 | "output_type": "stream", 253 | "text": [ 254 | "\n" 255 | ] 256 | } 257 | ], 258 | "source": [ 259 | "print(type(A_2d)) # 输出数组的类型" 260 | ] 261 | }, 262 | { 263 | "cell_type": "markdown", 264 | "id": "3bd3a633-c4f6-46cb-a325-fe0d9b28cf92", 265 | "metadata": {}, 266 | "source": [ 267 | "## 定义三维数组" 268 | ] 269 | }, 270 | { 271 | "cell_type": "code", 272 | "execution_count": 11, 273 | "id": "16daa0c8-c544-46ba-be31-eaa40ba2dbe4", 274 | "metadata": {}, 275 | "outputs": [], 276 | "source": [ 277 | "A1 = [[2, 4], # 定义第一个二维数组A1\n", 278 | " [6, 8]]" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 12, 284 | "id": "fc2603f8-e6e9-4f81-9918-fbbe49bf3127", 285 | "metadata": {}, 286 | "outputs": [], 287 | "source": [ 288 | "A2 = [[1, 3], # 定义第二个二维数组A2\n", 289 | " [5, 7]]" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": 13, 295 | "id": "51c45098-6ebd-44ea-8360-190b70b9ce41", 296 | "metadata": {}, 297 | "outputs": [], 298 | "source": [ 299 | "A3 = [[1, 0], # 定义第三个二维数组A3\n", 300 | " [0, 1]]" 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": 14, 306 | "id": "ba92b36b-bd5c-4df2-a829-982b292f0368", 307 | "metadata": {}, 308 | "outputs": [ 309 | { 310 | "data": { 311 | "text/plain": [ 312 | "array([[[2, 4],\n", 313 | " [6, 8]],\n", 314 | "\n", 315 | " [[1, 3],\n", 316 | " [5, 7]],\n", 317 | "\n", 318 | " [[1, 0],\n", 319 | " [0, 1]]])" 320 | ] 321 | }, 322 | "execution_count": 14, 323 | "metadata": {}, 324 | "output_type": "execute_result" 325 | } 326 | ], 327 | "source": [ 328 | "A_3d = np.array([A1, A2, A3]) # 将A1、A2和A3组合为三维数组A_3d\n", 329 | "A_3d" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 15, 335 | "id": "8687bb73-81ac-4ad4-9722-1bbbdc29fd28", 336 | "metadata": {}, 337 | "outputs": [ 338 | { 339 | "name": "stdout", 340 | "output_type": "stream", 341 | "text": [ 342 | "(3, 2, 2)\n" 343 | ] 344 | } 345 | ], 346 | "source": [ 347 | "print(A_3d.shape) # 输出三维数组的形状" 348 | ] 349 | }, 350 | { 351 | "cell_type": "code", 352 | "execution_count": 16, 353 | "id": "6e36a674-efa1-4584-8037-2b117ceece6f", 354 | "metadata": {}, 355 | "outputs": [ 356 | { 357 | "name": "stdout", 358 | "output_type": "stream", 359 | "text": [ 360 | "\n" 361 | ] 362 | } 363 | ], 364 | "source": [ 365 | "print(type(A_3d)) # 输出数组的类型" 366 | ] 367 | }, 368 | { 369 | "cell_type": "code", 370 | "execution_count": null, 371 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 372 | "metadata": {}, 373 | "outputs": [], 374 | "source": [] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": null, 379 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 380 | "metadata": {}, 381 | "outputs": [], 382 | "source": [] 383 | } 384 | ], 385 | "metadata": { 386 | "kernelspec": { 387 | "display_name": "Python 3 (ipykernel)", 388 | "language": "python", 389 | "name": "python3" 390 | }, 391 | "language_info": { 392 | "codemirror_mode": { 393 | "name": "ipython", 394 | "version": 3 395 | }, 396 | "file_extension": ".py", 397 | "mimetype": "text/x-python", 398 | "name": "python", 399 | "nbconvert_exporter": "python", 400 | "pygments_lexer": "ipython3", 401 | "version": "3.12.7" 402 | } 403 | }, 404 | "nbformat": 4, 405 | "nbformat_minor": 5 406 | } 407 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_02.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# diag() 函数\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "53c03812-0303-4691-9961-f87c9059705c", 17 | "metadata": {}, 18 | "source": [ 19 | "\n", 20 | "\n", 21 | "该代码首先定义了一个 $3 \\times 3$ 的矩阵 $A$:\n", 22 | "\n", 23 | "$$\n", 24 | "A = \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\\\ 7 & 8 & 9 \\end{bmatrix}\n", 25 | "$$\n", 26 | "\n", 27 | "然后,代码使用 `np.diag` 提取矩阵 $A$ 的对角元素,得到向量 $a = [1, 5, 9]$。接下来,通过向量 $a$ 构建了一个新的对角矩阵 $A_{\\text{diag}}$,其形式为:\n", 28 | "\n", 29 | "$$\n", 30 | "A_{\\text{diag}} = \\begin{bmatrix} 1 & 0 & 0 \\\\ 0 & 5 & 0 \\\\ 0 & 0 & 9 \\end{bmatrix}\n", 31 | "$$\n", 32 | "\n", 33 | "此过程展示了从一个矩阵中提取对角线元素并利用这些元素构造新的对角矩阵的操作。" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "id": "ccb1e0a3-d0ed-4996-9880-b08ba4918993", 39 | "metadata": {}, 40 | "source": [ 41 | "## 导入所需库" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 1, 47 | "id": "e1227d8c-7f70-48b9-af13-a17776aa8152", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "import numpy as np # 导入NumPy库,用于数值计算" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "id": "49b8f8e3-3955-48f6-ab9c-de1db5afbe2a", 57 | "metadata": {}, 58 | "source": [ 59 | "## 定义矩阵" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 2, 65 | "id": "c6358766-e0e7-480c-814e-c1ccfbae8e24", 66 | "metadata": {}, 67 | "outputs": [ 68 | { 69 | "data": { 70 | "text/plain": [ 71 | "matrix([[1, 2, 3],\n", 72 | " [4, 5, 6],\n", 73 | " [7, 8, 9]])" 74 | ] 75 | }, 76 | "execution_count": 2, 77 | "metadata": {}, 78 | "output_type": "execute_result" 79 | } 80 | ], 81 | "source": [ 82 | "A = np.matrix([[1, 2, 3], # 定义矩阵A\n", 83 | " [4, 5, 6],\n", 84 | " [7, 8, 9]])\n", 85 | "A " 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "id": "3a682155-7c02-4961-acb9-ab7a3c1b17e8", 91 | "metadata": {}, 92 | "source": [ 93 | "## 提取对角元素" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 3, 99 | "id": "7b2ea9e5-48fa-4b8f-ad4c-6b040817a15d", 100 | "metadata": {}, 101 | "outputs": [ 102 | { 103 | "data": { 104 | "text/plain": [ 105 | "array([1, 5, 9])" 106 | ] 107 | }, 108 | "execution_count": 3, 109 | "metadata": {}, 110 | "output_type": "execute_result" 111 | } 112 | ], 113 | "source": [ 114 | "a = np.diag(A) # 提取矩阵A的对角元素\n", 115 | "a" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "id": "f4e2f66a-370e-410a-ab12-c1f071662dc9", 121 | "metadata": {}, 122 | "source": [ 123 | "## 构造对角矩阵" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": 4, 129 | "id": "eea76f59-4071-47b4-b852-740f3df7045c", 130 | "metadata": {}, 131 | "outputs": [ 132 | { 133 | "data": { 134 | "text/plain": [ 135 | "array([[1, 0, 0],\n", 136 | " [0, 5, 0],\n", 137 | " [0, 0, 9]])" 138 | ] 139 | }, 140 | "execution_count": 4, 141 | "metadata": {}, 142 | "output_type": "execute_result" 143 | } 144 | ], 145 | "source": [ 146 | "A_diag = np.diag(a) # 使用对角元素a构造对角矩阵A_diag\n", 147 | "A_diag" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": null, 153 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 154 | "metadata": {}, 155 | "outputs": [], 156 | "source": [] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 162 | "metadata": {}, 163 | "outputs": [], 164 | "source": [] 165 | } 166 | ], 167 | "metadata": { 168 | "kernelspec": { 169 | "display_name": "Python 3 (ipykernel)", 170 | "language": "python", 171 | "name": "python3" 172 | }, 173 | "language_info": { 174 | "codemirror_mode": { 175 | "name": "ipython", 176 | "version": 3 177 | }, 178 | "file_extension": ".py", 179 | "mimetype": "text/x-python", 180 | "name": "python", 181 | "nbconvert_exporter": "python", 182 | "pygments_lexer": "ipython3", 183 | "version": "3.12.7" 184 | } 185 | }, 186 | "nbformat": 4, 187 | "nbformat_minor": 5 188 | } 189 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_03.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 矩阵加减法\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "a8042cab-e99c-4d94-a9be-96175baa837e", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码定义了两个 $2 \\times 2$ 矩阵 $A$ 和 $B$,分别为:\n", 20 | "\n", 21 | "$$\n", 22 | "A = \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\end{bmatrix}, \\quad B = \\begin{bmatrix} 2 & 6 \\\\ 4 & 8 \\end{bmatrix}\n", 23 | "$$\n", 24 | "\n", 25 | "代码随后计算了矩阵 $A$ 和 $B$ 的加法与减法。矩阵加法 $A + B$ 的结果为:\n", 26 | "\n", 27 | "$$\n", 28 | "A + B = \\begin{bmatrix} 1+2 & 2+6 \\\\ 3+4 & 4+8 \\end{bmatrix} = \\begin{bmatrix} 3 & 8 \\\\ 7 & 12 \\end{bmatrix}\n", 29 | "$$\n", 30 | "\n", 31 | "矩阵减法 $A - B$ 的结果为:\n", 32 | "\n", 33 | "$$\n", 34 | "A - B = \\begin{bmatrix} 1-2 & 2-6 \\\\ 3-4 & 4-8 \\end{bmatrix} = \\begin{bmatrix} -1 & -4 \\\\ -1 & -4 \\end{bmatrix}\n", 35 | "$$\n", 36 | "\n", 37 | "代码展示了使用 `np.add` 和 `np.subtract` 函数以及直接使用操作符完成矩阵加减法的两种实现方式。" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "id": "05fbf711-6eee-49a5-a5a5-a00c9726e60e", 43 | "metadata": {}, 44 | "source": [ 45 | "## 导入所需库" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 1, 51 | "id": "ced7d4cd-a41e-4a61-b8eb-a5221ac81fcf", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "import numpy as np # 导入NumPy库,用于数值计算" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "id": "f2afe209-4fad-4614-9697-2c8dcee0ac98", 61 | "metadata": {}, 62 | "source": [ 63 | "## 定义矩阵" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 2, 69 | "id": "7c955d5b-6e3b-4ae8-b162-16e5b739b31a", 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "matrix([[1, 2],\n", 76 | " [3, 4]])" 77 | ] 78 | }, 79 | "execution_count": 2, 80 | "metadata": {}, 81 | "output_type": "execute_result" 82 | } 83 | ], 84 | "source": [ 85 | "A = np.matrix([[1, 2], \n", 86 | " [3, 4]]) # 定义矩阵A\n", 87 | "A" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 3, 93 | "id": "7d16a094-2bae-46e1-b98c-35e1a1cbabba", 94 | "metadata": {}, 95 | "outputs": [ 96 | { 97 | "data": { 98 | "text/plain": [ 99 | "matrix([[2, 6],\n", 100 | " [4, 8]])" 101 | ] 102 | }, 103 | "execution_count": 3, 104 | "metadata": {}, 105 | "output_type": "execute_result" 106 | } 107 | ], 108 | "source": [ 109 | "B = np.matrix([[2, 6], \n", 110 | " [4, 8]]) # 定义矩阵B\n", 111 | "B" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "id": "83b0d359-e7e0-45ed-9241-b5643ec9a631", 117 | "metadata": {}, 118 | "source": [ 119 | "## 矩阵加法" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 4, 125 | "id": "476f434f-f285-47f2-b444-240bf970142d", 126 | "metadata": {}, 127 | "outputs": [ 128 | { 129 | "data": { 130 | "text/plain": [ 131 | "matrix([[ 3, 8],\n", 132 | " [ 7, 12]])" 133 | ] 134 | }, 135 | "execution_count": 4, 136 | "metadata": {}, 137 | "output_type": "execute_result" 138 | } 139 | ], 140 | "source": [ 141 | "A_plus_B = np.add(A, B) # 使用np.add函数计算矩阵A和B的和\n", 142 | "A_plus_B" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 5, 148 | "id": "dbeb5ab0-70f7-4c11-9ba4-86fceeade833", 149 | "metadata": {}, 150 | "outputs": [ 151 | { 152 | "data": { 153 | "text/plain": [ 154 | "matrix([[ 3, 8],\n", 155 | " [ 7, 12]])" 156 | ] 157 | }, 158 | "execution_count": 5, 159 | "metadata": {}, 160 | "output_type": "execute_result" 161 | } 162 | ], 163 | "source": [ 164 | "A_plus_B_2 = A + B # 使用加法操作符计算矩阵A和B的和\n", 165 | "A_plus_B_2" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "id": "8d40792e-8cd1-4d9a-a372-38bf758f6f6e", 171 | "metadata": {}, 172 | "source": [ 173 | "## 矩阵减法" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 6, 179 | "id": "d1535c49-e64c-4503-8655-405263614ae6", 180 | "metadata": {}, 181 | "outputs": [ 182 | { 183 | "data": { 184 | "text/plain": [ 185 | "matrix([[-1, -4],\n", 186 | " [-1, -4]])" 187 | ] 188 | }, 189 | "execution_count": 6, 190 | "metadata": {}, 191 | "output_type": "execute_result" 192 | } 193 | ], 194 | "source": [ 195 | "A_minus_B = np.subtract(A, B) # 使用np.subtract函数计算矩阵A和B的差\n", 196 | "A_minus_B" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 7, 202 | "id": "32372955-1f18-4c2f-bcb7-fc734e608328", 203 | "metadata": {}, 204 | "outputs": [ 205 | { 206 | "data": { 207 | "text/plain": [ 208 | "matrix([[-1, -4],\n", 209 | " [-1, -4]])" 210 | ] 211 | }, 212 | "execution_count": 7, 213 | "metadata": {}, 214 | "output_type": "execute_result" 215 | } 216 | ], 217 | "source": [ 218 | "A_minus_B_2 = A - B # 使用减法操作符计算矩阵A和B的差\n", 219 | "A_minus_B_2" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": null, 225 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 226 | "metadata": {}, 227 | "outputs": [], 228 | "source": [] 229 | }, 230 | { 231 | "cell_type": "code", 232 | "execution_count": null, 233 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 234 | "metadata": {}, 235 | "outputs": [], 236 | "source": [] 237 | } 238 | ], 239 | "metadata": { 240 | "kernelspec": { 241 | "display_name": "Python 3 (ipykernel)", 242 | "language": "python", 243 | "name": "python3" 244 | }, 245 | "language_info": { 246 | "codemirror_mode": { 247 | "name": "ipython", 248 | "version": 3 249 | }, 250 | "file_extension": ".py", 251 | "mimetype": "text/x-python", 252 | "name": "python", 253 | "nbconvert_exporter": "python", 254 | "pygments_lexer": "ipython3", 255 | "version": "3.12.7" 256 | } 257 | }, 258 | "nbformat": 4, 259 | "nbformat_minor": 5 260 | } 261 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_04.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 矩阵标量乘法\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "0cf4bb7f-f36d-486a-9187-a6f4f7ec18ba", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码定义了一个标量 $k = 2$ 和一个 $2 \\times 2$ 矩阵 $X$:\n", 20 | "\n", 21 | "$$\n", 22 | "X = \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\end{bmatrix}\n", 23 | "$$\n", 24 | "\n", 25 | "代码随后计算了标量 $k$ 与矩阵 $X$ 的乘积,得到的结果矩阵 $k \\times X$ 为:\n", 26 | "\n", 27 | "$$\n", 28 | "k \\times X = 2 \\times \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\end{bmatrix} = \\begin{bmatrix} 2 & 4 \\\\ 6 & 8 \\end{bmatrix}\n", 29 | "$$\n", 30 | "\n", 31 | "代码展示了使用 `np.dot` 函数和直接标量乘法来实现标量与矩阵乘积的两种方法。" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "id": "9b646351-bc61-4c43-96ed-a265eb25eaac", 37 | "metadata": {}, 38 | "source": [ 39 | "## 导入所需库" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 1, 45 | "id": "9a74e2ab-fc70-43a4-85f6-3ddeeacfc5ab", 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "import numpy as np # 导入NumPy库,用于数值计算" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "id": "6bf76475-2000-4adb-82bf-33664ee781da", 55 | "metadata": {}, 56 | "source": [ 57 | "## 定义标量和矩阵" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 2, 63 | "id": "e74e9afd-6c86-4ccd-bd9e-4382bfe0c31f", 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "k = 2 # 定义标量k" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 3, 73 | "id": "db0ca529-60e7-4093-8942-8976a5bc8b29", 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [ 77 | "X = [[1, 2], \n", 78 | " [3, 4]] # 定义矩阵X" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "id": "8a306144-ae4b-4b29-9b1a-9a4282ef2f21", 84 | "metadata": {}, 85 | "source": [ 86 | "## 标量与矩阵的乘法" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 4, 92 | "id": "33380485-bdda-4392-8ace-7e11690f111b", 93 | "metadata": {}, 94 | "outputs": [ 95 | { 96 | "data": { 97 | "text/plain": [ 98 | "array([[2, 4],\n", 99 | " [6, 8]])" 100 | ] 101 | }, 102 | "execution_count": 4, 103 | "metadata": {}, 104 | "output_type": "execute_result" 105 | } 106 | ], 107 | "source": [ 108 | "k_times_X = np.dot(k, X) # 使用np.dot计算k和X的标量乘法\n", 109 | "k_times_X" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 5, 115 | "id": "be39b596-ea34-4108-9447-e3a46d21f91c", 116 | "metadata": {}, 117 | "outputs": [ 118 | { 119 | "data": { 120 | "text/plain": [ 121 | "matrix([[2, 4],\n", 122 | " [6, 8]])" 123 | ] 124 | }, 125 | "execution_count": 5, 126 | "metadata": {}, 127 | "output_type": "execute_result" 128 | } 129 | ], 130 | "source": [ 131 | "k_times_X_2 = k * np.matrix(X) # 使用*操作符计算k和X的标量乘法\n", 132 | "k_times_X_2" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 139 | "metadata": {}, 140 | "outputs": [], 141 | "source": [] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [] 150 | } 151 | ], 152 | "metadata": { 153 | "kernelspec": { 154 | "display_name": "Python 3 (ipykernel)", 155 | "language": "python", 156 | "name": "python3" 157 | }, 158 | "language_info": { 159 | "codemirror_mode": { 160 | "name": "ipython", 161 | "version": 3 162 | }, 163 | "file_extension": ".py", 164 | "mimetype": "text/x-python", 165 | "name": "python", 166 | "nbconvert_exporter": "python", 167 | "pygments_lexer": "ipython3", 168 | "version": "3.12.7" 169 | } 170 | }, 171 | "nbformat": 4, 172 | "nbformat_minor": 5 173 | } 174 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_05.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 广播机制\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "61a42cc1-9923-4983-973d-b03b59d6acc1", 17 | "metadata": {}, 18 | "source": [ 19 | "这段代码展示了 NumPy 的广播机制,通过定义矩阵、标量、列向量和行向量进行一系列加法操作。代码首先定义了一个 $3 \\times 2$ 的矩阵 $A$、一个标量 $k$、一个列向量 $c$ 和一个行向量 $r$。它们的具体定义如下:\n", 20 | "\n", 21 | "$$\n", 22 | "A = \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\\\ 5 & 6 \\end{bmatrix}, \\quad k = 2, \\quad c = \\begin{bmatrix} 3 \\\\ 2 \\\\ 1 \\end{bmatrix}, \\quad r = \\begin{bmatrix} 2 & 1 \\end{bmatrix}\n", 23 | "$$\n", 24 | "\n", 25 | "代码使用 NumPy 广播机制,分别计算以下几种加法操作:\n", 26 | "\n", 27 | "1. **矩阵 $A$ 与标量 $k$ 相加**:标量 $k$ 会广播到矩阵 $A$ 的每个元素,即每个元素都加上 $k$ 值。这种情况下,运算结果为:\n", 28 | "\n", 29 | " $$\n", 30 | " A + k = \\begin{bmatrix} 1+2 & 2+2 \\\\ 3+2 & 4+2 \\\\ 5+2 & 6+2 \\end{bmatrix} = \\begin{bmatrix} 3 & 4 \\\\ 5 & 6 \\\\ 7 & 8 \\end{bmatrix}\n", 31 | " $$\n", 32 | "\n", 33 | "2. **矩阵 $A$ 与列向量 $c$ 相加**:列向量 $c$ 被广播到矩阵 $A$ 的每一列,使得 $c$ 的每个元素与 $A$ 相同行的每个元素相加,得到:\n", 34 | "\n", 35 | " $$\n", 36 | " A + c = \\begin{bmatrix} 1+3 & 2+3 \\\\ 3+2 & 4+2 \\\\ 5+1 & 6+1 \\end{bmatrix} = \\begin{bmatrix} 4 & 5 \\\\ 5 & 6 \\\\ 6 & 7 \\end{bmatrix}\n", 37 | " $$\n", 38 | "\n", 39 | "3. **矩阵 $A$ 与行向量 $r$ 相加**:行向量 $r$ 被广播到矩阵 $A$ 的每一行,使得 $r$ 的每个元素与 $A$ 相同行的每个元素相加,结果为:\n", 40 | "\n", 41 | " $$\n", 42 | " A + r = \\begin{bmatrix} 1+2 & 2+1 \\\\ 3+2 & 4+1 \\\\ 5+2 & 6+1 \\end{bmatrix} = \\begin{bmatrix} 3 & 3 \\\\ 5 & 5 \\\\ 7 & 7 \\end{bmatrix}\n", 43 | " $$\n", 44 | "\n", 45 | "4. **列向量 $c$ 与行向量 $r$ 相加**:通过广播,$c$ 和 $r$ 组合成一个 $3 \\times 2$ 的矩阵。每个 $c$ 的元素加到每一行的 $r$ 上,得到:\n", 46 | "\n", 47 | " $$\n", 48 | " c + r = \\begin{bmatrix} 3+2 & 3+1 \\\\ 2+2 & 2+1 \\\\ 1+2 & 1+1 \\end{bmatrix} = \\begin{bmatrix} 5 & 4 \\\\ 4 & 3 \\\\ 3 & 2 \\end{bmatrix}\n", 49 | " $$\n", 50 | "\n", 51 | "该代码展示了 NumPy 广播机制的灵活性,使得矩阵、向量和标量间的加法运算在不同维度下可以直接进行。" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "id": "dbbb9e8f-480a-4b84-be1c-10299faa79c3", 57 | "metadata": {}, 58 | "source": [ 59 | "## 导入所需库" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 1, 65 | "id": "2da2788b-62a1-4402-bcc8-7c4448392cb3", 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "import numpy as np # 导入NumPy库,用于数值计算" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "id": "371997be-719d-416d-9e23-6c0c9ae9bc96", 75 | "metadata": {}, 76 | "source": [ 77 | "## 定义矩阵" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 2, 83 | "id": "7acefee2-ddb0-4ec5-924e-b15c468f3bda", 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "data": { 88 | "text/plain": [ 89 | "matrix([[1, 2],\n", 90 | " [3, 4],\n", 91 | " [5, 6]])" 92 | ] 93 | }, 94 | "execution_count": 2, 95 | "metadata": {}, 96 | "output_type": "execute_result" 97 | } 98 | ], 99 | "source": [ 100 | "A = np.matrix([[1, 2], # 定义矩阵A\n", 101 | " [3, 4],\n", 102 | " [5, 6]])\n", 103 | "A" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "id": "6a695575-9a76-41e6-bb17-6d77d1dbca49", 109 | "metadata": {}, 110 | "source": [ 111 | "## 定义标量" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 3, 117 | "id": "7b44157d-b5c4-450c-b5a9-8c17ec1fb9fc", 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "k = 2 # 定义标量k" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "id": "950972dd-22ff-4a81-9793-2172ba4cc752", 127 | "metadata": {}, 128 | "source": [ 129 | "## 定义列向量" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 4, 135 | "id": "f59ea6bd-d607-48cf-8a7f-80eb5aac438c", 136 | "metadata": {}, 137 | "outputs": [ 138 | { 139 | "data": { 140 | "text/plain": [ 141 | "array([[3],\n", 142 | " [2],\n", 143 | " [1]])" 144 | ] 145 | }, 146 | "execution_count": 4, 147 | "metadata": {}, 148 | "output_type": "execute_result" 149 | } 150 | ], 151 | "source": [ 152 | "c = np.array([[3], # 定义列向量c\n", 153 | " [2],\n", 154 | " [1]])\n", 155 | "c" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "id": "1a4a65e0-ce82-414a-990b-64713bca3913", 161 | "metadata": {}, 162 | "source": [ 163 | "## 定义行向量" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": 5, 169 | "id": "c571bb39-d6b7-44ea-b5d7-2b197223eb5f", 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "data": { 174 | "text/plain": [ 175 | "array([[2, 1]])" 176 | ] 177 | }, 178 | "execution_count": 5, 179 | "metadata": {}, 180 | "output_type": "execute_result" 181 | } 182 | ], 183 | "source": [ 184 | "r = np.array([[2, 1]]) # 定义行向量r\n", 185 | "r" 186 | ] 187 | }, 188 | { 189 | "cell_type": "markdown", 190 | "id": "7a7d2094-3824-4efa-a099-40781551d1ff", 191 | "metadata": {}, 192 | "source": [ 193 | "## 广播原则" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "id": "82e777a0-142f-4a7d-b3e1-2e38af1fe399", 199 | "metadata": {}, 200 | "source": [ 201 | "## 矩阵A加标量k" 202 | ] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": 6, 207 | "id": "c7c158d0-9576-471c-953f-8767f19d9473", 208 | "metadata": {}, 209 | "outputs": [ 210 | { 211 | "data": { 212 | "text/plain": [ 213 | "matrix([[3, 4],\n", 214 | " [5, 6],\n", 215 | " [7, 8]])" 216 | ] 217 | }, 218 | "execution_count": 6, 219 | "metadata": {}, 220 | "output_type": "execute_result" 221 | } 222 | ], 223 | "source": [ 224 | "A_plus_k = A + k # 矩阵A与标量k相加\n", 225 | "A_plus_k" 226 | ] 227 | }, 228 | { 229 | "cell_type": "markdown", 230 | "id": "07c8aa0c-d857-4267-a1b7-99c7fc856f6d", 231 | "metadata": {}, 232 | "source": [ 233 | "## 矩阵A加列向量c" 234 | ] 235 | }, 236 | { 237 | "cell_type": "code", 238 | "execution_count": 7, 239 | "id": "919ef4b1-d43d-4c1e-933c-f9c8fde768f1", 240 | "metadata": {}, 241 | "outputs": [ 242 | { 243 | "data": { 244 | "text/plain": [ 245 | "matrix([[4, 5],\n", 246 | " [5, 6],\n", 247 | " [6, 7]])" 248 | ] 249 | }, 250 | "execution_count": 7, 251 | "metadata": {}, 252 | "output_type": "execute_result" 253 | } 254 | ], 255 | "source": [ 256 | "A_plus_c = A + c # 矩阵A与列向量c相加\n", 257 | "A_plus_c" 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "id": "07bd091a-0642-400a-8fd2-57ea4588875a", 263 | "metadata": {}, 264 | "source": [ 265 | "## 矩阵A加行向量r" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 8, 271 | "id": "3a18f414-460e-452e-808e-47fd9d339345", 272 | "metadata": {}, 273 | "outputs": [ 274 | { 275 | "data": { 276 | "text/plain": [ 277 | "matrix([[3, 3],\n", 278 | " [5, 5],\n", 279 | " [7, 7]])" 280 | ] 281 | }, 282 | "execution_count": 8, 283 | "metadata": {}, 284 | "output_type": "execute_result" 285 | } 286 | ], 287 | "source": [ 288 | "A_plus_r = A + r # 矩阵A与行向量r相加\n", 289 | "A_plus_r" 290 | ] 291 | }, 292 | { 293 | "cell_type": "markdown", 294 | "id": "5fd72975-156a-46c3-abce-170467f5d416", 295 | "metadata": {}, 296 | "source": [ 297 | "## 列向量c加行向量r" 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "execution_count": 9, 303 | "id": "e5ad12d3-b203-4a4e-90c4-20b693dfa4a2", 304 | "metadata": {}, 305 | "outputs": [ 306 | { 307 | "data": { 308 | "text/plain": [ 309 | "array([[5, 4],\n", 310 | " [4, 3],\n", 311 | " [3, 2]])" 312 | ] 313 | }, 314 | "execution_count": 9, 315 | "metadata": {}, 316 | "output_type": "execute_result" 317 | } 318 | ], 319 | "source": [ 320 | "c_plus_r = c + r # 列向量c与行向量r相加\n", 321 | "c_plus_r" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": null, 327 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 328 | "metadata": {}, 329 | "outputs": [], 330 | "source": [] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": null, 335 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 336 | "metadata": {}, 337 | "outputs": [], 338 | "source": [] 339 | } 340 | ], 341 | "metadata": { 342 | "kernelspec": { 343 | "display_name": "Python 3 (ipykernel)", 344 | "language": "python", 345 | "name": "python3" 346 | }, 347 | "language_info": { 348 | "codemirror_mode": { 349 | "name": "ipython", 350 | "version": 3 351 | }, 352 | "file_extension": ".py", 353 | "mimetype": "text/x-python", 354 | "name": "python", 355 | "nbconvert_exporter": "python", 356 | "pygments_lexer": "ipython3", 357 | "version": "3.12.7" 358 | } 359 | }, 360 | "nbformat": 4, 361 | "nbformat_minor": 5 362 | } 363 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_06.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 矩阵乘法\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "f78179ac-736d-417f-964f-a079c966931d", 17 | "metadata": {}, 18 | "source": [ 19 | "\n", 20 | "\n", 21 | "该代码定义了两个 $2 \\times 2$ 的矩阵 $A$ 和 $B$,并计算了它们的矩阵乘积。矩阵 $A$ 和 $B$ 分别为:\n", 22 | "\n", 23 | "$$\n", 24 | "A = \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\end{bmatrix}, \\quad B = \\begin{bmatrix} 2 & 4 \\\\ 1 & 3 \\end{bmatrix}\n", 25 | "$$\n", 26 | "\n", 27 | "矩阵乘积 $A @ B$ 的计算结果为:\n", 28 | "\n", 29 | "$$\n", 30 | "A @ B = \\begin{bmatrix} 1 \\cdot 2 + 2 \\cdot 1 & 1 \\cdot 4 + 2 \\cdot 3 \\\\ 3 \\cdot 2 + 4 \\cdot 1 & 3 \\cdot 4 + 4 \\cdot 3 \\end{bmatrix} = \\begin{bmatrix} 4 & 10 \\\\ 10 & 24 \\end{bmatrix}\n", 31 | "$$\n", 32 | "\n", 33 | "代码中,矩阵乘法操作使用了 `np.matmul` 函数和 `@` 运算符两种方式。这展示了 NumPy 中进行矩阵乘法的两种等效方法。" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "id": "cc4e525d-60d4-4447-a29e-2e1ead9aa96e", 39 | "metadata": {}, 40 | "source": [ 41 | "## 导入所需库" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 1, 47 | "id": "80885172-f546-4973-add9-496ddb779de5", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "import numpy as np # 导入NumPy库,用于数值计算" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "id": "bef4a295-b3fe-493c-9baf-04b2a95d913e", 57 | "metadata": {}, 58 | "source": [ 59 | "## 定义两个矩阵" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 2, 65 | "id": "8abe8f8d-6398-4bb6-ac14-a1b1139873fd", 66 | "metadata": {}, 67 | "outputs": [ 68 | { 69 | "data": { 70 | "text/plain": [ 71 | "array([[1, 2],\n", 72 | " [3, 4]])" 73 | ] 74 | }, 75 | "execution_count": 2, 76 | "metadata": {}, 77 | "output_type": "execute_result" 78 | } 79 | ], 80 | "source": [ 81 | "A = np.array([[1, 2], # 定义矩阵A\n", 82 | " [3, 4]])\n", 83 | "A" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 3, 89 | "id": "dbb8337a-f940-4337-9a98-65692ff3e854", 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "data": { 94 | "text/plain": [ 95 | "array([[2, 4],\n", 96 | " [1, 3]])" 97 | ] 98 | }, 99 | "execution_count": 3, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "B = np.array([[2, 4], # 定义矩阵B\n", 106 | " [1, 3]])\n", 107 | "B" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "id": "fd37527e-b082-4899-a2fe-6b04c8db9fea", 113 | "metadata": {}, 114 | "source": [ 115 | "## 矩阵乘法" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 4, 121 | "id": "313d8fec-6e35-4e36-900f-efa4bd5c6adc", 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "text/plain": [ 127 | "array([[ 4, 10],\n", 128 | " [10, 24]])" 129 | ] 130 | }, 131 | "execution_count": 4, 132 | "metadata": {}, 133 | "output_type": "execute_result" 134 | } 135 | ], 136 | "source": [ 137 | "A_times_B = np.matmul(A, B) # 使用np.matmul计算矩阵A和B的乘积\n", 138 | "A_times_B" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 5, 144 | "id": "3efab8d4-012b-4f28-b515-d9047d180a89", 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "data": { 149 | "text/plain": [ 150 | "array([[ 4, 10],\n", 151 | " [10, 24]])" 152 | ] 153 | }, 154 | "execution_count": 5, 155 | "metadata": {}, 156 | "output_type": "execute_result" 157 | } 158 | ], 159 | "source": [ 160 | "A_times_B_2 = A @ B # 使用@操作符计算矩阵A和B的乘积\n", 161 | "A_times_B_2" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 168 | "metadata": {}, 169 | "outputs": [], 170 | "source": [] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [] 179 | } 180 | ], 181 | "metadata": { 182 | "kernelspec": { 183 | "display_name": "Python 3 (ipykernel)", 184 | "language": "python", 185 | "name": "python3" 186 | }, 187 | "language_info": { 188 | "codemirror_mode": { 189 | "name": "ipython", 190 | "version": 3 191 | }, 192 | "file_extension": ".py", 193 | "mimetype": "text/x-python", 194 | "name": "python", 195 | "nbconvert_exporter": "python", 196 | "pygments_lexer": "ipython3", 197 | "version": "3.12.7" 198 | } 199 | }, 200 | "nbformat": 4, 201 | "nbformat_minor": 5 202 | } 203 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_07.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 矩阵乘法操作\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "d134e1be-222a-4fec-b5d9-78dfd4fcb3cc", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码演示了 NumPy 中数组和矩阵的乘法操作,分别展示了逐元素乘法和矩阵乘法的不同结果。\n", 20 | "\n", 21 | "1. **逐元素乘法**:在第一个操作中,$A$ 和 $B$ 都是 `np.array` 类型。按逐元素方式进行乘法时,$A$ 将被广播到与 $B$ 形状相匹配,结果为:\n", 22 | "\n", 23 | " $$\n", 24 | " A \\odot B = \\begin{bmatrix} 1 \\times 5 & 2 \\times 6 \\\\ 1 \\times 8 & 2 \\times 9 \\end{bmatrix} = \\begin{bmatrix} 5 & 12 \\\\ 8 & 18 \\end{bmatrix}\n", 25 | " $$\n", 26 | "\n", 27 | "2. **矩阵乘法**:在第二个操作中,$A$ 为 `np.array` 类型,而 $B$ 为 `np.matrix` 类型。此时 `*` 操作符按矩阵乘法执行,计算结果为:\n", 28 | "\n", 29 | " $$\n", 30 | " A \\times B = \\begin{bmatrix} 1 \\times 5 + 2 \\times 8 & 1 \\times 6 + 2 \\times 9 \\end{bmatrix} = \\begin{bmatrix} 21 & 24 \\end{bmatrix}\n", 31 | " $$\n", 32 | "\n", 33 | "3. **矩阵乘法**:在第三个操作中,$A$ 和 $B$ 都是 `np.matrix` 类型,再次执行矩阵乘法,结果与第二个操作相同:\n", 34 | "\n", 35 | " $$\n", 36 | " A \\times B = \\begin{bmatrix} 21 & 24 \\end{bmatrix}\n", 37 | " $$\n", 38 | "\n", 39 | "此代码展示了在 NumPy 中 `np.array` 和 `np.matrix` 类型的不同行为及 `*` 操作符在逐元素和矩阵乘法间的区别。" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "id": "e694f73c-5da9-404b-930b-1b15c38c149e", 45 | "metadata": {}, 46 | "source": [ 47 | "## 导入所需库" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 1, 53 | "id": "04dd0c40-af12-47f6-8f60-1bba1b377b51", 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "import numpy as np # 导入NumPy库,用于数值计算" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "id": "9dab05d3-2be2-47c9-97a5-e1b779132a1f", 63 | "metadata": {}, 64 | "source": [ 65 | "## 定义数组A和B并进行逐元素乘法" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 2, 71 | "id": "87bb0d5c-67d8-4a10-95c8-c407a32932ad", 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "A = np.array([[1, 2]]) # 定义数组A" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 3, 81 | "id": "8b9a1b34-090e-4432-a096-d45934e8c0aa", 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "B = np.array([[5, 6], # 定义数组B\n", 86 | " [8, 9]])" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 4, 92 | "id": "ef365f07-ebfe-432e-9ea3-bc45cecc0335", 93 | "metadata": {}, 94 | "outputs": [ 95 | { 96 | "data": { 97 | "text/plain": [ 98 | "array([[ 5, 12],\n", 99 | " [ 8, 18]])" 100 | ] 101 | }, 102 | "execution_count": 4, 103 | "metadata": {}, 104 | "output_type": "execute_result" 105 | } 106 | ], 107 | "source": [ 108 | "A * B # 打印A和B的逐元素乘法结果" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "id": "00486c88-927e-4c24-b2be-d6f9e8672e0f", 114 | "metadata": {}, 115 | "source": [ 116 | "## 定义数组A和矩阵B并进行矩阵乘法" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 5, 122 | "id": "82d3c241-4790-40c4-aa1f-3a383250ba74", 123 | "metadata": {}, 124 | "outputs": [], 125 | "source": [ 126 | "A = np.array([[1, 2]]) # 定义数组A" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 6, 132 | "id": "e6298ff4-cf44-4851-a835-d22563bd4d1d", 133 | "metadata": {}, 134 | "outputs": [], 135 | "source": [ 136 | "B = np.matrix([[5, 6], # 定义矩阵B\n", 137 | " [8, 9]])" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": 7, 143 | "id": "c036b953-8d3d-443e-87eb-1fe46fcd6014", 144 | "metadata": {}, 145 | "outputs": [ 146 | { 147 | "data": { 148 | "text/plain": [ 149 | "matrix([[21, 24]])" 150 | ] 151 | }, 152 | "execution_count": 7, 153 | "metadata": {}, 154 | "output_type": "execute_result" 155 | } 156 | ], 157 | "source": [ 158 | "A * B # 打印A和B的矩阵乘法结果" 159 | ] 160 | }, 161 | { 162 | "cell_type": "markdown", 163 | "id": "ab903f71-3eb5-4290-a835-ae58622e69a4", 164 | "metadata": {}, 165 | "source": [ 166 | "## 定义矩阵A和矩阵B并进行矩阵乘法" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 8, 172 | "id": "ab60983c-0ad3-4263-ad82-84986df908d0", 173 | "metadata": {}, 174 | "outputs": [], 175 | "source": [ 176 | "A = np.matrix([[1, 2]]) # 定义矩阵A" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 9, 182 | "id": "6ccade11-529f-4962-8eab-139e08a62592", 183 | "metadata": {}, 184 | "outputs": [], 185 | "source": [ 186 | "B = np.matrix([[5, 6], # 定义矩阵B\n", 187 | " [8, 9]])" 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 10, 193 | "id": "e60a1889-600c-4982-9b61-3001d9fbd32f", 194 | "metadata": {}, 195 | "outputs": [ 196 | { 197 | "data": { 198 | "text/plain": [ 199 | "matrix([[21, 24]])" 200 | ] 201 | }, 202 | "execution_count": 10, 203 | "metadata": {}, 204 | "output_type": "execute_result" 205 | } 206 | ], 207 | "source": [ 208 | "A * B # 打印A和B的矩阵乘法结果" 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": null, 214 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 215 | "metadata": {}, 216 | "outputs": [], 217 | "source": [] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": null, 222 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 223 | "metadata": {}, 224 | "outputs": [], 225 | "source": [] 226 | } 227 | ], 228 | "metadata": { 229 | "kernelspec": { 230 | "display_name": "Python 3 (ipykernel)", 231 | "language": "python", 232 | "name": "python3" 233 | }, 234 | "language_info": { 235 | "codemirror_mode": { 236 | "name": "ipython", 237 | "version": 3 238 | }, 239 | "file_extension": ".py", 240 | "mimetype": "text/x-python", 241 | "name": "python", 242 | "nbconvert_exporter": "python", 243 | "pygments_lexer": "ipython3", 244 | "version": "3.12.7" 245 | } 246 | }, 247 | "nbformat": 4, 248 | "nbformat_minor": 5 249 | } 250 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_08.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 矩阵幂\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "82179f04-01ef-4824-a7ec-80be438ed9fd", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码演示了在 NumPy 中如何计算矩阵的三次幂与逐元素三次方的区别:\n", 20 | "\n", 21 | "1. **矩阵的三次幂**:通过 `matrix_power` 或连续的矩阵乘法 `A @ A @ A` 计算矩阵 $A$ 的三次幂。给定矩阵:\n", 22 | "\n", 23 | " $$\n", 24 | " A = \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\end{bmatrix}\n", 25 | " $$\n", 26 | "\n", 27 | " 其三次幂 $A^3$ 计算为:\n", 28 | "\n", 29 | " $$\n", 30 | " A^3 = A @ A @ A = \\begin{bmatrix} 37 & 54 \\\\ 81 & 118 \\end{bmatrix}\n", 31 | " $$\n", 32 | "\n", 33 | "2. **逐元素三次方**:`A ** 3` 计算的是矩阵 $A$ 每个元素的三次方,结果为:\n", 34 | "\n", 35 | " $$\n", 36 | " A \\odot A \\odot A = \\begin{bmatrix} 1^3 & 2^3 \\\\ 3^3 & 4^3 \\end{bmatrix} = \\begin{bmatrix} 1 & 8 \\\\ 27 & 64 \\end{bmatrix}\n", 37 | " $$\n", 38 | "\n", 39 | "代码展示了矩阵幂运算(整体矩阵相乘)和逐元素幂运算(每个元素单独运算)的区别。" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "id": "5a569286-52c7-4d2b-a1c1-57f1b89ba147", 45 | "metadata": {}, 46 | "source": [ 47 | "## 导入所需库" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 1, 53 | "id": "826fccd1-ad68-46f8-8229-75da1e8ddec8", 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "import numpy as np\n", 58 | "from numpy.linalg import matrix_power as pw # 导入矩阵幂函数" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "id": "f0390858-5fb8-4db6-8139-a9c6e98b48ec", 64 | "metadata": {}, 65 | "source": [ 66 | "## 定义矩阵" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 2, 72 | "id": "b358aa8f-44ad-4366-8fd5-9890ab983691", 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "A = np.array([[1., 2.], # 定义矩阵A\n", 77 | " [3., 4.]])" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "id": "1ee41f87-83e0-417e-8429-5650e71574c9", 83 | "metadata": {}, 84 | "source": [ 85 | "## 计算矩阵的三次幂" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 3, 91 | "id": "dcff939d-82f9-4098-ada3-81a6bf29e76d", 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "data": { 96 | "text/plain": [ 97 | "array([[ 37., 54.],\n", 98 | " [ 81., 118.]])" 99 | ] 100 | }, 101 | "execution_count": 3, 102 | "metadata": {}, 103 | "output_type": "execute_result" 104 | } 105 | ], 106 | "source": [ 107 | "A_3 = pw(A, 3) # 使用matrix_power计算矩阵A的三次幂\n", 108 | "A_3" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 4, 114 | "id": "fa89d52c-7726-4d10-b170-ddf0274aa160", 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "data": { 119 | "text/plain": [ 120 | "array([[ 37., 54.],\n", 121 | " [ 81., 118.]])" 122 | ] 123 | }, 124 | "execution_count": 4, 125 | "metadata": {}, 126 | "output_type": "execute_result" 127 | } 128 | ], 129 | "source": [ 130 | "A @ A @ A # 使用矩阵乘法逐步计算A的三次幂" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "id": "3290bcd6-38f4-449f-8dd0-4e51a00a7067", 136 | "metadata": {}, 137 | "source": [ 138 | "## 元素逐次三次方" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 5, 144 | "id": "9cf3a84f-d907-4e8e-b3e9-c0637c68bd97", 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "data": { 149 | "text/plain": [ 150 | "array([[ 1., 8.],\n", 151 | " [27., 64.]])" 152 | ] 153 | }, 154 | "execution_count": 5, 155 | "metadata": {}, 156 | "output_type": "execute_result" 157 | } 158 | ], 159 | "source": [ 160 | "A_3_piecewise = A ** 3 # 计算矩阵A的每个元素的三次方\n", 161 | "A_3_piecewise" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 168 | "metadata": {}, 169 | "outputs": [], 170 | "source": [] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [] 179 | } 180 | ], 181 | "metadata": { 182 | "kernelspec": { 183 | "display_name": "Python 3 (ipykernel)", 184 | "language": "python", 185 | "name": "python3" 186 | }, 187 | "language_info": { 188 | "codemirror_mode": { 189 | "name": "ipython", 190 | "version": 3 191 | }, 192 | "file_extension": ".py", 193 | "mimetype": "text/x-python", 194 | "name": "python", 195 | "nbconvert_exporter": "python", 196 | "pygments_lexer": "ipython3", 197 | "version": "3.12.7" 198 | } 199 | }, 200 | "nbformat": 4, 201 | "nbformat_minor": 5 202 | } 203 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_09.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 矩阵乘幂比较\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "f7cb8538-a1e9-4d16-9e49-6772327912c0", 17 | "metadata": {}, 18 | "source": [ 19 | "\n", 20 | "该代码展示了 `np.matrix` 和 `np.array` 在平方操作中的不同行为。\n", 21 | "\n", 22 | "1. **矩阵平方(`np.matrix` 类型)**:当 $A$ 是 `np.matrix` 类型时,`A**2` 计算的是矩阵乘法,即 $A @ A$。对于矩阵:\n", 23 | "\n", 24 | " $$\n", 25 | " A = \\begin{bmatrix} 1 & 3 \\\\ 2 & 4 \\end{bmatrix}\n", 26 | " $$\n", 27 | "\n", 28 | " 其平方 $A^2$ 计算为:\n", 29 | "\n", 30 | " $$\n", 31 | " A^2 = \\begin{bmatrix} 1 & 3 \\\\ 2 & 4 \\end{bmatrix} @ \\begin{bmatrix} 1 & 3 \\\\ 2 & 4 \\end{bmatrix} = \\begin{bmatrix} 7 & 15 \\\\ 10 & 22 \\end{bmatrix}\n", 32 | " $$\n", 33 | "\n", 34 | "2. **逐元素平方(`np.array` 类型)**:当 $B$ 是 `np.array` 类型时,`B**2` 计算的是逐元素平方,即每个元素单独平方。对于数组:\n", 35 | "\n", 36 | " $$\n", 37 | " B = \\begin{bmatrix} 1 & 3 \\\\ 2 & 4 \\end{bmatrix}\n", 38 | " $$\n", 39 | "\n", 40 | " 逐元素平方的结果为:\n", 41 | "\n", 42 | " $$\n", 43 | " B\\odot B = \\begin{bmatrix} 1^2 & 3^2 \\\\ 2^2 & 4^2 \\end{bmatrix} = \\begin{bmatrix} 1 & 9 \\\\ 4 & 16 \\end{bmatrix}\n", 44 | " $$\n", 45 | "\n", 46 | "此代码展示了 `np.matrix` 和 `np.array` 在平方操作上的关键差异:一个执行矩阵乘法,另一个进行逐元素运算。" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "id": "9734eeec-2b37-40f9-add5-c4ccd409546a", 52 | "metadata": {}, 53 | "source": [ 54 | "## 导入所需库" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 1, 60 | "id": "4b42a3b3-504c-45eb-8c6b-2830e6a11be8", 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "import numpy as np # 导入NumPy库,用于数值计算" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "id": "79f50411-80c3-487e-b20d-e42867cea09a", 70 | "metadata": {}, 71 | "source": [ 72 | "## 定义矩阵A并计算其矩阵平方" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 2, 78 | "id": "5879a711-cd82-4352-a41f-c9b950865d71", 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [ 82 | "A = np.matrix([[1, 3], # 定义为np.matrix类型的矩阵A\n", 83 | " [2, 4]])" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 3, 89 | "id": "02a0e4c0-e50d-4955-8e72-351468e22d57", 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "name": "stdout", 94 | "output_type": "stream", 95 | "text": [ 96 | "[[ 7 15]\n", 97 | " [10 22]]\n" 98 | ] 99 | } 100 | ], 101 | "source": [ 102 | "print(A**2) # 打印矩阵A的矩阵平方结果" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "id": "8dee9c28-b297-4f4d-9f0b-b0c8880d792e", 108 | "metadata": {}, 109 | "source": [ 110 | "## 定义数组B并计算其逐元素平方" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 4, 116 | "id": "7ab6ed46-fca3-46de-aa69-8d1a16b67d24", 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "B = np.array([[1, 3], # 定义为np.array类型的数组B\n", 121 | " [2, 4]])" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 5, 127 | "id": "8e1194bb-59fa-40a2-b0a2-e2c85b7cc667", 128 | "metadata": {}, 129 | "outputs": [ 130 | { 131 | "name": "stdout", 132 | "output_type": "stream", 133 | "text": [ 134 | "[[ 1 9]\n", 135 | " [ 4 16]]\n" 136 | ] 137 | } 138 | ], 139 | "source": [ 140 | "print(B**2) # 打印数组B的逐元素平方结果" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": null, 154 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 155 | "metadata": {}, 156 | "outputs": [], 157 | "source": [] 158 | } 159 | ], 160 | "metadata": { 161 | "kernelspec": { 162 | "display_name": "Python 3 (ipykernel)", 163 | "language": "python", 164 | "name": "python3" 165 | }, 166 | "language_info": { 167 | "codemirror_mode": { 168 | "name": "ipython", 169 | "version": 3 170 | }, 171 | "file_extension": ".py", 172 | "mimetype": "text/x-python", 173 | "name": "python", 174 | "nbconvert_exporter": "python", 175 | "pygments_lexer": "ipython3", 176 | "version": "3.12.7" 177 | } 178 | }, 179 | "nbformat": 4, 180 | "nbformat_minor": 5 181 | } 182 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_10.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 转置\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "34fd7eb5-f8ae-40eb-832c-23f93d07cfeb", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码定义了一个 $3 \\times 2$ 矩阵 $A$,并计算其转置矩阵。矩阵 $A$ 定义为:\n", 20 | "\n", 21 | "$$\n", 22 | "A = \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\\\ 5 & 6 \\end{bmatrix}\n", 23 | "$$\n", 24 | "\n", 25 | "矩阵的转置 $A^T$ 将行变为列,结果为一个 $2 \\times 3$ 的矩阵:\n", 26 | "\n", 27 | "$$\n", 28 | "A^T = \\begin{bmatrix} 1 & 3 & 5 \\\\ 2 & 4 & 6 \\end{bmatrix}\n", 29 | "$$\n", 30 | "\n", 31 | "代码使用了两种方法来计算转置矩阵:`A.transpose()` 方法和 `A.T` 属性,二者等效。这段代码展示了如何在 NumPy 中对矩阵进行转置操作。" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "id": "4562dc5f-106d-458a-9c21-058f45dc7750", 37 | "metadata": {}, 38 | "source": [ 39 | "## 导入所需库" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 1, 45 | "id": "492fc116-d1e3-404a-92fc-92bf126234a5", 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "import numpy as np # 导入NumPy库,用于数值计算" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "id": "58efb734-2fce-475e-a954-2ff78a1bf71f", 55 | "metadata": {}, 56 | "source": [ 57 | "## 定义矩阵A" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 2, 63 | "id": "1581437b-c937-42fc-b1f1-c176a48b0a33", 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "data": { 68 | "text/plain": [ 69 | "array([[1, 2],\n", 70 | " [3, 4],\n", 71 | " [5, 6]])" 72 | ] 73 | }, 74 | "execution_count": 2, 75 | "metadata": {}, 76 | "output_type": "execute_result" 77 | } 78 | ], 79 | "source": [ 80 | "A = np.array([[1, 2], # 定义矩阵A\n", 81 | " [3, 4],\n", 82 | " [5, 6]])\n", 83 | "A" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "id": "13eeb291-b311-4823-a983-c9749695b2e2", 89 | "metadata": {}, 90 | "source": [ 91 | "## 计算矩阵的转置" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 3, 97 | "id": "d34daecc-75e6-4f6f-9af7-d506d9d73eb9", 98 | "metadata": {}, 99 | "outputs": [ 100 | { 101 | "data": { 102 | "text/plain": [ 103 | "array([[1, 3, 5],\n", 104 | " [2, 4, 6]])" 105 | ] 106 | }, 107 | "execution_count": 3, 108 | "metadata": {}, 109 | "output_type": "execute_result" 110 | } 111 | ], 112 | "source": [ 113 | "A_T = A.transpose() # 使用transpose方法计算A的转置\n", 114 | "A_T" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 4, 120 | "id": "5ac7a53b-8e59-40ee-a2d8-dafe251f386d", 121 | "metadata": {}, 122 | "outputs": [ 123 | { 124 | "data": { 125 | "text/plain": [ 126 | "array([[1, 3, 5],\n", 127 | " [2, 4, 6]])" 128 | ] 129 | }, 130 | "execution_count": 4, 131 | "metadata": {}, 132 | "output_type": "execute_result" 133 | } 134 | ], 135 | "source": [ 136 | "A_T_2 = A.T # 使用.T属性计算A的转置\n", 137 | "A_T_2" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 144 | "metadata": {}, 145 | "outputs": [], 146 | "source": [] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": null, 151 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 152 | "metadata": {}, 153 | "outputs": [], 154 | "source": [] 155 | } 156 | ], 157 | "metadata": { 158 | "kernelspec": { 159 | "display_name": "Python 3 (ipykernel)", 160 | "language": "python", 161 | "name": "python3" 162 | }, 163 | "language_info": { 164 | "codemirror_mode": { 165 | "name": "ipython", 166 | "version": 3 167 | }, 168 | "file_extension": ".py", 169 | "mimetype": "text/x-python", 170 | "name": "python", 171 | "nbconvert_exporter": "python", 172 | "pygments_lexer": "ipython3", 173 | "version": "3.12.7" 174 | } 175 | }, 176 | "nbformat": 4, 177 | "nbformat_minor": 5 178 | } 179 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_11.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 矩阵逆\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "17664ff7-4c6b-4539-80c1-07f98b6ef2c2", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码定义了一个 $2 \\times 2$ 矩阵 $A$,并计算其逆矩阵 $A^{-1}$。矩阵 $A$ 为:\n", 20 | "\n", 21 | "$$\n", 22 | "A = \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\end{bmatrix}\n", 23 | "$$\n", 24 | "\n", 25 | "通过求逆操作得到 $A$ 的逆矩阵:\n", 26 | "\n", 27 | "$$\n", 28 | "A^{-1} = \\begin{bmatrix} -2 & 1 \\\\ 1.5 & -0.5 \\end{bmatrix}\n", 29 | "$$\n", 30 | "\n", 31 | "接下来,代码计算矩阵 $A$ 与其逆矩阵 $A^{-1}$ 的乘积,理论上应得到单位矩阵:\n", 32 | "\n", 33 | "$$\n", 34 | "A @ A^{-1} = \\begin{bmatrix} 1 & 0 \\\\ 0 & 1 \\end{bmatrix}\n", 35 | "$$\n", 36 | "\n", 37 | "这段代码展示了如何使用 `inv` 函数计算矩阵的逆,并验证矩阵与其逆矩阵的乘积结果。" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "id": "1feaec35-bb29-42b9-a011-ad9135b0c638", 43 | "metadata": {}, 44 | "source": [ 45 | "## 导入所需库" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 1, 51 | "id": "5d2a42fe-89e9-4736-b847-a7433aece846", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "import numpy as np\n", 56 | "from numpy.linalg import inv # 导入矩阵求逆函数" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "id": "8ed902be-675e-4438-b550-dbbbf9cf6a66", 62 | "metadata": {}, 63 | "source": [ 64 | "## 定义矩阵A" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 2, 70 | "id": "d8339162-83a4-47b2-9d41-2203ab292820", 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "data": { 75 | "text/plain": [ 76 | "array([[1., 2.],\n", 77 | " [3., 4.]])" 78 | ] 79 | }, 80 | "execution_count": 2, 81 | "metadata": {}, 82 | "output_type": "execute_result" 83 | } 84 | ], 85 | "source": [ 86 | "A = np.array([[1., 2.], # 定义矩阵A\n", 87 | " [3., 4.]])\n", 88 | "A" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "id": "fb5a51d4-624e-48fb-b792-54c433bb0df9", 94 | "metadata": {}, 95 | "source": [ 96 | "## 计算矩阵的逆" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 4, 102 | "id": "dee6461e-cf77-4d73-b4a2-552c0bbe4fa7", 103 | "metadata": {}, 104 | "outputs": [ 105 | { 106 | "data": { 107 | "text/plain": [ 108 | "array([[-2. , 1. ],\n", 109 | " [ 1.5, -0.5]])" 110 | ] 111 | }, 112 | "execution_count": 4, 113 | "metadata": {}, 114 | "output_type": "execute_result" 115 | } 116 | ], 117 | "source": [ 118 | "A_inverse = inv(A) # 计算矩阵A的逆\n", 119 | "A_inverse" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 5, 125 | "id": "ff4c814d-c6e7-416a-b027-0a2a28ef8ba1", 126 | "metadata": {}, 127 | "outputs": [ 128 | { 129 | "data": { 130 | "text/plain": [ 131 | "array([[1.00000000e+00, 1.11022302e-16],\n", 132 | " [0.00000000e+00, 1.00000000e+00]])" 133 | ] 134 | }, 135 | "execution_count": 5, 136 | "metadata": {}, 137 | "output_type": "execute_result" 138 | } 139 | ], 140 | "source": [ 141 | "A_times_A_inv = A @ A_inverse # 计算矩阵A与其逆矩阵的乘积\n", 142 | "A_times_A_inv" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 149 | "metadata": {}, 150 | "outputs": [], 151 | "source": [] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [] 160 | } 161 | ], 162 | "metadata": { 163 | "kernelspec": { 164 | "display_name": "Python 3 (ipykernel)", 165 | "language": "python", 166 | "name": "python3" 167 | }, 168 | "language_info": { 169 | "codemirror_mode": { 170 | "name": "ipython", 171 | "version": 3 172 | }, 173 | "file_extension": ".py", 174 | "mimetype": "text/x-python", 175 | "name": "python", 176 | "nbconvert_exporter": "python", 177 | "pygments_lexer": "ipython3", 178 | "version": "3.12.7" 179 | } 180 | }, 181 | "nbformat": 4, 182 | "nbformat_minor": 5 183 | } 184 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_12.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 矩阵逆\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "c83af894-1177-41f1-9e0c-5df36a5e4755", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码演示了 `np.matrix` 和 `np.array` 在计算矩阵逆时的区别。矩阵 $A$ 被定义为 `np.matrix` 类型,直接使用 `.I` 属性即可求逆;而矩阵 $B$ 被定义为 `np.array` 类型,不支持 `.I` 属性,因此会报错。\n", 20 | "\n", 21 | "矩阵 $A$ 的定义为:\n", 22 | "\n", 23 | "$$\n", 24 | "A = \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\end{bmatrix}\n", 25 | "$$\n", 26 | "\n", 27 | "其逆矩阵为:\n", 28 | "\n", 29 | "$$\n", 30 | "A^{-1} = \\begin{bmatrix} -2 & 1 \\\\ 1.5 & -0.5 \\end{bmatrix}\n", 31 | "$$\n", 32 | "\n", 33 | "`np.matrix` 类型允许直接调用 `.I` 属性计算逆矩阵,而 `np.array` 类型则需使用 `numpy.linalg.inv` 函数求逆。" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "id": "a7654b39-8ea4-480f-9b62-949c3e52bbfe", 39 | "metadata": {}, 40 | "source": [ 41 | "## 导入所需库" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 1, 47 | "id": "e3ba8f7c-9319-46f3-a52c-9eeef1ed5ae5", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "import numpy as np # 导入NumPy库,用于数值计算" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "id": "b11501ac-e96b-45ab-9563-63977efe46f7", 57 | "metadata": {}, 58 | "source": [ 59 | "## 定义矩阵A并计算其逆" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 2, 65 | "id": "368c1708-7217-4844-9b32-3e9398c15358", 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "A = np.matrix([[1, 2], # 定义为np.matrix类型的矩阵A\n", 70 | " [3, 4]])" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 3, 76 | "id": "56017ddb-fe6d-4d98-ba7a-963a3b854428", 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "name": "stdout", 81 | "output_type": "stream", 82 | "text": [ 83 | "[[-2. 1. ]\n", 84 | " [ 1.5 -0.5]]\n" 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "print(A.I) # 打印矩阵A的逆矩阵" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "id": "fb72cfe6-f62d-42a2-ac12-3a551854f4cb", 95 | "metadata": {}, 96 | "source": [ 97 | "## 定义数组B并尝试计算其逆" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 4, 103 | "id": "abc5a48d-5499-41e4-b826-a9b63acfd8ba", 104 | "metadata": {}, 105 | "outputs": [], 106 | "source": [ 107 | "B = np.array([[1, 2], # 定义为np.array类型的数组B\n", 108 | " [3, 4]])" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 6, 114 | "id": "afd919b3-7d56-4543-b1fb-a78bca4bbc26", 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "ename": "AttributeError", 119 | "evalue": "'numpy.ndarray' object has no attribute 'I'", 120 | "output_type": "error", 121 | "traceback": [ 122 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 123 | "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", 124 | "Cell \u001b[1;32mIn[6], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(B\u001b[38;5;241m.\u001b[39mI)\n", 125 | "\u001b[1;31mAttributeError\u001b[0m: 'numpy.ndarray' object has no attribute 'I'" 126 | ] 127 | } 128 | ], 129 | "source": [ 130 | "print(B.I) # 尝试打印数组B的逆,会报错" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": null, 144 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [] 148 | } 149 | ], 150 | "metadata": { 151 | "kernelspec": { 152 | "display_name": "Python 3 (ipykernel)", 153 | "language": "python", 154 | "name": "python3" 155 | }, 156 | "language_info": { 157 | "codemirror_mode": { 158 | "name": "ipython", 159 | "version": 3 160 | }, 161 | "file_extension": ".py", 162 | "mimetype": "text/x-python", 163 | "name": "python", 164 | "nbconvert_exporter": "python", 165 | "pygments_lexer": "ipython3", 166 | "version": "3.12.7" 167 | } 168 | }, 169 | "nbformat": 4, 170 | "nbformat_minor": 5 171 | } 172 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_13.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 迹\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "8cc1d765-91db-4530-81ad-0220895c1e85", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码定义了一个 $3 \\times 3$ 矩阵 $A$,并计算其迹(trace)。矩阵 $A$ 的定义为:\n", 20 | "\n", 21 | "$$\n", 22 | "A = \\begin{bmatrix} 1 & -1 & 0 \\\\ 3 & 2 & 4 \\\\ -2 & 0 & 3 \\end{bmatrix}\n", 23 | "$$\n", 24 | "\n", 25 | "矩阵的迹是其主对角线元素之和,公式为:\n", 26 | "\n", 27 | "$$\n", 28 | "\\text{tr}(A) = A_{11} + A_{22} + A_{33}\n", 29 | "$$\n", 30 | "\n", 31 | "因此,矩阵 $A$ 的迹为:\n", 32 | "\n", 33 | "$$\n", 34 | "\\text{tr}(A) = 1 + 2 + 3 = 6\n", 35 | "$$\n", 36 | "\n", 37 | "此代码展示了如何使用 `np.trace` 函数计算矩阵的迹。" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "id": "ba8dee01-3887-4a76-93a9-274b079171a1", 43 | "metadata": {}, 44 | "source": [ 45 | "## 导入所需库" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 1, 51 | "id": "650779c1-a190-44cc-a778-127b2c189962", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "import numpy as np # 导入NumPy库,用于数值计算" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "id": "5ff0a2c5-dcea-4891-84d4-7a72436e6772", 61 | "metadata": {}, 62 | "source": [ 63 | "## 定义矩阵A" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 2, 69 | "id": "a1a28546-6d6c-4f65-a94f-c8cb27e5ead5", 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "array([[ 1, -1, 0],\n", 76 | " [ 3, 2, 4],\n", 77 | " [-2, 0, 3]])" 78 | ] 79 | }, 80 | "execution_count": 2, 81 | "metadata": {}, 82 | "output_type": "execute_result" 83 | } 84 | ], 85 | "source": [ 86 | "A = np.array([[1, -1, 0], # 定义矩阵A\n", 87 | " [3, 2, 4],\n", 88 | " [-2, 0, 3]])\n", 89 | "A" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "id": "7b8f3355-005a-4b5f-be18-41ada700fc7b", 95 | "metadata": {}, 96 | "source": [ 97 | "## 计算矩阵A的迹" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 3, 103 | "id": "9e5b87ef-8278-4900-b60c-6e96a60e5eef", 104 | "metadata": {}, 105 | "outputs": [ 106 | { 107 | "data": { 108 | "text/plain": [ 109 | "6" 110 | ] 111 | }, 112 | "execution_count": 3, 113 | "metadata": {}, 114 | "output_type": "execute_result" 115 | } 116 | ], 117 | "source": [ 118 | "tr_A = np.trace(A) # 计算矩阵A的迹\n", 119 | "tr_A" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": null, 125 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 126 | "metadata": {}, 127 | "outputs": [], 128 | "source": [] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": null, 133 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [] 137 | } 138 | ], 139 | "metadata": { 140 | "kernelspec": { 141 | "display_name": "Python 3 (ipykernel)", 142 | "language": "python", 143 | "name": "python3" 144 | }, 145 | "language_info": { 146 | "codemirror_mode": { 147 | "name": "ipython", 148 | "version": 3 149 | }, 150 | "file_extension": ".py", 151 | "mimetype": "text/x-python", 152 | "name": "python", 153 | "nbconvert_exporter": "python", 154 | "pygments_lexer": "ipython3", 155 | "version": "3.12.7" 156 | } 157 | }, 158 | "nbformat": 4, 159 | "nbformat_minor": 5 160 | } 161 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_14.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 矩阵逐项积\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "cb498579-9952-45fc-93e8-50479104f8f2", 17 | "metadata": {}, 18 | "source": [ 19 | "\n", 20 | "该代码定义了两个 $2 \\times 2$ 矩阵 $A$ 和 $B$,并计算它们的 Hadamard 积(逐元素乘积)。矩阵 $A$ 和 $B$ 分别为:\n", 21 | "\n", 22 | "$$\n", 23 | "A = \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\end{bmatrix}, \\quad B = \\begin{bmatrix} 5 & 6 \\\\ 7 & 8 \\end{bmatrix}\n", 24 | "$$\n", 25 | "\n", 26 | "Hadamard 积(逐元素乘积)的结果为每个对应元素相乘,计算公式为:\n", 27 | "\n", 28 | "$$\n", 29 | "A \\odot B = \\begin{bmatrix} 1 \\cdot 5 & 2 \\cdot 6 \\\\ 3 \\cdot 7 & 4 \\cdot 8 \\end{bmatrix} = \\begin{bmatrix} 5 & 12 \\\\ 21 & 32 \\end{bmatrix}\n", 30 | "$$\n", 31 | "\n", 32 | "代码使用 `np.multiply` 函数和 `*` 操作符两种方式来计算逐元素乘积,二者等效。该操作用于生成对应元素相乘的矩阵。" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "id": "46ade452-7ec0-45e9-959c-1276be6d4724", 38 | "metadata": {}, 39 | "source": [ 40 | "## 导入所需库" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 1, 46 | "id": "c90949ae-66bd-4373-ac80-42341574da7c", 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "import numpy as np # 导入NumPy库,用于数值计算" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "id": "9b8e04f7-6950-42d1-9981-81ee65208cce", 56 | "metadata": {}, 57 | "source": [ 58 | "## 定义矩阵A和B" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 2, 64 | "id": "bab49ebe-1142-4a6b-9662-ccc569aaf590", 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "A = np.array([[1, 2], # 定义矩阵A\n", 69 | " [3, 4]])" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 3, 75 | "id": "c63f1c20-b2b9-4688-ab7d-800ed8510add", 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "B = np.array([[5, 6], # 定义矩阵B\n", 80 | " [7, 8]])" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "id": "861a16bd-2946-438e-8aed-1b974e7d99d6", 86 | "metadata": {}, 87 | "source": [ 88 | "## 计算Hadamard积(逐元素乘积)" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 4, 94 | "id": "f0947846-bc63-482d-a5ac-a6e891794832", 95 | "metadata": {}, 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/plain": [ 100 | "array([[ 5, 12],\n", 101 | " [21, 32]])" 102 | ] 103 | }, 104 | "execution_count": 4, 105 | "metadata": {}, 106 | "output_type": "execute_result" 107 | } 108 | ], 109 | "source": [ 110 | "A_times_B_piecewise = np.multiply(A, B) # 使用np.multiply计算A和B的逐元素乘积\n", 111 | "A_times_B_piecewise" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 5, 117 | "id": "7e81c46d-d82b-45fa-b22b-5f99b812f2e4", 118 | "metadata": {}, 119 | "outputs": [ 120 | { 121 | "data": { 122 | "text/plain": [ 123 | "array([[ 5, 12],\n", 124 | " [21, 32]])" 125 | ] 126 | }, 127 | "execution_count": 5, 128 | "metadata": {}, 129 | "output_type": "execute_result" 130 | } 131 | ], 132 | "source": [ 133 | "A_times_B_piecewise_V2 = A * B # 使用*操作符计算A和B的逐元素乘积\n", 134 | "A_times_B_piecewise_V2" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": null, 140 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 141 | "metadata": {}, 142 | "outputs": [], 143 | "source": [] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 149 | "metadata": {}, 150 | "outputs": [], 151 | "source": [] 152 | } 153 | ], 154 | "metadata": { 155 | "kernelspec": { 156 | "display_name": "Python 3 (ipykernel)", 157 | "language": "python", 158 | "name": "python3" 159 | }, 160 | "language_info": { 161 | "codemirror_mode": { 162 | "name": "ipython", 163 | "version": 3 164 | }, 165 | "file_extension": ".py", 166 | "mimetype": "text/x-python", 167 | "name": "python", 168 | "nbconvert_exporter": "python", 169 | "pygments_lexer": "ipython3", 170 | "version": "3.12.7" 171 | } 172 | }, 173 | "nbformat": 4, 174 | "nbformat_minor": 5 175 | } 176 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Bk4_Ch04_15.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 04\n", 9 | "\n", 10 | "# 行列式\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "167f6933-14ac-44fb-83e3-24d28b21a894", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码定义了一个 $2 \\times 2$ 矩阵 $A$,并计算其行列式。矩阵 $A$ 的定义为:\n", 20 | "\n", 21 | "$$\n", 22 | "A = \\begin{bmatrix} 4 & 2 \\\\ 1 & 3 \\end{bmatrix}\n", 23 | "$$\n", 24 | "\n", 25 | "行列式计算公式为:\n", 26 | "\n", 27 | "$$\n", 28 | "\\det(A) = A_{11} A_{22} - A_{12} A_{21}\n", 29 | "$$\n", 30 | "\n", 31 | "具体计算得:\n", 32 | "\n", 33 | "$$\n", 34 | "\\det(A) = 4 \\cdot 3 - 2 \\cdot 1 = 12 - 2 = 10\n", 35 | "$$\n", 36 | "\n", 37 | "该代码使用 `np.linalg.det` 函数来计算行列式的值。" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "id": "38e823dc-d626-4fba-8ac6-3fc7d73e9486", 43 | "metadata": {}, 44 | "source": [ 45 | "## 导入所需库" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 1, 51 | "id": "1c1d325e-6981-4885-a9c1-d59bdbe0a194", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "import numpy as np # 导入NumPy库,用于数值计算" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "id": "cd7164de-4737-4076-89d3-3f7b8e5b988b", 61 | "metadata": {}, 62 | "source": [ 63 | "## 定义矩阵A" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 2, 69 | "id": "194dc241-67d8-4ca1-a752-e6c7d2237c94", 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "A = np.array([[4, 2], # 定义矩阵A\n", 74 | " [1, 3]])" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "id": "8bf849ff-6000-4d22-8e57-8d15debbb248", 80 | "metadata": {}, 81 | "source": [ 82 | "## 计算矩阵A的行列式" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 3, 88 | "id": "d910437e-4d72-4c09-8618-a809968077a9", 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [ 92 | "det_A = np.linalg.det(A) # 计算矩阵A的行列式" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 99 | "metadata": {}, 100 | "outputs": [], 101 | "source": [] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [] 110 | } 111 | ], 112 | "metadata": { 113 | "kernelspec": { 114 | "display_name": "Python 3 (ipykernel)", 115 | "language": "python", 116 | "name": "python3" 117 | }, 118 | "language_info": { 119 | "codemirror_mode": { 120 | "name": "ipython", 121 | "version": 3 122 | }, 123 | "file_extension": ".py", 124 | "mimetype": "text/x-python", 125 | "name": "python", 126 | "nbconvert_exporter": "python", 127 | "pygments_lexer": "ipython3", 128 | "version": "3.12.7" 129 | } 130 | }, 131 | "nbformat": 4, 132 | "nbformat_minor": 5 133 | } 134 | -------------------------------------------------------------------------------- /Book4_Ch04_Python_Codes/Streamlit_Bk4_Ch04_16.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | ## 导入必要的库 10 | import plotly.graph_objects as go # 用于创建绘图对象 11 | import numpy as np # 用于数值计算 12 | from plotly.subplots import make_subplots # 用于创建子图 13 | import streamlit as st # 用于构建交互式Web应用 14 | 15 | ## 定义一个函数,将NumPy数组格式化为LaTeX矩阵 16 | def bmatrix(a): 17 | """返回一个LaTeX bmatrix格式的字符串 18 | :param a: 输入的NumPy数组 19 | :return: 返回LaTeX矩阵的字符串表示 20 | """ 21 | if len(a.shape) > 2: # 检查数组是否为二维 22 | raise ValueError('bmatrix最多只能展示二维数组') # 如果不是二维数组,抛出异常 23 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 去掉数组表示中的方括号并分行 24 | rv = [r'\begin{bmatrix}'] # 添加LaTeX矩阵的起始标签 25 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 将每行元素用&连接并加上换行符 26 | rv += [r'\end{bmatrix}'] # 添加LaTeX矩阵的结束标签 27 | return '\n'.join(rv) # 返回拼接后的字符串 28 | 29 | ## 初始化网格范围 30 | n = m = 20 # 定义网格的横纵坐标范围 31 | 32 | ## 创建子图 33 | fig = make_subplots(rows=1, cols=2, horizontal_spacing=0.035) # 创建一个包含两列的子图 34 | 35 | ## 绘制垂直线的坐标 36 | xv = [] # 存储垂直线的x坐标 37 | yv = [] # 存储垂直线的y坐标 38 | for k in range(-n, n + 1): # 遍历网格范围 39 | xv.extend([k, k, np.nan]) # 每条垂直线的起始和结束x坐标 40 | yv.extend([-m, m, np.nan]) # 每条垂直线的起始和结束y坐标 41 | 42 | ## 绘制垂直线 43 | lw = 1 # 定义线条宽度 44 | fig.add_trace(go.Scatter(x=xv, y=yv, mode="lines", line_width=lw, line_color='red'), 1, 1) # 添加垂直线到第一个子图 45 | 46 | ## 绘制水平线的坐标 47 | xh = [] # 存储水平线的x坐标 48 | yh = [] # 存储水平线的y坐标 49 | for k in range(-m, m + 1): # 遍历网格范围 50 | xh.extend([-m, m, np.nan]) # 每条水平线的起始和结束x坐标 51 | yh.extend([k, k, np.nan]) # 每条水平线的起始和结束y坐标 52 | fig.add_trace(go.Scatter(x=xh, y=yh, mode="lines", line_width=lw, line_color='blue'), 1, 1) # 添加水平线到第一个子图 53 | 54 | ## 创建交互式侧边栏 55 | with st.sidebar: # 定义侧边栏 56 | st.latex(r''' 57 | A = \begin{bmatrix} 58 | a & b\\ 59 | c & d 60 | \end{bmatrix}''') # 显示矩阵A的LaTeX格式 61 | a = st.slider('a', -2.0, 2.0, step=0.1, value=1.0) # 创建滑块选择矩阵A的元素a 62 | b = st.slider('b', -2.0, 2.0, step=0.1, value=0.0) # 创建滑块选择矩阵A的元素b 63 | c = st.slider('c', -2.0, 2.0, step=0.1, value=0.0) # 创建滑块选择矩阵A的元素c 64 | d = st.slider('c', -2.0, 2.0, step=0.1, value=1.0) # 创建滑块选择矩阵A的元素d 65 | 66 | ## 定义矩阵变换 67 | theta = np.pi / 6 # 定义角度theta 68 | A = np.array([[a, b], [c, d]], dtype=float) # 根据用户输入定义矩阵A 69 | 70 | ## 应用矩阵变换到垂直线 71 | X = np.array(xv) # 垂直线的x坐标 72 | Y = np.array(yv) # 垂直线的y坐标 73 | Txvyv = A @ np.stack((X, Y)) # 对垂直线应用矩阵A的变换 74 | 75 | ## 应用矩阵变换到水平线 76 | X = np.array(xh) # 水平线的x坐标 77 | Y = np.array(yh) # 水平线的y坐标 78 | Txhyh = A @ np.stack((X, Y)) # 对水平线应用矩阵A的变换 79 | 80 | ## 显示矩阵及其计算结果 81 | st.latex(r'A = ' + bmatrix(A)) # 显示矩阵A的LaTeX格式 82 | a1 = A[:, 0].reshape((-1, 1)) # 提取矩阵A的第一列 83 | a2 = A[:, 1].reshape((-1, 1)) # 提取矩阵A的第二列 84 | 85 | st.latex(r''' 86 | a_1 = Ae_1 = ''' + bmatrix(A) + 'e_1 = ' + bmatrix(a1)) # 显示第一列向量的计算 87 | st.latex(r''' 88 | a_2 = Ae_2 = ''' + bmatrix(A) + 'e_2 = ' + bmatrix(a2)) # 显示第二列向量的计算 89 | st.latex(r'\begin{vmatrix} A \end{vmatrix} = ' + str(np.linalg.det(A))) # 显示矩阵A的行列式 90 | 91 | ## 定义一个正方形并应用矩阵变换 92 | square_x = np.array([0, 1, 1, 0]) # 定义正方形的x坐标 93 | square_y = np.array([0, 0, 1, 1]) # 定义正方形的y坐标 94 | square_array = np.stack((square_x, square_y)) # 将正方形的坐标堆叠为二维数组 95 | 96 | fig.add_trace(go.Scatter(x=square_x, y=square_y, fill="toself", line_color='orange'), 1, 1) # 在第一个子图中绘制原始正方形 97 | A_times_square_array = A @ square_array # 将正方形应用矩阵A的变换 98 | 99 | fig.add_trace(go.Scatter(x=A_times_square_array[0, :], y=A_times_square_array[1, :], fill="toself", line_color='orange'), 1, 2) # 绘制变换后的正方形 100 | fig.add_trace(go.Scatter(x=Txvyv[0], y=Txvyv[1], mode="lines", line_width=lw, line_color='red'), 1, 2) # 绘制变换后的垂直线 101 | fig.add_trace(go.Scatter(x=Txhyh[0], y=Txhyh[1], mode="lines", line_width=lw, line_color='blue'), 1, 2) # 绘制变换后的水平线 102 | 103 | ## 更新图形布局 104 | fig.update_xaxes(range=[-4, 4]) # 设置x轴范围 105 | fig.update_yaxes(range=[-4, 4]) # 设置y轴范围 106 | fig.update_layout(width=800, height=500, showlegend=False, template="none", plot_bgcolor="white", yaxis2_showgrid=False, xaxis2_showgrid=False) # 设置图形布局 107 | 108 | ## 在Streamlit中显示图形 109 | st.plotly_chart(fig) # 显示绘图 110 | -------------------------------------------------------------------------------- /Book4_Ch04_矩阵__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch04_矩阵__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch05_矩阵乘法__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch05_矩阵乘法__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch06_Python_Codes/Bk4_Ch06_01.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 06\n", 9 | "\n", 10 | "# 分块矩阵\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "25999c8b-f570-4ca4-b9d4-6e8c9537b859", 17 | "metadata": {}, 18 | "source": [ 19 | "这段代码演示了如何对矩阵进行分块和重组操作。首先定义了一个 \\(4 \\times 5\\) 矩阵 \\( A \\):\n", 20 | "\n", 21 | "$$\n", 22 | "A = \\begin{bmatrix}\n", 23 | "1 & 2 & 3 & 0 & 0 \\\\\n", 24 | "4 & 5 & 6 & 0 & 0 \\\\\n", 25 | "0 & 0 & 0 & -1 & 0 \\\\\n", 26 | "0 & 0 & 0 & 0 & 1 \\\\\n", 27 | "\\end{bmatrix}\n", 28 | "$$\n", 29 | "\n", 30 | "然后使用 NumPy 的切片方法,将矩阵 \\( A \\) 分割为 4 个子矩阵(即 \\(2 \\times 2\\) 的块矩阵结构):\n", 31 | "\n", 32 | "1. \\( A_{1,1} = A[0:2, 0:3] \\),即前两行和前三列的子矩阵:\n", 33 | " $$\n", 34 | " A_{1,1} = \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix}\n", 35 | " $$\n", 36 | " \n", 37 | "2. \\( A_{1,2} = A[0:2, 3:] \\),即前两行和最后两列的子矩阵:\n", 38 | " $$\n", 39 | " A_{1,2} = \\begin{bmatrix} 0 & 0 \\\\ 0 & 0 \\end{bmatrix}\n", 40 | " $$\n", 41 | "\n", 42 | "3. \\( A_{2,1} = A[2:, 0:3] \\),即后两行和前三列的子矩阵:\n", 43 | " $$\n", 44 | " A_{2,1} = \\begin{bmatrix} 0 & 0 & 0 \\\\ 0 & 0 & 0 \\end{bmatrix}\n", 45 | " $$\n", 46 | "\n", 47 | "4. \\( A_{2,2} = A[2:, 3:] \\),即后两行和最后两列的子矩阵:\n", 48 | " $$\n", 49 | " A_{2,2} = \\begin{bmatrix} -1 & 0 \\\\ 0 & 1 \\end{bmatrix}\n", 50 | " $$\n", 51 | "\n", 52 | "最后使用 `np.block` 函数将这些子矩阵重新组合为一个新的矩阵 \\( A' \\),其结构与原矩阵 \\( A \\) 相同:\n", 53 | "\n", 54 | "$$\n", 55 | "A' = \\begin{bmatrix} \n", 56 | "A_{1,1} & A_{1,2} \\\\ \n", 57 | "A_{2,1} & A_{2,2} \n", 58 | "\\end{bmatrix} = \n", 59 | "\\begin{bmatrix} \n", 60 | "1 & 2 & 3 & 0 & 0 \\\\ \n", 61 | "4 & 5 & 6 & 0 & 0 \\\\ \n", 62 | "0 & 0 & 0 & -1 & 0 \\\\ \n", 63 | "0 & 0 & 0 & 0 & 1 \n", 64 | "\\end{bmatrix}\n", 65 | "$$ \n", 66 | "\n", 67 | "通过这种方法,可以方便地在分块矩阵操作中对矩阵进行重新组合,实现了矩阵的分解与重构。" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 1, 73 | "id": "da9bd893-e25f-4193-b12b-e5cac674f64b", 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [ 77 | "import numpy as np" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "id": "67b49f8e-b6d5-49d4-b4a4-190ecd915450", 83 | "metadata": {}, 84 | "source": [ 85 | "## 定义矩阵 A" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 2, 91 | "id": "e00b27dd-c721-42e1-8f65-fa2937b460ad", 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "data": { 96 | "text/plain": [ 97 | "array([[ 1, 2, 3, 0, 0],\n", 98 | " [ 4, 5, 6, 0, 0],\n", 99 | " [ 0, 0, 0, -1, 0],\n", 100 | " [ 0, 0, 0, 0, 1]])" 101 | ] 102 | }, 103 | "execution_count": 2, 104 | "metadata": {}, 105 | "output_type": "execute_result" 106 | } 107 | ], 108 | "source": [ 109 | "A = np.array([[1, 2, 3, 0, 0], # 定义矩阵 A 的元素\n", 110 | " [4, 5, 6, 0, 0],\n", 111 | " [0, 0, 0, -1, 0],\n", 112 | " [0, 0 ,0, 0, 1]])\n", 113 | "A" 114 | ] 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "id": "5a878c1b-238b-4f8d-a033-db66fb2aa0fa", 119 | "metadata": {}, 120 | "source": [ 121 | "## NumPy 数组切片操作" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 3, 127 | "id": "440560e5-ed77-4bbc-8fa7-d2c09285e3c7", 128 | "metadata": {}, 129 | "outputs": [ 130 | { 131 | "data": { 132 | "text/plain": [ 133 | "array([[1, 2, 3],\n", 134 | " [4, 5, 6]])" 135 | ] 136 | }, 137 | "execution_count": 3, 138 | "metadata": {}, 139 | "output_type": "execute_result" 140 | } 141 | ], 142 | "source": [ 143 | "A_1_1 = A[0:2,0:3] # 提取矩阵 A 的前两行和前三列作为子矩阵 A_1_1\n", 144 | "A_1_1" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": 4, 150 | "id": "29344301-cbb7-4fbd-b64b-d23aced6823e", 151 | "metadata": {}, 152 | "outputs": [ 153 | { 154 | "data": { 155 | "text/plain": [ 156 | "array([[0, 0],\n", 157 | " [0, 0]])" 158 | ] 159 | }, 160 | "execution_count": 4, 161 | "metadata": {}, 162 | "output_type": "execute_result" 163 | } 164 | ], 165 | "source": [ 166 | "A_1_2 = A[0:2,3:] # 提取矩阵 A 的前两行和最后两列作为子矩阵 A_1_2\n", 167 | "A_1_2\n", 168 | "# A_1_2 = A[0:2,-2:] # 或者用负索引方式提取前两行和最后两列(注释部分)" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 5, 174 | "id": "b24013dd-a04e-44f6-9c89-67b2a0027bff", 175 | "metadata": {}, 176 | "outputs": [ 177 | { 178 | "data": { 179 | "text/plain": [ 180 | "array([[0, 0, 0],\n", 181 | " [0, 0, 0]])" 182 | ] 183 | }, 184 | "execution_count": 5, 185 | "metadata": {}, 186 | "output_type": "execute_result" 187 | } 188 | ], 189 | "source": [ 190 | "A_2_1 = A[2:,0:3] # 提取矩阵 A 的后两行和前三列作为子矩阵 A_2_1\n", 191 | "A_2_1\n", 192 | "# A_2_1 = A[-2:,0:3] # 或者用负索引方式提取后两行和前三列(注释部分)" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 6, 198 | "id": "2aa41d01-ef5a-450d-b912-d0cf9134f16f", 199 | "metadata": {}, 200 | "outputs": [ 201 | { 202 | "data": { 203 | "text/plain": [ 204 | "array([[-1, 0],\n", 205 | " [ 0, 1]])" 206 | ] 207 | }, 208 | "execution_count": 6, 209 | "metadata": {}, 210 | "output_type": "execute_result" 211 | } 212 | ], 213 | "source": [ 214 | "A_2_2 = A[2:,3:] # 提取矩阵 A 的后两行和最后两列作为子矩阵 A_2_2\n", 215 | "A_2_2\n", 216 | "# A_2_2 = A[-2:,-2:] # 或者用负索引方式提取后两行和最后两列(注释部分)" 217 | ] 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "id": "f618ccce-d822-417d-8ce1-6cb6d3f90999", 222 | "metadata": {}, 223 | "source": [ 224 | "## 使用嵌套列表中的块组装矩阵" 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": 7, 230 | "id": "4dc81f48-c1a3-42e0-82df-b76c62601926", 231 | "metadata": {}, 232 | "outputs": [ 233 | { 234 | "data": { 235 | "text/plain": [ 236 | "array([[ 1, 2, 3, 0, 0],\n", 237 | " [ 4, 5, 6, 0, 0],\n", 238 | " [ 0, 0, 0, -1, 0],\n", 239 | " [ 0, 0, 0, 0, 1]])" 240 | ] 241 | }, 242 | "execution_count": 7, 243 | "metadata": {}, 244 | "output_type": "execute_result" 245 | } 246 | ], 247 | "source": [ 248 | "A_ = np.block([[A_1_1, A_1_2], # 通过 np.block 函数将子矩阵 A_1_1、A_1_2、A_2_1 和 A_2_2 组合成新的矩阵 A_\n", 249 | " [A_2_1, A_2_2]])\n", 250 | "A_" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": null, 256 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 257 | "metadata": {}, 258 | "outputs": [], 259 | "source": [] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": null, 264 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 265 | "metadata": {}, 266 | "outputs": [], 267 | "source": [] 268 | } 269 | ], 270 | "metadata": { 271 | "kernelspec": { 272 | "display_name": "Python 3 (ipykernel)", 273 | "language": "python", 274 | "name": "python3" 275 | }, 276 | "language_info": { 277 | "codemirror_mode": { 278 | "name": "ipython", 279 | "version": 3 280 | }, 281 | "file_extension": ".py", 282 | "mimetype": "text/x-python", 283 | "name": "python", 284 | "nbconvert_exporter": "python", 285 | "pygments_lexer": "ipython3", 286 | "version": "3.12.7" 287 | } 288 | }, 289 | "nbformat": 4, 290 | "nbformat_minor": 5 291 | } 292 | -------------------------------------------------------------------------------- /Book4_Ch06_分块矩阵__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch06_分块矩阵__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch07_Python_Codes/Streamlit_Bk4_Ch07_01.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | import plotly.graph_objects as go 10 | import numpy as np 11 | from plotly.subplots import make_subplots 12 | import streamlit as st 13 | 14 | # 定义一个函数,用于返回LaTeX格式的bmatrix 15 | def bmatrix(a): 16 | """返回LaTeX bmatrix 17 | :a: numpy数组 18 | :returns: 作为字符串的LaTeX bmatrix 19 | """ 20 | if len(a.shape) > 2: 21 | raise ValueError('bmatrix最多只能显示二维数组') 22 | lines = str(a).replace('[', '').replace(']', '').splitlines() 23 | rv = [r'\begin{bmatrix}'] 24 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] 25 | rv += [r'\end{bmatrix}'] 26 | return '\n'.join(rv) 27 | 28 | # 设置网格的范围 29 | n = m = 20 30 | 31 | # 创建一个具有两个子图的图表 32 | fig = make_subplots(rows=1, cols=2, horizontal_spacing=0.035) 33 | 34 | # 初始化垂直线的x和y坐标列表 35 | xv = [] 36 | yv = [] 37 | 38 | # 添加垂直线的坐标 39 | for k in range(-n, n + 1): 40 | xv.extend([k, k, np.nan]) 41 | yv.extend([-m, m, np.nan]) 42 | 43 | # 设置线宽 44 | lw = 1 45 | # 添加垂直线到图表 46 | fig.add_trace(go.Scatter(x=xv, y=yv, mode="lines", line_width=lw, 47 | line_color='red'), 1, 1) 48 | 49 | # 初始化水平线的x和y坐标列表 50 | xh = [] 51 | yh = [] 52 | # 添加水平线的坐标 53 | for k in range(-m, m + 1): 54 | xh.extend([-m, m, np.nan]) 55 | yh.extend([k, k, np.nan]) 56 | fig.add_trace(go.Scatter(x=xh, y=yh, mode="lines", line_width=lw, 57 | line_color='blue'), 1, 1) 58 | 59 | # 在侧边栏中添加滑块控件 60 | with st.sidebar: 61 | # 显示LaTeX矩阵 62 | st.latex(r''' 63 | A = \begin{bmatrix} 64 | a & b\\ 65 | c & d 66 | \end{bmatrix}''') 67 | 68 | # 添加矩阵A的参数滑块 69 | a = st.slider('a', -2.0, 2.0, step=0.1, value=1.0) 70 | b = st.slider('b', -2.0, 2.0, step=0.1, value=0.0) 71 | c = st.slider('c', -2.0, 2.0, step=0.1, value=0.0) 72 | d = st.slider('d', -2.0, 2.0, step=0.1, value=1.0) 73 | 74 | # 定义旋转角度 75 | theta = np.pi / 6 76 | # 定义矩阵A 77 | A = np.array([[a, b], 78 | [c, d]], dtype=float) 79 | 80 | # 将垂直线的坐标转换为NumPy数组 81 | X = np.array(xv) 82 | Y = np.array(yv) 83 | 84 | # 通过矩阵A变换垂直线的坐标 85 | Txvyv = A @ np.stack((X, Y)) 86 | 87 | # 将水平线的坐标转换为NumPy数组 88 | X = np.array(xh) 89 | Y = np.array(yh) 90 | 91 | # 通过矩阵A变换水平线的坐标 92 | Txhyh = A @ np.stack((X, Y)) 93 | 94 | # 显示矩阵A的LaTeX格式 95 | st.latex(bmatrix(A)) 96 | 97 | # 提取矩阵A的列向量 98 | a1 = A[:, 0].reshape((-1, 1)) 99 | a2 = A[:, 1].reshape((-1, 1)) 100 | 101 | # 显示列向量的LaTeX表达式 102 | st.latex(r''' 103 | a_1 = Ae_1 = ''' + bmatrix(A) + 104 | 'e_1 = ' + bmatrix(a1) 105 | ) 106 | 107 | st.latex(r''' 108 | a_2 = Ae_2 = ''' + bmatrix(A) + 109 | 'e_2 = ' + bmatrix(a2) 110 | ) 111 | 112 | # 添加变换后的垂直线到图表 113 | fig.add_trace(go.Scatter(x=Txvyv[0], y=Txvyv[1], 114 | mode="lines", line_width=lw, 115 | line_color='red'), 1, 2) 116 | 117 | # 添加变换后的水平线到图表 118 | fig.add_trace(go.Scatter(x=Txhyh[0], y=Txhyh[1], 119 | mode="lines", line_width=lw, 120 | line_color='blue'), 1, 2) 121 | 122 | # 设置x轴和y轴的范围 123 | fig.update_xaxes(range=[-4, 4]) 124 | fig.update_yaxes(range=[-4, 4]) 125 | 126 | # 设置图表的布局和样式 127 | fig.update_layout(width=800, height=500, showlegend=False, template="none", 128 | plot_bgcolor="white", yaxis2_showgrid=False, xaxis2_showgrid=False) 129 | 130 | # 在Streamlit应用中显示图表 131 | st.plotly_chart(fig) 132 | -------------------------------------------------------------------------------- /Book4_Ch07_Python_Codes/Streamlit_Bk4_Ch07_02.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | import pandas as pd 10 | import plotly.graph_objs as go 11 | import streamlit as st 12 | import numpy as np 13 | 14 | # 使用 Streamlit 的侧边栏设置滑块,用于选择每个维度的数据点数量 15 | with st.sidebar: 16 | num = st.slider('Number of points for each dimension', # 滑块标题 17 | max_value=20, # 最大值为20 18 | min_value=10, # 最小值为10 19 | step=1) # 步长为1 20 | 21 | # 生成从0到1均匀分布的线性空间数据点 22 | x1 = np.linspace(0, 1, num) 23 | x2 = x1 # x2 和 x1 相同 24 | x3 = x1 # x3 和 x1 相同 25 | 26 | # 生成三维网格,用于三维坐标的组合 27 | xx1, xx2, xx3 = np.meshgrid(x1, x2, x3) 28 | 29 | # 将网格展开为一维数组 30 | x1_ = xx1.ravel() 31 | x2_ = xx2.ravel() 32 | x3_ = xx3.ravel() 33 | 34 | # 创建一个 Pandas DataFrame,存储三维坐标和对应的RGB颜色分量 35 | df = pd.DataFrame({'X': x1_, # x 坐标 36 | 'Y': x2_, # y 坐标 37 | 'Z': x3_, # z 坐标 38 | 'R': (x1_ * 256).round(), # R 通道值 39 | 'G': (x2_ * 256).round(), # G 通道值 40 | 'B': (x3_ * 256).round()}) # B 通道值 41 | 42 | # 创建 3D 散点图的跟踪对象 43 | trace = go.Scatter3d( 44 | x=df.X, # x 轴数据 45 | y=df.Y, # y 轴数据 46 | z=df.Z, # z 轴数据 47 | mode='markers', # 数据点的显示模式为散点 48 | marker=dict( 49 | size=3, # 数据点的大小 50 | color=['rgb({},{},{})'.format(r, g, b) # 将 RGB 分量转换为颜色字符串 51 | for r, g, b in zip(df.R.values, df.G.values, df.B.values)], 52 | opacity=0.9, # 数据点的不透明度 53 | ) 54 | ) 55 | 56 | # 将散点图添加到数据列表中 57 | data = [trace] 58 | 59 | # 定义 3D 图的布局,包括坐标轴和边距 60 | layout = go.Layout( 61 | margin=dict(l=0, r=0, b=0, t=0), # 图形边距设置为0 62 | scene=dict( 63 | xaxis=dict(title='e_1'), # x 轴标题 64 | yaxis=dict(title='e_2'), # y 轴标题 65 | zaxis=dict(title='e_3'), # z 轴标题 66 | ), 67 | ) 68 | 69 | # 创建包含数据和布局的图表对象 70 | fig = go.Figure(data=data, layout=layout) 71 | 72 | # 使用 Streamlit 显示图表 73 | st.plotly_chart(fig) 74 | 75 | -------------------------------------------------------------------------------- /Book4_Ch07_向量空间__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch07_向量空间__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch08_Python_Codes/Streamlit_Bk4_Ch08_02.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | import plotly.graph_objects as go 10 | import numpy as np 11 | from plotly.subplots import make_subplots 12 | import streamlit as st 13 | 14 | # 定义一个函数,用于将矩阵转换为LaTeX格式的bmatrix 15 | def bmatrix(a): 16 | """返回LaTeX bmatrix 17 | 18 | :a: numpy数组 19 | :returns: 作为字符串的LaTeX bmatrix 20 | """ 21 | if len(a.shape) > 2: 22 | raise ValueError('bmatrix最多支持显示二维矩阵') # 确保输入矩阵是二维的 23 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 格式化矩阵为字符串 24 | rv = [r'\begin{bmatrix}'] # LaTeX矩阵的开始部分 25 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 添加每一行数据 26 | rv += [r'\end{bmatrix}'] # LaTeX矩阵的结束部分 27 | return '\n'.join(rv) 28 | 29 | # 设置网格大小 30 | n = m = 20 31 | 32 | # 创建带两个子图的图表 33 | fig = make_subplots(rows=1, cols=2, horizontal_spacing=0.035) 34 | 35 | # 初始化垂直线的x和y坐标列表 36 | xv = [] 37 | yv = [] 38 | 39 | # 添加垂直线的坐标 40 | for k in range(-n, n + 1): 41 | xv.extend([k, k, np.nan]) # 添加x坐标并在每条线后加入NaN以断开 42 | yv.extend([-m, m, np.nan]) # 添加y坐标并在每条线后加入NaN以断开 43 | # 设置线宽 44 | lw = 1 # line_width 45 | # 将垂直线添加到第一个子图 46 | fig.add_trace(go.Scatter(x=xv, y=yv, mode="lines", line_width=lw, 47 | line_color='red'), 1, 1) 48 | 49 | # 初始化水平线的x和y坐标列表 50 | xh = [] 51 | yh = [] 52 | # 添加水平线的坐标 53 | for k in range(-m, m + 1): 54 | xh.extend([-m, m, np.nan]) # 添加x坐标并在每条线后加入NaN以断开 55 | yh.extend([k, k, np.nan]) # 添加y坐标并在每条线后加入NaN以断开 56 | # 将水平线添加到第一个子图 57 | fig.add_trace(go.Scatter(x=xh, y=yh, mode="lines", line_width=lw, 58 | line_color='blue'), 1, 1) 59 | 60 | # 在Streamlit侧边栏中定义滑块和显示LaTeX公式 61 | with st.sidebar: 62 | # 显示旋转矩阵的公式 63 | st.latex(r''' 64 | R = \begin{bmatrix} 65 | \cos(\theta) & -\sin(\theta)\\ 66 | \sin(\theta) & \cos(\theta) 67 | \end{bmatrix}''') 68 | 69 | # 添加滑块,用于选择旋转角度theta 70 | theta = st.slider('Theta degree: ', -180, 180, step=5, value=0) # 滑块范围为-180到180度 71 | theta = theta / 180 * np.pi # 将角度转换为弧度 72 | 73 | # 定义旋转矩阵R 74 | R = np.array([[np.cos(theta), -np.sin(theta)], 75 | [np.sin(theta), np.cos(theta)]], dtype=float) 76 | 77 | # 将垂直线的坐标转换为NumPy数组 78 | X = np.array(xv) 79 | Y = np.array(yv) 80 | 81 | # 使用旋转矩阵R变换垂直线的坐标 82 | Txvyv = R @ np.stack((X, Y)) # 对每个坐标点应用旋转变换 83 | 84 | # 将水平线的坐标转换为NumPy数组 85 | X = np.array(xh) 86 | Y = np.array(yh) 87 | 88 | # 使用旋转矩阵R变换水平线的坐标 89 | Txhyh = R @ np.stack((X, Y)) # 对每个坐标点应用旋转变换 90 | 91 | # 显示旋转矩阵的LaTeX表达式 92 | st.latex(r'R = ' + bmatrix(R)) 93 | 94 | # 提取旋转矩阵的列向量 95 | r1 = R[:, 0].reshape((-1, 1)) # 第一列向量 96 | r2 = R[:, 1].reshape((-1, 1)) # 第二列向量 97 | 98 | # 显示列向量的LaTeX公式 99 | st.latex(r''' 100 | r_1 = R e_1 = ''' + bmatrix(R) + 101 | 'e_1 = ' + bmatrix(r1) 102 | ) 103 | st.latex(r''' 104 | r_2 = R e_2 = ''' + bmatrix(R) + 105 | 'e_2 = ' + bmatrix(r2) 106 | ) 107 | 108 | # 显示旋转矩阵的行列式值 109 | st.latex(r'\begin{vmatrix} R \end{vmatrix} = ' + str(np.linalg.det(R))) 110 | 111 | # 将变换后的垂直线添加到第二个子图 112 | fig.add_trace(go.Scatter(x=Txvyv[0], y=Txvyv[1], 113 | mode="lines", line_width=lw, 114 | line_color='red'), 1, 2) 115 | 116 | # 将变换后的水平线添加到第二个子图 117 | fig.add_trace(go.Scatter(x=Txhyh[0], y=Txhyh[1], 118 | mode="lines", line_width=lw, 119 | line_color='blue'), 1, 2) 120 | 121 | # 设置x轴和y轴的范围 122 | fig.update_xaxes(range=[-4, 4]) 123 | fig.update_yaxes(range=[-4, 4]) 124 | 125 | # 设置图表的布局和样式 126 | fig.update_layout(width=800, height=500, showlegend=False, template="none", 127 | plot_bgcolor="white", yaxis2_showgrid=False, xaxis2_showgrid=False) 128 | 129 | # 在Streamlit应用中显示图表 130 | st.plotly_chart(fig) 131 | -------------------------------------------------------------------------------- /Book4_Ch08_Python_Codes/Streamlit_Bk4_Ch08_03.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | import plotly.graph_objects as go 10 | import numpy as np 11 | from plotly.subplots import make_subplots 12 | import streamlit as st 13 | 14 | # 定义一个函数,用于生成LaTeX格式的矩阵表示 15 | def bmatrix(a): 16 | """返回LaTeX bmatrix 17 | :a: numpy数组 18 | :returns: LaTeX bmatrix格式的字符串 19 | """ 20 | if len(a.shape) > 2: # 检查矩阵维度是否超过2 21 | raise ValueError('bmatrix最多支持二维矩阵') 22 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 格式化矩阵为字符串 23 | rv = [r'\begin{bmatrix}'] # 开始LaTeX矩阵表示 24 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 添加每一行 25 | rv += [r'\end{bmatrix}'] # 结束LaTeX矩阵表示 26 | return '\n'.join(rv) 27 | 28 | # 设置网格大小 29 | n = m = 20 30 | 31 | # 创建具有两个子图的图表 32 | fig = make_subplots(rows=1, cols=2, horizontal_spacing=0.035) 33 | 34 | # 初始化垂直线的x和y坐标列表 35 | xv = [] 36 | yv = [] 37 | 38 | # 添加垂直线的坐标 39 | for k in range(-n, n + 1): 40 | xv.extend([k, k, np.nan]) # 添加垂直线的x坐标并在每条线后加入NaN以断开 41 | yv.extend([-m, m, np.nan]) # 添加垂直线的y坐标并在每条线后加入NaN以断开 42 | 43 | # 设置线宽 44 | lw = 1 # 线宽 45 | # 将垂直线添加到图表的第一个子图 46 | fig.add_trace(go.Scatter(x=xv, y=yv, mode="lines", line_width=lw, 47 | line_color='red'), 1, 1) 48 | 49 | # 初始化水平线的x和y坐标列表 50 | xh = [] 51 | yh = [] 52 | 53 | # 添加水平线的坐标 54 | for k in range(-m, m + 1): 55 | xh.extend([-m, m, np.nan]) # 添加水平线的x坐标并在每条线后加入NaN以断开 56 | yh.extend([k, k, np.nan]) # 添加水平线的y坐标并在每条线后加入NaN以断开 57 | 58 | # 将水平线添加到图表的第一个子图 59 | fig.add_trace(go.Scatter(x=xh, y=yh, mode="lines", line_width=lw, 60 | line_color='blue'), 1, 1) 61 | 62 | # 使用Streamlit的侧边栏显示滑块和LaTeX矩阵公式 63 | with st.sidebar: 64 | st.latex(r''' 65 | A = \begin{bmatrix} 66 | a & b\\ 67 | c & d 68 | \end{bmatrix}''') # 显示矩阵A的LaTeX公式 69 | 70 | # 添加滑块控件,供用户调整矩阵A的元素值 71 | a = st.slider('a', -2.0, 2.0, step=0.1, value=1.0) 72 | b = st.slider('b', -2.0, 2.0, step=0.1, value=0.0) 73 | c = st.slider('c', -2.0, 2.0, step=0.1, value=0.0) 74 | d = st.slider('d', -2.0, 2.0, step=0.1, value=1.0) 75 | 76 | # 定义一个固定的角度值 77 | theta = np.pi / 6 78 | 79 | # 创建矩阵A 80 | A = np.array([[a, b], 81 | [c, d]], dtype=float) 82 | 83 | # 获取垂直线的坐标并转换为NumPy数组 84 | X = np.array(xv) 85 | Y = np.array(yv) 86 | 87 | # 使用矩阵A变换垂直线的坐标 88 | Txvyv = A @ np.stack((X, Y)) # 对坐标点应用线性变换 89 | 90 | # 获取水平线的坐标并转换为NumPy数组 91 | X = np.array(xh) 92 | Y = np.array(yh) 93 | 94 | # 使用矩阵A变换水平线的坐标 95 | Txhyh = A @ np.stack((X, Y)) # 对坐标点应用线性变换 96 | 97 | # 显示矩阵A的LaTeX格式 98 | st.latex(r'A = ' + bmatrix(A)) 99 | 100 | # 提取矩阵A的列向量 101 | a1 = A[:, 0].reshape((-1, 1)) # 第一列 102 | a2 = A[:, 1].reshape((-1, 1)) # 第二列 103 | 104 | # 显示矩阵列向量的LaTeX公式 105 | st.latex(r''' 106 | a_1 = Ae_1 = ''' + bmatrix(A) + 107 | 'e_1 = ' + bmatrix(a1) 108 | ) 109 | st.latex(r''' 110 | a_2 = Ae_2 = ''' + bmatrix(A) + 111 | 'e_2 = ' + bmatrix(a2) 112 | ) 113 | 114 | # 显示矩阵A的行列式值 115 | st.latex(r'\begin{vmatrix} A \end{vmatrix} = ' + str(np.linalg.det(A))) 116 | 117 | # 生成一个单位圆的坐标 118 | theta_array = np.linspace(0, 2 * np.pi, 101) # 定义角度数组 119 | circle_x = np.cos(theta_array) # 单位圆x坐标 120 | circle_y = np.sin(theta_array) # 单位圆y坐标 121 | circle_array = np.stack((circle_x, circle_y)) # 将x和y坐标堆叠为二维数组 122 | 123 | # 将单位圆添加到第一个子图 124 | fig.add_trace(go.Scatter(x=circle_x, y=circle_y, 125 | fill="toself", line_color='orange'), 1, 1) 126 | 127 | # 使用矩阵A变换单位圆的坐标 128 | A_times_circle_array = A @ circle_array 129 | 130 | # 将变换后的单位圆添加到第二个子图 131 | fig.add_trace(go.Scatter(x=A_times_circle_array[0, :], 132 | y=A_times_circle_array[1, :], 133 | fill="toself", line_color='orange'), 1, 2) 134 | 135 | # 将变换后的垂直线添加到第二个子图 136 | fig.add_trace(go.Scatter(x=Txvyv[0], y=Txvyv[1], 137 | mode="lines", line_width=lw, 138 | line_color='blue'), 1, 2) 139 | 140 | # 将变换后的水平线添加到第二个子图 141 | fig.add_trace(go.Scatter(x=Txhyh[0], y=Txhyh[1], 142 | mode="lines", line_width=lw, 143 | line_color='red'), 1, 2) 144 | 145 | # 设置x轴和y轴的范围 146 | fig.update_xaxes(range=[-4, 4]) 147 | fig.update_yaxes(range=[-4, 4]) 148 | 149 | # 设置图表的布局和样式 150 | fig.update_layout(width=800, height=500, showlegend=False, template="none", 151 | plot_bgcolor="white", yaxis2_showgrid=False, xaxis2_showgrid=False) 152 | 153 | # 在Streamlit应用中显示图表 154 | st.plotly_chart(fig) 155 | -------------------------------------------------------------------------------- /Book4_Ch08_几何变换__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch08_几何变换__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch09_正交投影__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch09_正交投影__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch10_Python_Codes/Streamlit_Bk4_Ch10_01.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | ## 导入必要的库 10 | import streamlit as st # 导入 Streamlit,用于创建交互式 Web 应用 11 | import plotly.express as px # 导入 Plotly Express,用于绘图 12 | 13 | import seaborn as sns # 导入 Seaborn,用于数据可视化 14 | import numpy as np # 导入 NumPy,用于数值计算 15 | import matplotlib.pyplot as plt # 导入 Matplotlib,用于绘图 16 | import pandas as pd # 导入 Pandas,用于数据处理 17 | from sklearn.datasets import load_iris # 从 scikit-learn 导入 Iris 数据集 18 | 19 | ## 定义函数 bmatrix,用于生成 LaTeX 矩阵 20 | def bmatrix(a): 21 | """返回一个 LaTeX 矩阵""" 22 | if len(a.shape) > 2: # 检查输入是否为二维数组 23 | raise ValueError('bmatrix 函数最多显示二维矩阵') # 如果不是二维,抛出异常 24 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 将数组转为字符串并去除括号 25 | rv = [r'\begin{bmatrix}'] # 开始 LaTeX 矩阵的格式 26 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 为每一行添加 LaTeX 格式 27 | rv += [r'\end{bmatrix}'] # 结束 LaTeX 矩阵的格式 28 | return '\n'.join(rv) # 将所有行连接为字符串并返回 29 | 30 | ## 加载 Iris 数据集 31 | iris = load_iris() # 加载 Iris 数据集 32 | X = iris.data # 提取特征数据 33 | y = iris.target # 提取目标标签 34 | 35 | ## 定义特征名称 36 | feature_names = ['Sepal length, x1', 'Sepal width, x2', 37 | 'Petal length, x3', 'Petal width, x4'] # 定义特征名称 38 | 39 | ## 将特征数据转换为 DataFrame 40 | X_df = pd.DataFrame(X, columns=feature_names) # 创建 DataFrame,列名为特征名称 41 | 42 | ## 原始数据 X 43 | X = X_df.to_numpy() # 将 DataFrame 转换为 NumPy 数组 44 | 45 | ## 计算 Gram 矩阵和正交基 46 | G = X.T @ X # 计算 Gram 矩阵 G 47 | D, V = np.linalg.eig(G) # 对 Gram 矩阵求特征值和特征向量 48 | np.set_printoptions(suppress=True) # 设置 NumPy 打印选项,抑制科学记数法 49 | D = np.diag(D) # 将特征值转换为对角矩阵 50 | 51 | ## 在 Streamlit 应用中展示计算结果 52 | st.latex(r'G = X^T X = ' + bmatrix(G)) # 展示 Gram 矩阵 G 的 LaTeX 表示 53 | st.latex(r'G = V \Lambda V^T') # 展示特征分解公式 54 | st.latex(r'G = ' + 55 | bmatrix(np.round(V, 2)) + '@' + 56 | bmatrix(np.round(D, 2)) + '@' + 57 | bmatrix(np.round(V.T, 2))) # 展示分解结果 58 | st.write('Mapped data:') # 显示映射数据标题 59 | st.latex('Z = XV') # 显示 Z 的 LaTeX 表示 60 | 61 | ## 映射数据 Z 62 | Z = X @ V # 计算映射数据 Z 63 | 64 | ## 创建映射数据的 DataFrame 65 | df = pd.DataFrame(Z, columns=['PC1', 'PC2', 'PC3', 'PC4']) # 创建 DataFrame,列名为主成分 66 | mapping_rule = {0: 'setosa', 1: 'versicolor', 2: 'virginica'} # 定义类别映射规则 67 | df.insert(4, "species", y) # 插入类别列 68 | df['species'] = df['species'].map(mapping_rule) # 应用类别映射 69 | 70 | ## 提取特征列名称 71 | features = df.columns.to_list()[:-1] # 提取特征列名称,不包括类别列 72 | 73 | ## 映射数据表格 74 | with st.expander('Mapped data'): # 创建可展开区域,标题为 "Mapped data" 75 | st.write(df) # 显示映射数据的 DataFrame 76 | 77 | ## 热力图 78 | with st.expander('Heatmap'): # 创建可展开区域,标题为 "Heatmap" 79 | fig_1 = px.imshow(df.iloc[:, 0:4], # 绘制热力图,仅包含特征列 80 | color_continuous_scale='RdYlBu_r') # 使用指定的颜色映射 81 | st.plotly_chart(fig_1) # 显示热力图 82 | 83 | ## 2D 散点图 84 | with st.sidebar: # 创建侧边栏 85 | st.write('2D scatter plot') # 显示标题 "2D scatter plot" 86 | x_feature = st.radio('Horizontal axis', features) # 在侧边栏中选择横轴特征 87 | y_feature = st.radio('Vertical axis', features) # 在侧边栏中选择纵轴特征 88 | 89 | with st.expander('2D scatter plot'): # 创建可展开区域,标题为 "2D scatter plot" 90 | fig_2 = px.scatter(df, x=x_feature, y=y_feature, color="species") # 绘制 2D 散点图 91 | st.plotly_chart(fig_2) # 显示 2D 散点图 92 | 93 | ## 3D 散点图 94 | with st.expander('3D scatter plot'): # 创建可展开区域,标题为 "3D scatter plot" 95 | fig_3 = px.scatter_3d(df, # 绘制 3D 散点图 96 | x='PC1', 97 | y='PC2', 98 | z='PC3', 99 | color='species') # 按类别着色 100 | st.plotly_chart(fig_3) # 显示 3D 散点图 101 | 102 | ## 成对散点图 103 | with st.expander('Pairwise scatter plot'): # 创建可展开区域,标题为 "Pairwise scatter plot" 104 | fig_4 = px.scatter_matrix(df, # 绘制成对散点图 105 | dimensions=["PC1", "PC2", "PC3", "PC4"], # 指定维度 106 | color="species") # 按类别着色 107 | st.plotly_chart(fig_4) # 显示成对散点图 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Book4_Ch10_数据投影__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch10_数据投影__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch11_矩阵分解__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch11_矩阵分解__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch12_Cholesky分解__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch12_Cholesky分解__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch13_Python_Codes/Streamlit_Bk4_Ch13_04.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2022 7 | ############### 8 | 9 | import streamlit as st # 导入 Streamlit 库,用于创建交互式 Web 应用 10 | import numpy as np # 导入 NumPy 库,用于数值计算 11 | import plotly.express as px # 导入 Plotly Express 库,用于绘制交互式图表 12 | import pandas as pd # 导入 Pandas 库,用于数据处理 13 | 14 | # 定义函数 bmatrix,用于将 NumPy 数组转化为 LaTeX 矩阵格式 15 | def bmatrix(a): 16 | """返回一个 LaTeX 矩阵表示""" 17 | if len(a.shape) > 2: # 检查输入的数组是否为二维 18 | raise ValueError('bmatrix 函数最多显示二维矩阵') # 如果不是二维数组,抛出异常 19 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 去掉数组的方括号并按行拆分 20 | rv = [r'\begin{bmatrix}'] # 开始 LaTeX 矩阵的表示 21 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 将每一行的元素用 LaTeX 格式化 22 | rv += [r'\end{bmatrix}'] # 结束 LaTeX 矩阵的表示 23 | return '\n'.join(rv) # 返回拼接后的 LaTeX 字符串 24 | 25 | # 在侧边栏创建交互式滑块,用户可调整矩阵 A 的元素 26 | with st.sidebar: 27 | # 在侧边栏中展示一个 LaTeX 格式的矩阵模板 28 | st.latex(r''' 29 | A = \begin{bmatrix} 30 | a & b\\ 31 | c & d 32 | \end{bmatrix}''') 33 | 34 | # 为矩阵 A 的元素 a, b, c, d 创建滑块,用户可调整这些值 35 | a = st.slider('a', -2.0, 2.0, step=0.1, value=1.0) # 滑块用于设置 a 的值,默认值为 1.0 36 | b = st.slider('b', -2.0, 2.0, step=0.1, value=0.0) # 滑块用于设置 b 的值,默认值为 0.0 37 | c = st.slider('c', -2.0, 2.0, step=0.1, value=0.0) # 滑块用于设置 c 的值,默认值为 0.0 38 | d = st.slider('d', -2.0, 2.0, step=0.1, value=1.0) # 滑块用于设置 d 的值,默认值为 1.0 39 | 40 | #%% 创建网格点用于二维平面上的点 41 | x1_ = np.linspace(-1, 1, 11) # 在 [-1, 1] 区间内生成 11 个均匀分布的点,用于 x1 42 | x2_ = np.linspace(-1, 1, 11) # 在 [-1, 1] 区间内生成 11 个均匀分布的点,用于 x2 43 | 44 | xx1, xx2 = np.meshgrid(x1_, x2_) # 创建二维网格,用于生成所有点的坐标 45 | X = np.column_stack((xx1.flatten(), xx2.flatten())) # 将网格点展开为二维数组,每行一个点的坐标 46 | 47 | # 定义矩阵 A,由用户调整的滑块值确定 48 | A = np.array([[a, b], # 矩阵 A 的第一行 49 | [c, d]]) # 矩阵 A 的第二行 50 | 51 | X = X @ A # 使用矩阵乘法,将点集 X 通过矩阵 A 进行线性变换 52 | 53 | #%% 创建颜色数组并将其添加到点数据中 54 | color_array = np.linspace(0, 1, len(X)) # 为每个点生成一个对应的颜色值,范围为 [0, 1] 55 | X = np.column_stack((X, color_array)) # 将颜色值添加到点数据中,作为第三列 56 | df = pd.DataFrame(X, columns=['z1', 'z2', 'color']) # 将点数据转换为 DataFrame,并命名列为 z1, z2, 和 color 57 | 58 | #%% 绘制散点图 59 | st.latex('A = ' + bmatrix(A)) # 在页面上以 LaTeX 格式展示矩阵 A 60 | 61 | # 使用 Plotly Express 绘制散点图 62 | fig = px.scatter(df, # 数据来源为 DataFrame 63 | x="z1", # z1 作为横轴 64 | y="z2", # z2 作为纵轴 65 | color='color', # 根据 color 列设置点的颜色 66 | color_continuous_scale='rainbow') # 使用彩虹色带表示颜色 67 | 68 | # 设置图形的布局参数 69 | fig.update_layout( 70 | autosize=False, # 禁用自动尺寸调整 71 | width=500, # 设置图形宽度为 500 像素 72 | height=500) # 设置图形高度为 500 像素 73 | 74 | # 添加横轴和纵轴的黑色参考线 75 | fig.add_hline(y=0, line_color='black') # 添加横轴参考线 76 | fig.add_vline(x=0, line_color='black') # 添加纵轴参考线 77 | 78 | # 设置坐标轴的显示范围 79 | fig.update_xaxes(range=[-3, 3]) # 设置 x 轴范围为 [-3, 3] 80 | fig.update_yaxes(range=[-3, 3]) # 设置 y 轴范围为 [-3, 3] 81 | 82 | # 禁用颜色条显示 83 | fig.update_coloraxes(showscale=False) # 隐藏颜色条 84 | 85 | # 在 Streamlit 页面中展示绘制的散点图 86 | st.plotly_chart(fig) 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /Book4_Ch13_特征值分解__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch13_特征值分解__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch14_Python_Codes/Bk4_Ch14_01.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 14\n", 9 | "\n", 10 | "# 矩阵平方根\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "c263fc95-881a-49fb-9c6c-a25508996623", 17 | "metadata": {}, 18 | "source": [ 19 | "该代码的主要任务是通过矩阵分解和重构方法,基于给定的矩阵$A$,验证矩阵重构的正确性。具体流程如下:\n", 20 | "\n", 21 | "1. **定义矩阵$A$**: \n", 22 | " 代码首先创建了一个$2 \\times 2$矩阵 $A = \\begin{bmatrix} 1.25 & -0.75 \\\\ -0.75 & 1.25 \\end{bmatrix}$。矩阵 $A$ 是一个对称矩阵,因此可以进行特征值分解。\n", 23 | "\n", 24 | "2. **计算特征值和特征向量**: \n", 25 | " 代码使用 `np.linalg.eig` 函数对矩阵 $A$ 进行特征值分解,计算出$A$的特征值(存储在 $LAMBDA$ 中)和特征向量(存储在 $V$ 中),满足以下分解公式:\n", 26 | " $$\n", 27 | " A = V \\Lambda V^{-1}\n", 28 | " $$\n", 29 | " 其中,$\\Lambda$ 是一个包含特征值的对角矩阵,$V$ 是由特征向量组成的矩阵。\n", 30 | "\n", 31 | "3. **构建矩阵$B$**: \n", 32 | " 接下来,代码构建了一个新的矩阵 $B$。它的计算公式为:\n", 33 | " $$\n", 34 | " B = V \\sqrt{\\Lambda} V^{-1}\n", 35 | " $$\n", 36 | " 其中,$\\sqrt{\\Lambda}$ 是对角矩阵,其对角元素是 $\\Lambda$ 的平方根。也就是说,$B$ 是通过将 $A$ 的特征值取平方根后重新组合得到的矩阵。\n", 37 | "\n", 38 | "4. **重构矩阵$A$并验证结果**: \n", 39 | " 最后,通过矩阵 $B$ 构造了一个新矩阵 $A_{reproduced}$,其计算公式为:\n", 40 | " $$\n", 41 | " A_{reproduced} = B B^T\n", 42 | " $$\n", 43 | " 这是利用矩阵 $B$ 重构 $A$ 的过程。对称矩阵 $A$ 的特征值平方根分解使得 $B B^T$ 应等于原始矩阵 $A$。因此,通过打印 $A_{reproduced}$,可以验证 $B B^T$ 是否等于 $A$,从而确认重构的正确性。" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 1, 49 | "id": "2759881c-9e2a-4e4d-a79c-1617f2a4be4f", 50 | "metadata": {}, 51 | "outputs": [], 52 | "source": [ 53 | "import numpy as np # 导入NumPy库" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "id": "a685835a-bcda-40f8-ac57-ff3738c0209f", 59 | "metadata": {}, 60 | "source": [ 61 | "## 初始化矩阵A" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 2, 67 | "id": "a6e9a15c-1d77-4a95-a13c-1c825598e8be", 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "A = np.matrix([[1.25, -0.75], # 定义矩阵A\n", 72 | " [-0.75, 1.25]]) # 矩阵的元素" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "id": "55297e89-757e-4136-a0af-4763d1db3e56", 78 | "metadata": {}, 79 | "source": [ 80 | "## 计算特征值和特征向量" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 3, 86 | "id": "998fa920-5e90-408f-8b70-dd3633c870e9", 87 | "metadata": {}, 88 | "outputs": [], 89 | "source": [ 90 | "LAMBDA, V = np.linalg.eig(A) # 计算矩阵A的特征值(LAMBDA)和特征向量(V)" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 4, 96 | "id": "ce8e4f8c-19a0-4392-b1ef-e794dcc5f187", 97 | "metadata": {}, 98 | "outputs": [ 99 | { 100 | "data": { 101 | "text/plain": [ 102 | "array([2. , 0.5])" 103 | ] 104 | }, 105 | "execution_count": 4, 106 | "metadata": {}, 107 | "output_type": "execute_result" 108 | } 109 | ], 110 | "source": [ 111 | "LAMBDA" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 5, 117 | "id": "13196da8-54c0-44bb-ac29-6cf7c6fec408", 118 | "metadata": {}, 119 | "outputs": [ 120 | { 121 | "data": { 122 | "text/plain": [ 123 | "matrix([[ 0.70710678, 0.70710678],\n", 124 | " [-0.70710678, 0.70710678]])" 125 | ] 126 | }, 127 | "execution_count": 5, 128 | "metadata": {}, 129 | "output_type": "execute_result" 130 | } 131 | ], 132 | "source": [ 133 | "V" 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "id": "c6bb1a72-57de-4ae9-a2e2-599db3122538", 139 | "metadata": {}, 140 | "source": [ 141 | "## 构建矩阵B" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 6, 147 | "id": "cb92d4fe-8443-473f-a61c-378630468024", 148 | "metadata": {}, 149 | "outputs": [], 150 | "source": [ 151 | "B = V @ np.diag(np.sqrt(LAMBDA)) @ np.linalg.inv(V) # 根据特征值和特征向量构建矩阵B" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 7, 157 | "id": "da0f2576-d262-41cd-8324-208cf3df1c82", 158 | "metadata": {}, 159 | "outputs": [ 160 | { 161 | "data": { 162 | "text/plain": [ 163 | "matrix([[ 1.06066017, -0.35355339],\n", 164 | " [-0.35355339, 1.06066017]])" 165 | ] 166 | }, 167 | "execution_count": 7, 168 | "metadata": {}, 169 | "output_type": "execute_result" 170 | } 171 | ], 172 | "source": [ 173 | "B" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "id": "d70a4893-0524-47aa-91ad-4ad9863a5c89", 179 | "metadata": {}, 180 | "source": [ 181 | "## 重构矩阵A并打印" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 8, 187 | "id": "d07c6472-787a-44c2-9d20-99e4d070826a", 188 | "metadata": {}, 189 | "outputs": [ 190 | { 191 | "name": "stdout", 192 | "output_type": "stream", 193 | "text": [ 194 | "[[ 1.25 -0.75]\n", 195 | " [-0.75 1.25]]\n" 196 | ] 197 | } 198 | ], 199 | "source": [ 200 | "A_reproduced = B @ B.T # 通过矩阵B的转置乘积重构矩阵A\n", 201 | "print(A_reproduced) # 输出重构后的矩阵A" 202 | ] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": null, 207 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 208 | "metadata": {}, 209 | "outputs": [], 210 | "source": [] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": null, 215 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 216 | "metadata": {}, 217 | "outputs": [], 218 | "source": [] 219 | } 220 | ], 221 | "metadata": { 222 | "kernelspec": { 223 | "display_name": "Python 3 (ipykernel)", 224 | "language": "python", 225 | "name": "python3" 226 | }, 227 | "language_info": { 228 | "codemirror_mode": { 229 | "name": "ipython", 230 | "version": 3 231 | }, 232 | "file_extension": ".py", 233 | "mimetype": "text/x-python", 234 | "name": "python", 235 | "nbconvert_exporter": "python", 236 | "pygments_lexer": "ipython3", 237 | "version": "3.12.7" 238 | } 239 | }, 240 | "nbformat": 4, 241 | "nbformat_minor": 5 242 | } 243 | -------------------------------------------------------------------------------- /Book4_Ch14_Python_Codes/Streamlit_Bk4_Ch14_02.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | import numpy as np # 导入NumPy库,用于数值计算 10 | import streamlit as st # 导入Streamlit库,用于创建交互式Web应用 11 | import time # 导入time模块,用于添加延时效果 12 | 13 | # 定义状态转移矩阵 A 14 | A = np.matrix([[0.7, 0.2], # 第一行表示从鸡到鸡的概率为0.7,从鸡到兔子的概率为0.3 15 | [0.3, 0.8]]) # 第二行表示从兔子到鸡的概率为0.2,从兔子到兔子的概率为0.8 16 | 17 | # 在侧边栏中创建交互组件 18 | with st.sidebar: 19 | # 创建滑块,用于用户设置初始状态中鸡的比例 20 | pi_0_chicken = st.slider('Ratio of chicken:', # 滑块标题 21 | 0.0, 1.0, step=0.1) # 范围从0到1,每次步进0.1 22 | pi_0_rabbit = 1 - pi_0_chicken # 计算兔子的比例,使鸡和兔子的比例和为1 23 | st.write('Ratio of rabbit: ' + str(round(pi_0_rabbit, 1))) # 显示兔子的比例,保留1位小数 24 | 25 | # 创建滑块,用于用户设置模拟的天数 26 | num_iterations = st.slider('Number of nights:', # 滑块标题 27 | 20, 100, step=5) # 范围从20到100,每次步进5 28 | 29 | # 创建进度条和状态文本,用于显示迭代进度 30 | progress_bar = st.sidebar.progress(0) # 初始化进度条为0% 31 | status_text = st.sidebar.empty() # 创建一个空白的文本区域,用于显示进度百分比 32 | 33 | # 初始化状态向量,将用户输入的初始比例存入数组 34 | last_rows = np.array([[pi_0_chicken, pi_0_rabbit]]) # 初始状态为一个行向量,包含鸡和兔子的比例 35 | 36 | # 创建一个折线图,用于实时展示状态变化 37 | chart = st.line_chart(last_rows) # 初始化折线图,并将初始状态绘制到图上 38 | 39 | # 开始迭代模拟状态转移 40 | for i in range(1, num_iterations): # 循环从第1天到用户设置的总天数 41 | last_status = last_rows[-1, :] # 获取当前的状态向量(最后一行) 42 | new_rows = last_status @ A.T # 使用矩阵乘法计算下一个状态,转移矩阵取转置 43 | percent = (i + 1) * 100 / num_iterations # 计算当前完成的百分比 44 | 45 | # 更新进度条和状态文本 46 | status_text.text("%i%% Complete" % percent) # 显示当前完成的百分比 47 | chart.add_rows(new_rows) # 将新状态添加到折线图 48 | progress_bar.progress(i) # 更新进度条的值 49 | last_rows = new_rows # 更新最后的状态向量为当前计算的状态 50 | time.sleep(0.1) # 延时0.1秒,以便观察每次状态更新 51 | 52 | # 清空进度条,表示模拟完成 53 | progress_bar.empty() # 移除进度条 54 | 55 | -------------------------------------------------------------------------------- /Book4_Ch14_Python_Codes/Streamlit_Bk4_Ch14_03.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | 10 | import plotly.graph_objects as go # 导入 Plotly 的图形对象模块,用于创建复杂的图形 11 | import streamlit as st # 导入 Streamlit 库,用于创建交互式 Web 应用 12 | import numpy as np # 导入 NumPy,用于数值计算 13 | import plotly.express as px # 导入 Plotly Express,用于快速绘制图表 14 | import pandas as pd # 导入 Pandas,用于数据处理 15 | import sympy # 导入 SymPy,用于符号运算和公式化表达 16 | 17 | # 定义函数 bmatrix,将 NumPy 数组转换为 LaTeX 格式的矩阵表示 18 | def bmatrix(a): 19 | """返回一个 LaTeX 矩阵表示""" 20 | if len(a.shape) > 2: # 检查输入是否为二维数组 21 | raise ValueError('bmatrix 函数最多显示二维矩阵') # 如果不是二维,抛出异常 22 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 将数组转换为字符串并去掉方括号 23 | rv = [r'\begin{bmatrix}'] # 开始 LaTeX 矩阵的格式 24 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 逐行添加 LaTeX 矩阵行 25 | rv += [r'\end{bmatrix}'] # 结束 LaTeX 矩阵的格式 26 | return '\n'.join(rv) # 返回拼接后的 LaTeX 字符串 27 | 28 | # 创建 Streamlit 侧边栏,用于调整矩阵 A 的参数 29 | with st.sidebar: 30 | # 显示矩阵 A 的 LaTeX 表示 31 | st.latex(r''' 32 | A = \begin{bmatrix} 33 | a & b\\ 34 | b & c 35 | \end{bmatrix}''') 36 | 37 | # 创建滑块,允许用户调整矩阵 A 的元素 a, b, c 的值 38 | a = st.slider('a', -2.0, 2.0, step=0.05, value=1.0) # 滑块用于调整 a 的值 39 | b = st.slider('b', -2.0, 2.0, step=0.05, value=0.0) # 滑块用于调整 b 的值 40 | c = st.slider('c', -2.0, 2.0, step=0.05, value=1.0) # 滑块用于调整 c 的值 41 | 42 | #%% 创建一个单位圆的点集 43 | theta_array = np.linspace(0, 2 * np.pi, 36) # 在 [0, 2π] 区间生成 36 个点,表示角度 44 | X = np.column_stack((np.cos(theta_array), # 用 cos 和 sin 创建单位圆上的点 45 | np.sin(theta_array))) 46 | 47 | # 创建矩阵 A 48 | A = np.array([[a, b], # 矩阵 A 的第一行 49 | [b, c]]) # 矩阵 A 的第二行 50 | 51 | # 显示单位圆的方程和线性变换后的方程 52 | st.latex(r'''z^Tz = 1''') # 显示单位圆的方程 53 | st.latex(r'''x = Az''') # 显示线性变换的方程 54 | 55 | # 显示矩阵 A 的 LaTeX 表示 56 | st.latex('A =' + bmatrix(A)) 57 | 58 | # 对单位圆的点集进行线性变换 59 | X_ = X @ A # 对单位圆上的点集 X 应用线性变换矩阵 A 60 | 61 | #%% 使用符号运算求解椭圆的方程 62 | x1, x2 = sympy.symbols('x1 x2') # 定义符号变量 x1 和 x2 63 | y1, y2 = sympy.symbols('y1 y2') # 定义符号变量 y1 和 y2 64 | x = np.array([[x1, x2]]).T # 定义符号向量 x 65 | y = np.array([[y1, y2]]).T # 定义符号向量 y 66 | 67 | # 计算 Q 矩阵 68 | Q = np.linalg.inv(A @ A.T) # Q = (AA^T)^(-1) 69 | D, V = np.linalg.eig(Q) # 计算 Q 的特征值和特征向量 70 | D = np.diag(D) # 将特征值转化为对角矩阵 71 | 72 | # 显示 Q 矩阵的分解 73 | st.latex(r'Q = \left( AA^T\right)^{-1} = ' + bmatrix(np.round(Q, 3))) # 显示 Q 矩阵 74 | st.latex(r'''Q = V \Lambda V^{T}''') # 显示特征分解公式 75 | st.latex(bmatrix(np.around(Q, decimals=3)) + '=' + 76 | bmatrix(np.around(V, decimals=3)) + '@' + 77 | bmatrix(np.around(D, decimals=3)) + '@' + 78 | bmatrix(np.around(V.T, decimals=3))) # 显示分解过程 79 | 80 | # 定义单位圆和变换后的椭圆方程 81 | f_x = x.T @ np.round(Q, 3) @ x # 单位圆在 Q 矩阵下的方程 82 | f_y = y.T @ np.round(D, 3) @ y # 椭圆在对角矩阵 D 下的方程 83 | 84 | # 显示椭圆方程 85 | from sympy import * 86 | st.write('The formula of the ellipse:') # 显示椭圆方程的标题 87 | st.latex(latex(simplify(f_x[0][0])) + ' = 1') # 显示椭圆方程 88 | st.write('The formula of the transformed ellipse:') # 显示变换后椭圆方程的标题 89 | st.latex(latex(simplify(f_y[0][0])) + ' = 1') # 显示变换后的椭圆方程 90 | 91 | #%% 添加颜色信息到变换后的点集 92 | color_array = np.linspace(0, 1, len(X)) # 为每个点生成一个颜色值 93 | X_c = np.column_stack((X_, color_array)) # 将颜色信息添加到点集中 94 | df = pd.DataFrame(X_c, columns=['x1', 'x2', 'color']) # 将点集转换为 DataFrame 格式 95 | 96 | #%% 绘制散点图 97 | fig = px.scatter(df, # 使用 Pandas 数据框作为数据源 98 | x="x1", # 横轴为 x1 99 | y="x2", # 纵轴为 x2 100 | color='color', # 根据颜色值为点上色 101 | color_continuous_scale=px.colors.sequential.Rainbow) # 使用彩虹色带 102 | 103 | # 设置图形布局 104 | fig.update_layout( 105 | autosize=False, # 禁用自动调整尺寸 106 | width=500, # 图表宽度为 500 像素 107 | height=500) # 图表高度为 500 像素 108 | 109 | # 添加横轴和纵轴的参考线 110 | fig.add_hline(y=0, line_color='black') # 添加黑色的水平参考线 111 | fig.add_vline(x=0, line_color='black') # 添加黑色的垂直参考线 112 | fig.update_layout(coloraxis_showscale=False) # 隐藏颜色条 113 | fig.update_xaxes(range=[-3, 3]) # 设置 x 轴范围 114 | fig.update_yaxes(range=[-3, 3]) # 设置 y 轴范围 115 | 116 | # 在 Streamlit 页面上显示图表 117 | st.plotly_chart(fig) 118 | 119 | 120 | -------------------------------------------------------------------------------- /Book4_Ch14_深入特征值分解__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch14_深入特征值分解__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch15_奇异值分解__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch15_奇异值分解__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch16_Python_Codes/Streamlit_Bk4_Ch16_01.py: -------------------------------------------------------------------------------- 1 | ############### 2 | # Authored by Weisheng Jiang 3 | # Book 4 | From Basic Arithmetic to Machine Learning 4 | # Published and copyrighted by Tsinghua University Press 5 | # Beijing, China, 2025 6 | ############### 7 | 8 | import streamlit as st # 导入 Streamlit 库,用于创建交互式 Web 应用 9 | import plotly.express as px # 导入 Plotly Express,用于绘制交互式图表 10 | 11 | import numpy as np # 导入 NumPy,用于数值计算 12 | import pandas as pd # 导入 Pandas,用于数据处理 13 | from sklearn.datasets import load_iris # 从 scikit-learn 导入 Iris 数据集 14 | 15 | #%% 16 | 17 | # 加载 Iris 数据集 18 | iris = load_iris() # 加载 Iris 数据集 19 | X = iris.data # 提取特征数据 20 | y = iris.target # 提取目标标签 21 | 22 | # 定义特征名称 23 | feature_names = ['Sepal length, x1', 'Sepal width, x2', 24 | 'Petal length, x3', 'Petal width, x4'] # 定义特征名称 25 | 26 | # 将 NumPy 数组 X 转换为 Pandas DataFrame 27 | X_df = pd.DataFrame(X, columns=feature_names) # 创建 DataFrame 并指定列名为特征名称 28 | 29 | # 在侧边栏中展示矩阵分解公式 30 | with st.sidebar: 31 | st.latex('X = USV^T') # 展示 SVD 的公式 32 | st.latex('X = \sum_{j=1}^{D} s_j u_j v_j^T') # 展示矩阵分解的展开公式 33 | st.latex('X \simeq \sum_{j=1}^{p} s_j u_j v_j^T') # 展示矩阵近似公式 34 | 35 | #%% 原始数据 X 36 | 37 | X = X_df.to_numpy() # 将 DataFrame 转换回 NumPy 数组 38 | 39 | # 计算矩阵 X 的奇异值分解 40 | U, S, V_T = np.linalg.svd(X, full_matrices=False) # 进行 SVD 分解 41 | S = np.diag(S) # 将奇异值转换为对角矩阵 42 | V = V_T.T # 转置右奇异矩阵以获得列向量形式 43 | 44 | # 在侧边栏中添加滑块,用于选择近似矩阵的成分数 p 45 | with st.sidebar: 46 | p = st.slider('Choose p, number of component to approximate X:', # 滑块标题 47 | 1, 4, step=1) # 滑块范围为 1 到 4,步进为 1 48 | 49 | #%% 近似矩阵 X 50 | 51 | # 使用前 p 个奇异值、左奇异向量和右奇异向量近似原始矩阵 X 52 | X_apprx = U[:, 0:p] @ S[0:p, 0:p] @ V[:, 0:p].T # 根据前 p 个成分计算近似矩阵 53 | X_apprx_df = pd.DataFrame(X_apprx, columns=feature_names) # 将近似矩阵转换为 DataFrame 54 | 55 | # 计算误差矩阵 56 | Error_df = X_df - X_apprx_df # 原始矩阵与近似矩阵的差 57 | 58 | #%% 可视化原始矩阵、近似矩阵和误差矩阵 59 | 60 | # 使用 Streamlit 的列布局 61 | col1, col2, col3 = st.columns(3) # 创建三列布局 62 | 63 | # 在第一列中显示原始矩阵 X 64 | with col1: 65 | st.latex('X') # 显示原始矩阵的 LaTeX 表示 66 | fig_1 = px.imshow(X_df, # 绘制热图表示原始矩阵 67 | color_continuous_scale='RdYlBu_r', # 使用红黄蓝色带 68 | range_color=[0, 8]) # 设置颜色范围 69 | 70 | fig_1.layout.height = 500 # 设置图像高度为 500 像素 71 | fig_1.layout.width = 300 # 设置图像宽度为 300 像素 72 | fig_1.update_layout(coloraxis_showscale=False) # 隐藏颜色条 73 | st.plotly_chart(fig_1) # 在 Streamlit 页面中显示图表 74 | 75 | # 在第二列中显示近似矩阵 X_apprx 76 | with col2: 77 | st.latex('\hat{X}') # 显示近似矩阵的 LaTeX 表示 78 | fig_2 = px.imshow(X_apprx_df, # 绘制热图表示近似矩阵 79 | color_continuous_scale='RdYlBu_r', # 使用红黄蓝色带 80 | range_color=[0, 8]) # 设置颜色范围 81 | 82 | fig_2.layout.height = 500 # 设置图像高度为 500 像素 83 | fig_2.layout.width = 300 # 设置图像宽度为 300 像素 84 | fig_2.update_layout(coloraxis_showscale=False) # 隐藏颜色条 85 | st.plotly_chart(fig_2) # 在 Streamlit 页面中显示图表 86 | 87 | # 在第三列中显示误差矩阵 X - X_apprx 88 | with col3: 89 | st.latex('X - \hat{X}') # 显示误差矩阵的 LaTeX 表示 90 | fig_3 = px.imshow(Error_df, # 绘制热图表示误差矩阵 91 | color_continuous_scale='RdYlBu_r', # 使用红黄蓝色带 92 | range_color=[0, 8]) # 设置颜色范围 93 | 94 | fig_3.layout.height = 500 # 设置图像高度为 500 像素 95 | fig_3.layout.width = 300 # 设置图像宽度为 300 像素 96 | fig_3.update_layout(coloraxis_showscale=False) # 隐藏颜色条 97 | st.plotly_chart(fig_3) # 在 Streamlit 页面中显示图表 98 | 99 | 100 | -------------------------------------------------------------------------------- /Book4_Ch16_深入奇异值分解__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch16_深入奇异值分解__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch17_Python_Codes/Streamlit_Bk4_Ch17_01.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | import sympy # 导入 sympy,用于符号计算 10 | import numpy as np # 导入 NumPy,用于数值计算 11 | from sympy.functions import exp # 从 sympy 导入指数函数 12 | import streamlit as st # 导入 Streamlit,用于创建交互式 Web 应用 13 | import plotly.figure_factory as ff # 导入 Plotly 工厂方法,用于可视化 14 | import plotly.graph_objects as go # 导入 Plotly 图形对象模块,用于复杂图形 15 | 16 | # 定义符号变量和函数 17 | x1, x2 = sympy.symbols('x1 x2') # 定义符号变量 x1 和 x2 18 | f_x = x1 * exp(-(x1**2 + x2**2)) # 定义函数 f(x1, x2) = x1 * exp(-(x1^2 + x2^2)) 19 | 20 | # 在页面上显示函数的 LaTeX 表示 21 | st.latex('f(x_1, x_2) = ' + sympy.latex(f_x)) # 显示 f(x1, x2) 的 LaTeX 表达式 22 | 23 | # 计算函数的梯度 24 | grad_f = [sympy.diff(f_x, var) for var in (x1, x2)] # 对 x1 和 x2 求偏导,得到梯度 25 | st.latex(r'\nabla f = ' + sympy.latex(grad_f) + '^T') # 显示梯度的 LaTeX 表达式 26 | 27 | # 将符号函数转换为数值计算函数 28 | f_x_fcn = sympy.lambdify([x1, x2], f_x) # 将 f_x 转换为 Python 函数 29 | grad_fcn = sympy.lambdify([x1, x2], grad_f) # 将梯度 grad_f 转换为 Python 函数 30 | 31 | # 定义 x1 和 x2 的值域,用于生成网格 32 | x1_array = np.linspace(-2, 2, 100) # 在 [-2, 2] 范围内生成 100 个均匀点 33 | x2_array = np.linspace(-2, 2, 100) # 同样生成 x2 的点 34 | 35 | # 创建细网格,用于绘制函数表面 36 | xx1, xx2 = np.meshgrid(x1_array, x2_array) # 创建细网格 37 | # 创建粗网格,用于绘制梯度场 38 | xx1_, xx2_ = np.meshgrid(np.linspace(-2, 2, 20), np.linspace(-2, 2, 20)) # 创建粗网格 39 | 40 | # 在粗网格上计算梯度向量 41 | V = grad_fcn(xx1_, xx2_) # 使用梯度函数计算粗网格上的梯度向量 42 | # 在细网格上计算函数值 43 | ff_x = f_x_fcn(xx1, xx2) # 使用函数 f_x 计算细网格上的函数值 44 | 45 | #%% 可视化 46 | 47 | # 绘制函数表面 48 | fig_surface = go.Figure(go.Surface( 49 | x=x1_array, # 表面图的 x 轴为 x1 的值 50 | y=x2_array, # 表面图的 y 轴为 x2 的值 51 | z=ff_x, # 表面图的 z 轴为函数值 52 | showscale=False)) # 禁用颜色条 53 | fig_surface.update_layout( 54 | autosize=False, # 禁用自动调整大小 55 | width=800, # 设置图表宽度为 800 像素 56 | height=800) # 设置图表高度为 800 像素 57 | 58 | # 在 Streamlit 页面上显示表面图 59 | st.plotly_chart(fig_surface) 60 | 61 | # 创建梯度场和等高线图 62 | f = ff.create_quiver(xx1_, xx2_, V[0], V[1]) # 创建梯度场图 63 | trace1 = f.data[0] # 提取梯度场的图层数据 64 | trace2 = go.Contour( # 创建等高线图 65 | x=x1_array, # 等高线图的 x 轴为 x1 的值 66 | y=x2_array, # 等高线图的 y 轴为 x2 的值 67 | z=ff_x, # 等高线图的 z 轴为函数值 68 | showscale=False) # 禁用颜色条 69 | 70 | # 将梯度场和等高线图合并为一个图形 71 | data = [trace1, trace2] # 合并两个图层数据 72 | fig = go.FigureWidget(data) # 创建图形对象 73 | fig.update_layout( 74 | autosize=False, # 禁用自动调整大小 75 | width=800, # 设置图表宽度为 800 像素 76 | height=800) # 设置图表高度为 800 像素 77 | 78 | # 添加辅助线 79 | fig.add_hline(y=0, line_color='black') # 添加水平辅助线 80 | fig.add_vline(x=0, line_color='black') # 添加垂直辅助线 81 | 82 | # 设置坐标轴范围 83 | fig.update_xaxes(range=[-2, 2]) # 设置 x 轴范围为 [-2, 2] 84 | fig.update_yaxes(range=[-2, 2]) # 设置 y 轴范围为 [-2, 2] 85 | fig.update_coloraxes(showscale=False) # 禁用颜色条 86 | 87 | # 在 Streamlit 页面上显示梯度场和等高线图 88 | st.plotly_chart(fig) 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Book4_Ch17_多元函数微分__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch17_多元函数微分__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch18_拉格朗日乘子法__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch18_拉格朗日乘子法__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch19_直线到超平面__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch19_直线到超平面__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch20_Python_Codes/Streamlit_Bk4_Ch20_02.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | import streamlit as st # 导入 Streamlit,用于创建交互式 Web 应用 10 | import plotly.graph_objects as go # 导入 Plotly 图形对象,用于绘图 11 | import sympy # 导入 SymPy,用于符号运算 12 | import numpy as np # 导入 NumPy,用于数值计算 13 | from scipy.stats import multivariate_normal # 从 SciPy 导入多元正态分布 14 | 15 | # 定义一个函数,将 NumPy 数组转换为 LaTeX bmatrix 格式 16 | def bmatrix(a): 17 | """返回一个 LaTeX 矩阵表示""" 18 | if len(a.shape) > 2: # 如果数组维度大于2,抛出异常 19 | raise ValueError('bmatrix 函数最多支持二维矩阵') 20 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 将数组转换为字符串并去掉方括号 21 | rv = [r'\begin{bmatrix}'] # LaTeX 矩阵起始 22 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 按行格式化 23 | rv += [r'\end{bmatrix}'] # LaTeX 矩阵结束 24 | return '\n'.join(rv) # 返回拼接后的字符串 25 | 26 | # 在侧边栏中创建滑块,用于调整协方差矩阵的参数 27 | with st.sidebar: 28 | # 显示协方差矩阵的 LaTeX 表示 29 | st.latex(r''' 30 | \Sigma = \begin{bmatrix} 31 | \sigma_1^2 & 32 | \rho \sigma_1 \sigma_2 \\ 33 | \rho \sigma_1 \sigma_2 & 34 | \sigma_2^2 35 | \end{bmatrix}''') 36 | 37 | # 定义协方差矩阵的元素 38 | st.write('$\sigma_1$') # 显示 σ₁ 39 | sigma_1 = st.slider('sigma_1', 1.0, 2.0, step=0.1) # 创建滑块,用于调整 σ₁ 40 | st.write('$\sigma_2$') # 显示 σ₂ 41 | sigma_2 = st.slider('sigma_2', 1.0, 2.0, step=0.1) # 创建滑块,用于调整 σ₂ 42 | st.write('$\\rho$') # 显示相关系数 ρ 43 | rho_12 = st.slider('rho', -0.9, 0.9, step=0.1) # 创建滑块,用于调整 ρ 44 | 45 | #%% 46 | 47 | # 显示正态分布的概率密度函数公式(1D 和 2D) 48 | st.latex(r''' 49 | f(x) = \frac{1}{\sqrt{2\pi} \sigma} 50 | \exp\left( -\frac{1}{2}\left(\frac{x-\mu}{\sigma}\right)^{\!2}\,\right) 51 | ''') # 1D 正态分布公式 52 | st.latex(r''' 53 | f(x) = \frac{1}{\left( 2 \pi \right)^{\frac{D}{2}} 54 | \begin{vmatrix} 55 | \Sigma 56 | \end{vmatrix}^{\frac{1}{2}}} 57 | \exp\left( 58 | -\frac{1}{2} 59 | \left( x - \mu \right)^{T} \Sigma^{-1} \left( x - \mu \right) 60 | \right) 61 | ''') # 2D 正态分布公式 62 | 63 | #%% 定义网格和协方差矩阵 64 | 65 | # 定义 x1 和 x2 的值域 66 | x1 = np.linspace(-3, 3, 101) # 在 [-3, 3] 上生成 101 个点 67 | x2 = np.linspace(-3, 3, 101) # 同样生成 x2 的点 68 | xx1, xx2 = np.meshgrid(x1, x2) # 创建网格点 69 | pos = np.dstack((xx1, xx2)) # 将网格点堆叠为多维数组 70 | 71 | # 定义协方差矩阵 72 | Sigma = [[sigma_1**2, rho_12 * sigma_1 * sigma_2], # 第一行 73 | [rho_12 * sigma_1 * sigma_2, sigma_2**2]] # 第二行 74 | 75 | # 创建多元正态分布对象 76 | rv = multivariate_normal([0, 0], Sigma) # 均值为 [0, 0],协方差矩阵为 Sigma 77 | PDF_zz = rv.pdf(pos) # 计算网格点上的概率密度值 78 | 79 | #%% 80 | 81 | # 将协方差矩阵转换为 NumPy 数组 82 | Sigma = np.array(Sigma) 83 | 84 | # 计算协方差矩阵的特征值和特征向量 85 | D, V = np.linalg.eig(Sigma) # 特征分解 86 | D = np.diag(D) # 将特征值转化为对角矩阵 87 | 88 | # 显示协方差矩阵和分解结果的 LaTeX 表示 89 | st.latex(r'''\Sigma = \begin{bmatrix}%s & %s\\%s & %s\end{bmatrix}''' 90 | % (sigma_1**2, 91 | rho_12 * sigma_1 * sigma_2, 92 | rho_12 * sigma_1 * sigma_2, 93 | sigma_2**2)) # 显示协方差矩阵 94 | st.latex(r'''\Sigma = V \Lambda V^{T}''') # 显示特征分解公式 95 | st.latex(bmatrix(Sigma) + '=' + 96 | bmatrix(np.around(V, decimals=3)) + '@' + 97 | bmatrix(np.around(D, decimals=3)) + '@' + 98 | bmatrix(np.around(V.T, decimals=3))) # 显示分解的详细过程 99 | 100 | #%% 绘制 3D 表面图 101 | 102 | # 创建 3D 表面图 103 | fig_surface = go.Figure(go.Surface( 104 | x=x1, # x 轴为 x1 的值 105 | y=x2, # y 轴为 x2 的值 106 | z=PDF_zz, # z 轴为概率密度值 107 | colorscale='RdYlBu_r')) # 使用红黄蓝颜色映射 108 | fig_surface.update_layout( 109 | autosize=False, # 禁用自动调整尺寸 110 | width=500, # 图表宽度 111 | height=500) # 图表高度 112 | st.plotly_chart(fig_surface) # 在 Streamlit 页面上显示 3D 表面图 113 | 114 | #%% 绘制 2D 等高线图 115 | 116 | # 创建 2D 等高线图 117 | fig_contour = go.Figure( 118 | go.Contour( 119 | z=PDF_zz, # 等高线图的高度值 120 | x=x1, # x 轴为 x1 的值 121 | y=x2, # y 轴为 x2 的值 122 | colorscale='RdYlBu_r' # 使用红黄蓝颜色映射 123 | )) 124 | 125 | # 设置等高线图的布局 126 | fig_contour.update_layout( 127 | autosize=False, # 禁用自动调整尺寸 128 | width=500, # 图表宽度 129 | height=500) # 图表高度 130 | 131 | # 在 Streamlit 页面上显示 2D 等高线图 132 | st.plotly_chart(fig_contour) 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /Book4_Ch20_再谈圆锥曲线__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch20_再谈圆锥曲线__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch21_Python_Codes/Bk4_Ch21_01.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "73bd968b-d970-4a05-94ef-4e7abf990827", 6 | "metadata": {}, 7 | "source": [ 8 | "Chapter 21\n", 9 | "\n", 10 | "# 判断正定矩阵\n", 11 | "Book_4《矩阵力量》 | 鸢尾花书:从加减乘除到机器学习 (第二版)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "54195758-c635-45fc-be6a-ebae54b12d78", 17 | "metadata": {}, 18 | "source": [ 19 | "这段代码的功能是判断一个矩阵是否为正定矩阵。首先,正定矩阵 \\( A \\) 的定义要求其必须是对称矩阵,即满足 \\( A = A^T \\)。若矩阵 \\( A \\) 是对称矩阵,代码进一步检查是否可以对其进行 Cholesky 分解。Cholesky 分解是一种将正定矩阵 \\( A \\) 表示为下三角矩阵 \\( L \\) 和其转置 \\( L^T \\) 的操作,即\n", 20 | "\n", 21 | "$$\n", 22 | "A = L L^T\n", 23 | "$$\n", 24 | "\n", 25 | "若分解成功,则说明 \\( A \\) 是正定矩阵,函数返回 `True`;若分解失败(引发 `LinAlgError` 异常),则矩阵不是正定矩阵,函数返回 `False`。在这段代码中,示例矩阵\n", 26 | "\n", 27 | "$$\n", 28 | "A = \\begin{bmatrix} 1 & 0 \\\\ 0 & 0 \\end{bmatrix}\n", 29 | "$$\n", 30 | "\n", 31 | "不是正定矩阵,因此代码会输出 `False`。" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 1, 37 | "id": "53cb4618-5e9f-4388-b8e2-893534f3cfbe", 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "import numpy as np # 导入 numpy 进行数值计算" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "id": "74d9b36f-c406-4573-a99e-db75e9380e36", 47 | "metadata": {}, 48 | "source": [ 49 | "## 定义判断正定矩阵的函数" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 2, 55 | "id": "7abef436-2925-4561-90ae-dc85e1fd34f4", 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "def is_pos_def(A): # 函数 is_pos_def 用于判断矩阵是否为正定矩阵\n", 60 | " if np.array_equal(A, A.T): # 检查矩阵是否为对称矩阵\n", 61 | " try:\n", 62 | " np.linalg.cholesky(A) # 尝试进行 Cholesky 分解\n", 63 | " return True # 若成功,则矩阵为正定矩阵\n", 64 | " except np.linalg.LinAlgError: # 若分解失败,捕获异常\n", 65 | " return False # 分解失败则矩阵不是正定矩阵\n", 66 | " else:\n", 67 | " return False # 若矩阵不对称,则直接返回 False" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "id": "7632f259-4cc2-40b5-8886-5c2c670b876c", 73 | "metadata": {}, 74 | "source": [ 75 | "## 定义待检测的矩阵" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 3, 81 | "id": "11933a91-89ae-4529-b5f6-302fa7eebf2b", 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "A = np.array([[1, 0], \n", 86 | " [0, 0]]) # 定义矩阵 A" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 4, 92 | "id": "7bb2c23d-c6ef-4f9a-8c48-01f55905fa97", 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "## 打印结果" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 5, 102 | "id": "6f4d7b05-2a48-40b5-879a-12e58b6ff62a", 103 | "metadata": {}, 104 | "outputs": [ 105 | { 106 | "name": "stdout", 107 | "output_type": "stream", 108 | "text": [ 109 | "False\n" 110 | ] 111 | } 112 | ], 113 | "source": [ 114 | "print(is_pos_def(A)) # 调用函数 is_pos_def,打印矩阵 A 是否为正定矩阵" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "id": "85a80909-2aac-49ed-bb7a-f8cc6b80ee7d", 121 | "metadata": {}, 122 | "outputs": [], 123 | "source": [] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": null, 128 | "id": "ecd322f4-f919-4be2-adc3-69d28ef25e69", 129 | "metadata": {}, 130 | "outputs": [], 131 | "source": [] 132 | } 133 | ], 134 | "metadata": { 135 | "kernelspec": { 136 | "display_name": "Python 3 (ipykernel)", 137 | "language": "python", 138 | "name": "python3" 139 | }, 140 | "language_info": { 141 | "codemirror_mode": { 142 | "name": "ipython", 143 | "version": 3 144 | }, 145 | "file_extension": ".py", 146 | "mimetype": "text/x-python", 147 | "name": "python", 148 | "nbconvert_exporter": "python", 149 | "pygments_lexer": "ipython3", 150 | "version": "3.12.7" 151 | } 152 | }, 153 | "nbformat": 4, 154 | "nbformat_minor": 5 155 | } 156 | -------------------------------------------------------------------------------- /Book4_Ch21_Python_Codes/Streamlit_Bk4_Ch21_02.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | import streamlit as st # 导入 Streamlit,用于构建交互式 Web 应用 10 | import plotly.graph_objects as go # 导入 Plotly 的图形对象模块,用于绘图 11 | import sympy # 导入 SymPy,用于符号运算 12 | import numpy as np # 导入 NumPy,用于数值计算 13 | 14 | def bmatrix(a): # 定义一个函数,将 NumPy 数组转换为 LaTeX bmatrix 格式的字符串 15 | """返回一个 LaTeX 矩阵表示""" 16 | if len(a.shape) > 2: # 如果输入数组维度大于 2,抛出异常 17 | raise ValueError('bmatrix 函数只支持二维矩阵') 18 | lines = str(a).replace('[', '').replace(']', '').splitlines() # 将数组转换为字符串并移除方括号 19 | rv = [r'\begin{bmatrix}'] # LaTeX 矩阵开始符号 20 | rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines] # 按行格式化 21 | rv += [r'\end{bmatrix}'] # LaTeX 矩阵结束符号 22 | return '\n'.join(rv) # 返回拼接后的 LaTeX 字符串 23 | 24 | with st.sidebar: # 在侧边栏中创建交互内容 25 | st.latex(r'''A = \begin{bmatrix} a & b\\ b & c \end{bmatrix}''') # 显示矩阵 A 的 LaTeX 表示 26 | st.latex(r'''f(x_1,x_2) = ax_1^2 + 2bx_1x_2 + cx_2^2''') # 显示二次形式的 LaTeX 表示 27 | a = st.slider('a', -2.0, 2.0, step=0.1) # 创建滑块,用于设置矩阵 A 的元素 a 28 | b = st.slider('b', -2.0, 2.0, step=0.1) # 创建滑块,用于设置矩阵 A 的元素 b 29 | c = st.slider('c', -2.0, 2.0, step=0.1) # 创建滑块,用于设置矩阵 A 的元素 c 30 | 31 | x1_ = np.linspace(-2, 2, 101) # 在 [-2, 2] 范围内生成 101 个均匀点,用于 x1 32 | x2_ = np.linspace(-2, 2, 101) # 同样生成 x2 的点 33 | xx1, xx2 = np.meshgrid(x1_, x2_) # 生成网格点,方便绘制 3D 和等高线图 34 | 35 | x1, x2 = sympy.symbols('x1 x2') # 定义符号变量 x1 和 x2 36 | A = np.array([[a, b], # 定义矩阵 A 的第一行 37 | [b, c]]) # 定义矩阵 A 的第二行 38 | D, V = np.linalg.eig(A) # 计算矩阵 A 的特征值 D 和特征向量 V 39 | D = np.diag(D) # 将特征值转化为对角矩阵 40 | 41 | st.latex(r'''A = \begin{bmatrix}%s & %s\\%s & %s\end{bmatrix}''' % (a, b, b, c)) # 显示矩阵 A 的 LaTeX 表示 42 | st.latex(r'''A = V \Lambda V^{T}''') # 显示特征分解公式 43 | st.latex(bmatrix(A) + '=' + bmatrix(np.around(V, decimals=3)) + '@' + bmatrix(np.around(D, decimals=3)) + '@' + bmatrix(np.around(V.T, decimals=3))) # 显示特征分解的详细过程 44 | 45 | x = np.array([[x1, x2]]).T # 定义符号向量 x 46 | f_x = a * x1**2 + 2 * b * x1 * x2 + c * x2**2 # 定义二次形式 f(x1, x2) 47 | st.latex(r'''f(x_1,x_2) = ''') # 显示二次形式的 LaTeX 表示 48 | st.write(f_x) # 显示二次形式的符号表达式 49 | 50 | f_x_fcn = sympy.lambdify([x1, x2], f_x) # 将符号函数 f(x1, x2) 转换为数值计算函数 51 | ff_x = f_x_fcn(xx1, xx2) # 在网格点上计算二次形式的值 52 | 53 | fig_surface = go.Figure(go.Surface( # 创建 3D 表面图 54 | x=x1_, # 表面图的 x 轴为 x1 的值 55 | y=x2_, # 表面图的 y 轴为 x2 的值 56 | z=ff_x, # 表面图的 z 轴为二次形式的值 57 | colorscale='RdYlBu_r')) # 使用红黄蓝颜色映射 58 | fig_surface.update_layout( 59 | autosize=False, # 禁用自动调整尺寸 60 | width=500, # 设置图表宽度为 500 像素 61 | height=500) # 设置图表高度为 500 像素 62 | st.plotly_chart(fig_surface) # 在 Streamlit 页面上显示 3D 表面图 63 | 64 | fig_contour = go.Figure( # 创建 2D 等高线图 65 | go.Contour( 66 | z=ff_x, # 等高线的高度值 67 | x=x1_, # 等高线图的 x 轴为 x1 的值 68 | y=x2_, # 等高线图的 y 轴为 x2 的值 69 | colorscale='RdYlBu_r' # 使用红黄蓝颜色映射 70 | )) 71 | fig_contour.update_layout( 72 | autosize=False, # 禁用自动调整尺寸 73 | width=500, # 设置图表宽度为 500 像素 74 | height=500) # 设置图表高度为 500 像素 75 | st.plotly_chart(fig_contour) # 在 Streamlit 页面上显示 2D 等高线图 76 | 77 | -------------------------------------------------------------------------------- /Book4_Ch21_Python_Codes/Streamlit_Bk4_Ch21_03.py: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # Authored by Weisheng Jiang 4 | # Book 4 | From Basic Arithmetic to Machine Learning 5 | # Published and copyrighted by Tsinghua University Press 6 | # Beijing, China, 2025 7 | ############### 8 | 9 | import numpy as np # 导入 NumPy,用于数值计算 10 | from sympy import lambdify, diff, exp, latex, simplify, symbols # 从 SymPy 导入符号计算相关模块 11 | import plotly.figure_factory as ff # 从 Plotly 导入工厂方法,用于绘制梯度向量和流线 12 | import plotly.graph_objects as go # 从 Plotly 导入图形对象模块,用于绘图 13 | import streamlit as st # 导入 Streamlit,用于构建交互式 Web 应用 14 | 15 | x1, x2 = symbols('x1 x2') # 定义符号变量 x1 和 x2 16 | num = 301 # 设置网格点数量 17 | x1_array = np.linspace(-3, 3, num) # 在 [-3, 3] 范围内生成 301 个均匀点用于 x1 18 | x2_array = np.linspace(-3, 3, num) # 在 [-3, 3] 范围内生成 301 个均匀点用于 x2 19 | xx1, xx2 = np.meshgrid(x1_array, x2_array) # 创建网格点,用于绘制函数和梯度图 20 | 21 | # 定义函数 f(x1, x2) 22 | f_x = 3 * (1 - x1)**2 * exp(-(x1**2) - (x2 + 1)**2) \ 23 | - 10 * (x1 / 5 - x1**3 - x2**5) * exp(-x1**2 - x2**2) \ 24 | - 1 / 3 * exp(-(x1 + 1)**2 - x2**2) # 定义复杂的二元函数 25 | 26 | f_x_fcn = lambdify([x1, x2], f_x) # 将符号函数 f_x 转换为数值计算函数 27 | f_zz = f_x_fcn(xx1, xx2) # 在网格点上计算函数值,用于绘制表面图和等高线图 28 | 29 | st.latex('f(x_1, x_2) = ' + latex(f_x)) # 在 Streamlit 页面中显示函数的 LaTeX 表示 30 | 31 | # 计算梯度 32 | grad_f = [diff(f_x, var) for var in (x1, x2)] # 对 f_x 分别对 x1 和 x2 求偏导,得到梯度向量 33 | grad_fcn = lambdify([x1, x2], grad_f) # 将梯度向量转换为数值计算函数 34 | 35 | x1__ = np.linspace(-3, 3, 40) # 在 [-3, 3] 范围内生成 40 个点用于 x1(粗网格) 36 | x2__ = np.linspace(-3, 3, 40) # 在 [-3, 3] 范围内生成 40 个点用于 x2(粗网格) 37 | xx1_, xx2_ = np.meshgrid(x1__, x2__) # 创建粗网格点 38 | V = grad_fcn(xx1_, xx2_) # 在粗网格点上计算梯度向量,用于绘制梯度图 39 | 40 | # 绘制 3D 表面图 41 | fig_surface = go.Figure(go.Surface( 42 | x=x1_array, # 表面图的 x 轴为 x1 网格点 43 | y=x2_array, # 表面图的 y 轴为 x2 网格点 44 | z=f_zz, # 表面图的 z 轴为函数值 45 | showscale=False, # 禁用颜色条 46 | colorscale='RdYlBu_r')) # 使用红黄蓝色带 47 | fig_surface.update_layout( 48 | autosize=False, # 禁用自动调整尺寸 49 | width=800, # 设置图表宽度为 800 像素 50 | height=600) # 设置图表高度为 600 像素 51 | st.plotly_chart(fig_surface) # 在 Streamlit 页面中显示 3D 表面图 52 | 53 | # 绘制梯度向量图和等高线图 54 | f = ff.create_quiver(xx1_, xx2_, V[0], V[1], arrow_scale=.1, scale=0.03) # 创建梯度向量图 55 | f_stream = ff.create_streamline(x1__, x2__, V[0], V[1], arrow_scale=.1) # 创建流线图 56 | trace1 = f.data[0] # 提取梯度向量的图层数据 57 | trace3 = f_stream.data[0] # 提取流线的图层数据 58 | trace2 = go.Contour( 59 | x=x1_array, # 等高线图的 x 轴为 x1 网格点 60 | y=x2_array, # 等高线图的 y 轴为 x2 网格点 61 | z=f_zz, # 等高线图的高度值为函数值 62 | showscale=False, # 禁用颜色条 63 | colorscale='RdYlBu_r') # 使用红黄蓝色带 64 | 65 | data = [trace1, trace2] # 将梯度向量图和等高线图组合 66 | fig = go.FigureWidget(data) # 创建图形对象 67 | fig.update_layout( 68 | autosize=False, # 禁用自动调整尺寸 69 | width=800, # 设置图表宽度为 800 像素 70 | height=800) # 设置图表高度为 800 像素 71 | fig.add_hline(y=0, line_color='black') # 添加水平辅助线 72 | fig.add_vline(x=0, line_color='black') # 添加垂直辅助线 73 | fig.update_xaxes(range=[-2, 2]) # 设置 x 轴范围为 [-2, 2] 74 | fig.update_yaxes(range=[-2, 2]) # 设置 y 轴范围为 [-2, 2] 75 | fig.update_coloraxes(showscale=False) # 禁用颜色条 76 | st.plotly_chart(fig) # 在 Streamlit 页面中显示组合图形 77 | 78 | # 绘制流线图和等高线图 79 | data2 = [trace3, trace2] # 将流线图和等高线图组合 80 | fig2 = go.FigureWidget(data2) # 创建图形对象 81 | fig2.update_layout( 82 | autosize=False, # 禁用自动调整尺寸 83 | width=800, # 设置图表宽度为 800 像素 84 | height=800) # 设置图表高度为 800 像素 85 | fig2.add_hline(y=0, line_color='black') # 添加水平辅助线 86 | fig2.add_vline(x=0, line_color='black') # 添加垂直辅助线 87 | fig2.update_xaxes(range=[-2, 2]) # 设置 x 轴范围为 [-2, 2] 88 | fig2.update_yaxes(range=[-2, 2]) # 设置 y 轴范围为 [-2, 2] 89 | fig2.update_coloraxes(showscale=False) # 禁用颜色条 90 | st.plotly_chart(fig2) # 在 Streamlit 页面中显示流线图和等高线图 91 | -------------------------------------------------------------------------------- /Book4_Ch21_曲面和正定性__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch21_曲面和正定性__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch22_数据与统计__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch22_数据与统计__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch23_数据空间__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch23_数据空间__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch24_数据分解__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch24_数据分解__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /Book4_Ch25_数据应用__矩阵力量__从加减乘除到机器学习.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/Book4_Ch25_数据应用__矩阵力量__从加减乘除到机器学习.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 《统计至简》五折入口: 2 | https://zhuanlan.zhihu.com/p/634253719 3 |
4 | 《数学要素》五折入口: 5 | https://zhuanlan.zhihu.com/p/620243026 6 |
7 | 《矩阵力量》五折入口: 8 | https://zhuanlan.zhihu.com/p/634253719 9 | 10 | 看个人情况,开源资源,永久有效哈。 11 | 12 | 纠错多的同学会得到赠书,以示感谢。 13 | -------------------------------------------------------------------------------- /鸢尾花书_整体布局.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Visualize-ML/Book4_Power-of-Matrix/5adb9e44a7537e183f173bdbe1075cbcf461c679/鸢尾花书_整体布局.pdf --------------------------------------------------------------------------------