Add files via upload

This commit is contained in:
Iris Series: Visualize Math -- From Arithmetic Basics to Machine Learning
2025-02-01 17:06:45 +08:00
committed by GitHub
parent f985536e82
commit 79be5dda7d
47 changed files with 10428 additions and 0 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,61 @@
###############
# Authored by Weisheng Jiang
# Book 4 | From Basic Arithmetic to Machine Learning
# Published and copyrighted by Tsinghua University Press
# Beijing, China, 2025
###############
## 导入必要的库
import streamlit as st # 引入Streamlit库用于创建交互式Web应用
import plotly.graph_objects as go # 引入Plotly图形对象模块用于绘图
import numpy as np # 引入NumPy库用于数值计算
## 定义网格数据
x1 = np.linspace(-2.5, 2.5, num=101) # 生成x1的线性等间距数组范围为-2.5到2.5共101个点
x2 = x1 # 定义x2与x1相同
xx1, xx2 = np.meshgrid(x1, x2) # 使用meshgrid生成二维网格数据
## 创建侧边栏以选择参数p
with st.sidebar: # 在侧边栏中设置参数
st.write('Note: Lp norm, p >= 1') # 显示提示信息Lp范数p >= 1
p = st.slider('p', # 创建滑块选择p值
min_value=-20.0, # p值的最小值为-20.0
max_value=20.0, # p值的最大值为20.0
step=0.2) # p值的步长为0.2
## 计算Lp范数的二维数据
zz = ((np.abs((xx1))**p) + (np.abs((xx2))**p))**(1. / p) # 根据Lp范数公式计算二维数据zz
## 创建二维等高线图
fig_1 = go.Figure(data=
go.Contour(z=zz, # 设置z轴数据为zz
x=x1, # 设置x轴数据为x1
y=x2, # 设置y轴数据为x2
colorscale='RdYlBu_r')) # 设置颜色映射为红黄蓝反转
fig_1.update_layout( # 更新图形布局
autosize=False, # 关闭自动调整大小
width=500, # 设置图形宽度为500
height=500, # 设置图形高度为500
margin=dict( # 设置图形边距
l=50, # 左边距为50
r=50, # 右边距为50
b=50, # 底边距为50
t=50)) # 顶边距为50
## 创建三维表面图
fig_2 = go.Figure(
go.Surface(
x=x1, # 设置x轴数据为x1
y=x2, # 设置y轴数据为x2
z=zz, # 设置z轴数据为zz
colorscale='RdYlBu_r')) # 设置颜色映射为红黄蓝反转
## 展示二维等高线图
with st.expander('2D contour'): # 创建可展开部分标题为“2D contour”
st.plotly_chart(fig_1) # 在Streamlit中显示二维等高线图
## 展示三维表面图
with st.expander('3D surface'): # 创建可展开部分标题为“3D surface”
st.plotly_chart(fig_2) # 在Streamlit中显示三维表面图

View File

@@ -0,0 +1,104 @@
###############
# Authored by Weisheng Jiang
# Book 4 | From Basic Arithmetic to Machine Learning
# Published and copyrighted by Tsinghua University Press
# Beijing, China, 2025
###############
## 导入必要的库
import plotly.graph_objects as go # 引入Plotly库用于绘图
import streamlit as st # 引入Streamlit库用于创建交互式Web应用
import numpy as np # 引入NumPy库用于数值计算
import plotly.express as px # 引入Plotly Express库用于快速绘图
import pandas as pd # 引入Pandas库用于数据操作
import sympy # 引入Sympy库用于符号计算
from scipy.spatial import distance # 引入SciPy库中的距离模块
## 定义距离计算函数
# 定义计算Minkowski距离的函数
# 如果设置Chebychev为True则计算Chebychev距离否则根据参数p计算Minkowski距离
def fcn_Minkowski(xx, yy, mu, p=2, Chebychev=False):
if Chebychev: # 如果选择Chebychev距离
zz = np.maximum(np.abs(xx - mu[0]), np.abs(yy - mu[1])) # 计算Chebychev距离
else: # 否则计算Minkowski距离
zz = ((np.abs((xx - mu[0]))**p) + (np.abs((yy - mu[1]))**p))**(1. / p) # 计算公式
return zz # 返回计算结果
# 定义计算Mahalanobis距离的函数
# 可以选择是否标准化Sigma矩阵
def fcn_mahal(xx, yy, mu, Sigma, standardized=False):
if standardized: # 如果选择标准化
D = np.diag(np.diag(Sigma)) # 提取对角线元素
Sigma_inv = np.linalg.inv(D) # 计算逆矩阵
else: # 否则直接计算Sigma的逆矩阵
Sigma_inv = np.linalg.inv(Sigma)
xy_ = np.stack((xx.flatten(), yy.flatten())).T # 将输入数组展平并堆叠
zz = np.diag(np.sqrt(np.dot(np.dot((xy_ - mu), Sigma_inv), (xy_ - mu).T))) # 计算Mahalanobis距离
zz = np.reshape(zz, xx.shape) # 重塑计算结果为网格形状
return zz # 返回计算结果
## 加载数据集
# 使用Plotly自带的鸢尾花数据集
df = px.data.iris()
## 创建侧边栏
with st.sidebar: # 定义侧边栏区域
dist_type = st.radio('Choose a type of distance: ', # 添加单选按钮选择距离类型
options=['Euclidean', 'City block', 'Minkowski', 'Chebychev', 'Mahalanobis', 'Standardized Euclidean'])
if dist_type == 'Minkowski': # 如果选择Minkowski距离
with st.sidebar: # 添加滑块以选择p值
p = st.slider('Specify a p value:', 1.0, 20.0, step=0.5)
## 计算距离
X = df[['sepal_length', 'petal_length']] # 提取鸢尾花数据集中感兴趣的特征
mu = X.mean().to_numpy() # 计算特征的均值
Sigma = X.cov().to_numpy() # 计算特征的协方差矩阵
x_array = np.linspace(0, 10, 101) # 定义x轴网格点
y_array = np.linspace(0, 10, 101) # 定义y轴网格点
xx, yy = np.meshgrid(x_array, y_array) # 创建二维网格
if dist_type == 'Minkowski': # 如果选择Minkowski距离
zz = fcn_Minkowski(xx, yy, mu, p) # 计算Minkowski距离
elif dist_type == 'Euclidean': # 如果选择欧几里得距离
zz = fcn_Minkowski(xx, yy, mu, 2) # 使用p=2计算Minkowski距离
elif dist_type == 'Chebychev': # 如果选择Chebychev距离
zz = fcn_Minkowski(xx, yy, mu, Chebychev=True) # 调用函数计算Chebychev距离
elif dist_type == 'Mahalanobis': # 如果选择Mahalanobis距离
zz = fcn_mahal(xx, yy, mu, Sigma) # 调用函数计算Mahalanobis距离
elif dist_type == 'City block': # 如果选择曼哈顿距离
zz = fcn_Minkowski(xx, yy, mu, 1) # 使用p=1计算Minkowski距离
elif dist_type == 'Standardized Euclidean': # 如果选择标准化欧几里得距离
zz = fcn_mahal(xx, yy, mu, Sigma, True) # 调用函数计算标准化欧几里得距离
## 数据可视化
st.title(dist_type + ' distance') # 设置标题
fig_2 = px.scatter(df, x='sepal_length', y='petal_length') # 绘制散点图
fig_2.add_trace(go.Contour( # 添加等高线
x=x_array, # 设置x轴网格点
y=y_array, # 设置y轴网格点
z=zz, # 设置计算的距离数据
contours_coloring='lines', # 等高线的样式
showscale=False)) # 不显示颜色条
fig_2.add_traces(
px.scatter(X.mean().to_frame().T, # 绘制均值点
x='sepal_length', # x轴为花萼长度
y='petal_length').update_traces(
marker_size=20, # 设置标记大小
marker_color="red", # 设置标记颜色
marker_symbol='x').data)
fig_2.update_layout(yaxis_range=[0, 10]) # 设置y轴范围
fig_2.update_layout(xaxis_range=[0, 10]) # 设置x轴范围
fig_2.add_hline(y=mu[1]) # 添加水平线
fig_2.add_vline(x=mu[0]) # 添加垂直线
fig_2.update_yaxes(
scaleratio=1, # 设置y轴比例
)
fig_2.update_layout(width=600, height=600) # 设置图形尺寸
st.plotly_chart(fig_2) # 在Streamlit中显示图形