Skip to content

Commit 5adb9e4

Browse files
authored
Add files via upload
1 parent 79be5dd commit 5adb9e4

27 files changed

+8126
-0
lines changed

Book4_Ch11_Python_Codes/Bk4_Ch11_01.ipynb

+190
Large diffs are not rendered by default.

Book4_Ch11_Python_Codes/Bk4_Ch11_02.ipynb

+374
Large diffs are not rendered by default.

Book4_Ch12_Python_Codes/Bk4_Ch12_01.ipynb

+367
Large diffs are not rendered by default.

Book4_Ch13_Python_Codes/Bk4_Ch13_01.ipynb

+331
Large diffs are not rendered by default.

Book4_Ch13_Python_Codes/Bk4_Ch13_02.ipynb

+344
Large diffs are not rendered by default.

Book4_Ch13_Python_Codes/Bk4_Ch13_03.ipynb

+308
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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+
+242
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
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+
}

0 commit comments

Comments
 (0)