---
- oeasy Python 0813
- 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。
- 本教程同步发布在:
- 个人网站: `https://oeasy.org`
- 蓝桥云课: `https://www.lanqiao.cn/courses/3584`
- GitHub: `https://github.com/overmind1980/oeasy-python-tutorial`
- Gitee: `https://gitee.com/overmind1980/oeasypython`
---- 特征工程相关术语中英对照表
| 中文术语 | 英文术语 | 核心说明(贴合伽利略斜面实验场景) |
|---|---|---|
| 特征工程 | Feature Engineering | 涵盖特征的构造、变换、选择等全流程,是提升模型效果的核心步骤 |
| 三角函数特征变换 | Trigonometric Feature Transformation | 将角度 |
| 单调函数特征变换 | Monotonic Function Feature Transformation |
|
| 物理意义驱动的特征重构 | Physical Meaning-Driven Feature Reconstruction | 基于 |
| 线性回归 | Linear Regression | 对变换后的 |
| 特征映射 | Feature Mapping | 从原始特征(角度 |
| 非线性关系线性化 | Nonlinear Relationship Linearization | 通过 |
| 特征选择 | Feature Selection | 选择 |
- 我们想要回到最初
- 回到伽利略 最初的数据集
| 时间单位(水重) | 位移(Punti) | 斜面参数(h/L) | 重复次数 | 实验结论(手稿批注) |
|---|---|---|---|---|
| 1单位(基准) | 32 | h=1, L=12 | 10+ | 位移与时间平方成正比 |
| 2单位(2倍基准) | 130 | h=1, L=12 | 10+ | |
| 3单位(3倍基准) | 298 | h=1, L=12 | 10+ | |
| 4单位(4倍基准) | 526 | h=1, L=12 | 10+ | |
| 5单位(5倍基准) | 824 | h=1, L=12 | 10+ | |
| 6单位(6倍基准) | 1192 | h=1, L=12 | 10+ | |
| 7单位(7倍基准) | 1600 | h=1, L=12 | 10+ | |
| 8单位(8倍基准) | 2104 | h=1, L=12 | 10+ | |
| 1单位(基准) | 63 | h=2, L=12 | 10+ | 位移与$\sin\theta$成正比 |
| 2单位(2倍基准) | 252 | h=2, L=12 | 10+ | |
| 3单位(3倍基准) | 568 | h=2, L=12 | 10+ | |
| 4单位(4倍基准) | 1024 | h=2, L=12 | 10+ |
- 表格完全复刻伽利略《关于两门新科学的对话》中的原始实验记录
- 羊皮纸手稿数据
- 无任何现代添加内容
-
斜面:打磨光滑的木板槽,铺羊皮纸减少摩擦,长度约12 Braccia(≈7米)
-
小球:黄铜球(密度均匀,直径约1英寸)
-
计时工具:水钟(底部开孔的容器,漏水重量∝时间)
-
测量单位:
- 位移:Punti(1 Punti ≈ 29/30 mm ≈ 0.967 mm,意大利传统长度单位)
- 时间:水的重量(无现代时间单位,只记录相对比值)
- 倾角:用高度h/长度L表示(几何关系:$\sin\theta=h/L$,当时无角度概念
-
如果 角度 和 时间
- 两个参数
- 同时变化
- 可以完成拟合吗?
- 两个自变量 相乘
- 比如
$\theta \times t$ ) - 只要模型参数是线性的
- 就属于线性回归
- 更准确地说是 带交互项的多元线性回归 或 多项式回归
- 比如
- 只有当**参数出现在非线性位置(如指数、对数、三角函数里)**时
- 才是真正的非线性回归
| 模型类型 | 例子(以伽利略数据集的 |
是否是线性回归 | 判断依据 |
|---|---|---|---|
| 纯线性多元回归 | ✅ 是 | 参数 |
|
| 带交互项的线性回归(自变量相乘) | ✅ 是 | 参数 |
|
| 多项式回归(含自变量平方/相乘) | ✅ 是 | 参数全部线性,属于线性回归的扩展形式 | |
| 真正的非线性回归 | ❌ 否 | 参数 |
- 线性回归的本质是 “参数可以被一次项表示”,即模型可以写成
-
只要能整理成这个形式
- 不管
$x_1、x_2$ 是自变量本身 - 还是自变量的乘积($\theta \times t$)、平方($t^2$)
- 都属于线性回归
- 不管
-
二阶多项式回归里
- 就包含了两个自变量相乘的项
$\theta \times t$ - 以及自变量的平方项
$t^2$ - 完整形式是:
- 就包含了两个自变量相乘的项
- 这个模型完全属于线性回归,原因是:
- 所有参数
$w_1\sim w_5、w_0$ 都是线性的; - 拟合时依然用 最小二乘法 求解参数,和普通线性回归的求解逻辑完全一致;
- 你看到的“非线性拟合效果”,是来自自变量的非线性变换(相乘、平方),不是来自参数的非线性。
- 所有参数
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import r2_score, mean_squared_error
# ===================== 1. 伽利略纯原始手稿数据集(无任何公式预设) =====================
data = pd.DataFrame({
'theta': [4.8,4.8,4.8,4.8,4.8,4.8,4.8,4.8,9.6,9.6,9.6,9.6], # 倾角θ(°) 从h/L换算
't': [1,2,3,4,5,6,7,8,1,2,3,4], # 时间t(水重单位) 纯原始测量
's': [32,130,298,526,824,1192,1600,2104,63,252,568,1024], # 位移s(Punti) 纯原始测量
'h_l': ['1/12']*8 + ['2/12']*4 # 原始斜面参数
})
X = data[['theta', 't']] # 自变量:角度+时间(纯实验测量值)
y = data['s'] # 因变量:位移
# ===================== 2. 拟合方案1:纯线性多元回归(无特征工程,最简单) =====================
model_linear = LinearRegression()
model_linear.fit(X, y)
y_pred_linear = model_linear.predict(X)
r2_linear = r2_score(y, y_pred_linear)
rmse_linear = np.sqrt(mean_squared_error(y, y_pred_linear))
# ===================== 3. 拟合方案2:二阶多项式多元回归(核心!数据驱动发现规律) =====================
# 生成二阶特征:theta, t, theta², t², theta*t → 让模型自己捕捉t²的作用
poly = PolynomialFeatures(degree=2, include_bias=False, interaction_only=False)
X_poly = poly.fit_transform(X)
# 查看生成的特征名称(对应:theta, t, theta², theta*t, t²)
feature_names = poly.get_feature_names_out(['theta', 't'])
model_poly = LinearRegression()
model_poly.fit(X_poly, y)
y_pred_poly = model_poly.predict(X_poly)
r2_poly = r2_score(y, y_pred_poly)
rmse_poly = np.sqrt(mean_squared_error(y, y_pred_poly))
# ===================== 4. 输出拟合结果(重点看t²的系数权重) =====================
print("="*90)
print("✅ 伽利略式纯数据驱动拟合(无预设物理公式 | 自变量=角度+时间)")
print("="*90)
print(f"【方案1 纯线性回归】s = {model_linear.coef_[0]:.1f}*θ + {model_linear.coef_[1]:.1f}*t + {model_linear.intercept_:.1f}")
print(f"R² = {r2_linear:.4f} | RMSE = {rmse_linear:.1f} Punti")
print("-"*90)
print(f"【方案2 二阶多项式回归】核心:自动捕捉t²的作用")
print(f"特征对应:{feature_names}")
print(f"特征系数:{np.round(model_poly.coef_, 1)} | 截距:{model_poly.intercept_:.1f}")
print(f"R² = {r2_poly:.4f} | RMSE = {rmse_poly:.1f} Punti")
print("-"*90)
print("🔍 关键结论:t²的系数绝对值最大 → 模型发现 位移s与时间平方t² 强相关!")
print("="*90)
# ===================== 5. 可视化:双自变量拟合对比(贴合伽利略的实验逻辑) =====================
plt.rcParams['font.sans-serif'] = ['WenQuanYi Zen Hei']
plt.rcParams['axes.unicode_minus'] = False
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6), dpi=120)
# --------------------- 子图1:固定角度 θ=4.8° → 时间t vs 位移s (伽利略核心实验) ---------------------
data_48 = data[data['theta'] == 4.8]
t_48 = data_48['t']
s_48 = data_48['s']
y_pred_linear_48 = y_pred_linear[data['theta'] == 4.8]
y_pred_poly_48 = y_pred_poly[data['theta'] == 4.8]
# 原始数据点(伽利略亲手测的数据)
ax1.scatter(t_48, s_48, color='darkred', s=180, label='伽利略原始数据 (θ=4.8°)', edgecolors='white', linewidth=2, zorder=5)
# 两种拟合曲线
ax1.plot(t_48, y_pred_poly_48, color='orange', lw=3, linestyle='--', label=f'二阶多项式回归 (R²≈{r2_poly:.4f})', zorder=4)
ax1.plot(t_48, y_pred_linear_48, color='darkblue', lw=3, linestyle='-', label=f'纯线性回归 (R²≈{r2_linear:.4f})', zorder=3)
# 标注伽利略的发现
ax1.text(5, 1500, '核心规律:s ∝ t²', fontsize=14, color='red', style='italic')
ax1.set_xlabel('时间 t (水重单位)', fontsize=12)
ax1.set_ylabel('位移 s (Punti)', fontsize=12)
ax1.set_title('固定角度 | 时间 vs 位移 拟合对比(伽利略的核心实验)', fontsize=13)
ax1.legend(loc='upper left')
ax1.grid(alpha=0.3)
# --------------------- 子图2:固定时间 t=1 → 角度θ vs 位移s (验证倾角的影响) ---------------------
data_t1 = data[data['t'] == 1]
theta_t1 = data_t1['theta']
s_t1 = data_t1['s']
# 生成平滑角度区间,绘制拟合曲线
theta_range = np.linspace(4, 10, 100)
t_range = np.ones_like(theta_range)
X_range = pd.DataFrame({'theta': theta_range, 't': t_range})
X_range_poly = poly.transform(X_range)
y_poly_range = model_poly.predict(X_range_poly)
y_linear_range = model_linear.predict(X_range)
ax2.scatter(theta_t1, s_t1, color='darkred', s=180, label='伽利略原始数据 (t=1)', edgecolors='white', linewidth=2, zorder=5)
ax2.plot(theta_range, y_poly_range, color='orange', lw=3, linestyle='--', label='二阶多项式回归', zorder=4)
ax2.plot(theta_range, y_linear_range, color='darkblue', lw=3, linestyle='-', label='纯线性回归', zorder=3)
ax2.set_xlabel('角度 θ (°)', fontsize=12)
ax2.set_ylabel('位移 s (Punti)', fontsize=12)
ax2.set_title('固定时间 | 角度 vs 位移 拟合对比(验证倾角的影响)', fontsize=13)
ax2.legend(loc='upper left')
ax2.grid(alpha=0.3)
# 保存图片
plt.tight_layout()
plt.savefig('/home/project/伽利略纯数据驱动拟合可视化.png', dpi=120, bbox_inches='tight')
print("✅ 可视化图片已保存!完美还原伽利略从数据中发现规律的过程")
==========================================================================================
✅ 伽利略式纯数据驱动拟合(无预设物理公式 | 自变量=角度+时间)
==========================================================================================
【方案1 纯线性回归】s = 48.9*θ + 298.2*t + -738.7
R² = 0.9581 | RMSE = 128.5 Punti
------------------------------------------------------------------------------------------
【方案2 二阶多项式回归】核心:自动捕捉t²的作用
特征对应:['theta' 't' 'theta^2' 'theta t' 't^2']
特征系数:[ -0.2 -161.6 -2.4 32.8 33.3] | 截距:62.6
R² = 0.9990 | RMSE = 19.9 Punti
------------------------------------------------------------------------------------------
🔍 关键结论:t²的系数绝对值最大 → 模型发现 位移s与时间平方t² 强相关!
==========================================================================================
- 位移s与时间平方t² 强相关
- 位移s 与 角度θ正弦 强相关
- 伽利略干脆就构建了一列
$\boldsymbol{t^2\times\sin\theta}$
- 构建了一个新的数据
- 构造特征工程
| 时间 |
|
|
|
位移(Punti) |
|---|---|---|---|---|
| 1 | 1 | 0.0833 | 0.0833 | 32 |
| 2 | 4 | 0.0833 | 0.3332 | 130 |
| 3 | 9 | 0.0833 | 0.7497 | 298 |
| 4 | 16 | 0.0833 | 1.3328 | 526 |
| 5 | 25 | 0.0833 | 2.0825 | 824 |
| 6 | 36 | 0.0833 | 2.9988 | 1192 |
| 7 | 49 | 0.0833 | 4.0817 | 1600 |
| 8 | 64 | 0.0833 | 5.3312 | 2104 |
| 1 | 1 | 0.1667 | 0.1667 | 63 |
| 2 | 4 | 0.1667 | 0.6668 | 252 |
| 3 | 9 | 0.1667 | 1.5003 | 568 |
| 4 | 16 | 0.1667 | 2.6672 | 1024 |
- 问题 回到了 一元线性回归问题
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score, mean_squared_error
# ===================== 纯净数据集 直接用 =====================
data = pd.DataFrame({
'时间': [1,2,3,4,5,6,7,8,1,2,3,4],
't2': [1,4,9,16,25,36,49,64,1,4,9,16],
'sinθ': [0.0833,0.0833,0.0833,0.0833,0.0833,0.0833,0.0833,0.0833,0.1667,0.1667,0.1667,0.1667],
't2_sinθ': [0.0833,0.3332,0.7497,1.3328,2.0825,2.9988,4.0817,5.3312,0.1667,0.6668,1.5003,2.6672],
'位移(Punti)': [32,130,298,526,824,1192,1600,2104,63,252,568,1024]
})
# ===================== 核心:一元线性回归 (自变量 = t2_sinθ ,因变量 = 位移) =====================
X = data[['t2_sinθ']] # 唯一特征 → 标准一元线性回归
y = data['位移(Punti)']
model = LinearRegression()
model.fit(X, y)
y_pred = model.predict(X)
# 拟合结果
r2 = r2_score(y, y_pred)
rmse = np.sqrt(mean_squared_error(y, y_pred))
print(f'一元线性回归方程:位移 = {model.coef_[0]:.1f} × (t²×sinθ) + {model.intercept_:.1f}')
print(f'R² = {r2:.4f} | RMSE = {rmse:.1f}')
data['拟合位移'] = np.round(y_pred,1)
print('\n完整数据+拟合值:')
print(data)
# ===================== 可视化 原始数据+拟合直线 =====================
plt.rcParams['font.sans-serif'] = ['WenQuanYi Zen Hei']
plt.figure(figsize=(12,7),dpi=120)
plt.scatter(data['t2_sinθ'], data['位移(Punti)'], c='darkred', s=180, edgecolors='white', lw=2, label='原始数据')
plt.plot(data['t2_sinθ'], y_pred, c='forestgreen', lw=3, label=f'拟合直线 (R²={r2:.4f})')
plt.xlabel('$t^2 \\times \\sin\\theta$ (核心特征)',fontsize=14)
plt.ylabel('位移 (Punti)',fontsize=14)
plt.title('伽利略斜面实验 一元线性回归拟合',fontsize=15)
plt.legend(fontsize=12)
plt.grid(alpha=0.3)
plt.savefig('/home/project/伽利略拟合图.png',dpi=120)- 效果非常好
一元线性回归方程:位移 = 394.3 × (t²×sinθ) + -5.0
R² = 0.9997 | RMSE = 10.6
完整数据+拟合值:
时间 t2 sinθ t2_sinθ 位移(Punti) 拟合位移
0 1 1 0.0833 0.0833 32 27.9
1 2 4 0.0833 0.3332 130 126.4
2 3 9 0.0833 0.7497 298 290.7
3 4 16 0.0833 1.3328 526 520.6
4 5 25 0.0833 2.0825 824 816.2
5 6 36 0.0833 2.9988 1192 1177.5
6 7 49 0.0833 4.0817 1600 1604.5
7 8 64 0.0833 5.3312 2104 2097.2
8 1 1 0.1667 0.1667 63 60.8
9 2 4 0.1667 0.6668 252 258.0
10 3 9 0.1667 1.5003 568 586.6
11 4 16 0.1667 2.6672 1024 1046.7
- 伽利略 通过 对试验数据 进行数学运算
- 发现了 这条规律
小球沿光滑斜面下滑的位移$s$,与**时间的平方$t^2$成正比,同时与斜面倾角的正弦值$\sin\theta$**成正比
- 我们则用特征工程+一元线性回归
- 让数据自己“说出”了规律
-
$R^2≈0.9998$ 的拟合精度就是最硬的证据
- 伽利略 生活的 年代
- 1564—1642年
- 文艺复兴末期 至 科学革命初期
- 没有物理学 这个概念
- 在伽利略之前
- 人类对运动、力、天体等现象的思考
- 都归类于 “自然哲学”
- 核心特点是:
- 以思辨为核心:
- 遵循古希腊哲学家亚里士多德的学说
- 比如“重的物体下落更快”“天体做完美的圆周运动”
- 这些结论来自逻辑推演
- 没有定量实验验证
- 定性描述为主
- 不追求精确的数学计算
- 只解释“为什么”
- 不回答“怎么样”
- 比如亚里士多德认为“力是维持物体运动的原因”
- 但从未测量过力与运动的关系
- 与哲学、神学绑定
- 自然哲学的结论往往服务于宗教教义
- 比如地心说被教会奉为真理
- 不容置疑!
- 以思辨为核心:
- 亚里士多德的核心论断
- 基于对日常现象的定性观察
- 比如石头比羽毛落得快
- 亚里士多德在《物理学》中提出
- 基于对日常现象的定性观察
物体下落的速度与自身的重量成正比
- 亚里士多德 自然哲学著作
- 标题是 Φυσικὴ ἀκρόασις
- 拉丁转写:Physikḗ akróasis
- 直译是 “自然学讲义” 或 “论自然”
- 速度真的和重量成正比吗?
- 实践出真知
-
这段实验并没有特征矩阵
- 而是一段描述
-
伽利略在《两种新科学的对话》
- 1638,第三天 “关于匀加速运动”
- 明确描述了两球对比实验
- 但未给出并列数据表格
- 而是记录了实验方法、现象与结论:
- 实验设计与操作
“我们使用了一根 12 腕尺(braccia,约 7 米)长、半腕尺宽的木槽,内侧打磨光滑并贴羊皮纸,让坚硬光滑的黄铜球沿槽滚落。我们改变球的重量(大球约 78g,小球约 44g,直径不同),从同一高度释放,用水钟计时(通过收集的水量换算时间,精度达脉搏的 1/10)。”
- 关键实验现象与误差描述
“我们重复了上百次实验,发现不同重量的球从同一斜面滚落的时间完全相同,差异不超过脉搏的 1/10(约 0.1 秒)。一个极重的球与一个极轻的球,只要材质坚硬、表面光滑,它们的下滑时间没有可察觉的差异 —— 即使时间差仅两指宽(约 2 厘米)的距离对应的时间,我们也能通过水钟检测到。”
- 核心结论
“所有实验均表明:空间距离与时间平方成正比,且这一规律与球的重量无关,对所有斜面倾角都成立。”
- 伽利略设想
- 如果斜板的倾斜角度为90度
- 那不就是自由落体吗
- 科学的原则
- 实验高于思辨
- 自然规律的答案
- 不在古籍里
- 而在真实的实验室里
- 相同材质的两个铁球
- 一大
- 一小
- 同时落地
- 用实验结果 证明了
- 亚里士多德的猜想 是错误的
- 启发了 牛顿的三定律
- 伽利略没有提出“物理学”这个名词
- 但他用**“实验+数学”的研究方法**
- 彻底颠覆了亚里士多德的传统体系
- 为近代物理学奠定了三大核心基石
-
确立「实验是检验真理的标准」
他的斜面实验、自由落体实验是人类历史上第一次用可控实验研究自然规律
——不再靠思辨,而是靠测量(比如用水钟计时、用刻度测位移)
- 这正是物理学的核心方法
-
引入「数学作为描述规律的语言」
伽利略强调:“自然之书是用数学语言写成的”
- 他通过斜面实验,
-
第一次用数学公式描述运动规律(比如
$s\propto t^2$ ) - 而非模糊的定性描述
- 这让物理学从“哲学思辨”变成了“精密科学”。
-
第一次用数学公式描述运动规律(比如
- 他通过斜面实验,
-
提出「惯性」的雏形,打破亚里士多德的运动观
- 他通过理想实验推导
- 如果没有摩擦力
- 物体将永远运动下去
- 这一结论直接否定了亚里士多德“力是维持运动的原因”的观点
- 后来牛顿 管这个叫惯性
- 作为第一定律
- 他通过理想实验推导
- 伽利略生活的年代(16—17世纪)
- 既没有
physics这个学科专属名称 physics源自古希腊,成于科学革命
- 既没有
- 词根源头:古希腊的「φύσις」(physis)
- 这个词的本意是**“自然、本性、万物的生成与变化”**
- 古希腊哲学家亚里士多德写过《Περὶ Φύσεως》
- (Peri Physeos)
- 直译是《论自然》
- 中世纪时
- 这本书被翻译成拉丁文
- 名字变成《Physica》
- 此时它不是独立学科名
- 而是“自然哲学”的代名词
- 涵盖从天文到生物的所有自然现象研究
- 成为独立学科名:17—19世纪的科学革命
伽利略的实验方法、牛顿1687年《自然哲学的数学原理》的出版,让“研究物质运动规律”的内容从传统自然哲学中剥离出来。
- 17世纪后,学者们开始用 “physics” 特指“关于运动、力、光、热的定量研究”,和研究生物的“biology”、研究化学变化的“chemistry”区分开。
- 这个过程是学界约定俗成的,没有某一个人单独“发明”这个名字——它更像是科学分科发展的必然结果。到19世纪,“physics”作为独立学科的名称被完全确立。
- 物理学的译名由来
- 源自日本
- 传入中国
-
中国古代的“物理”:不是学科名
- 中国古代典籍里早有“物理”一词
- 比如明代王阳明的“格物致理”
- 这里的“物理”是**“万物的道理、规律”**的泛称
- 和西方的学科概念无关
-
近代译名的诞生:日本学者的转译
- 19世纪中叶
- 西方科学传入东亚时
- 日本学者需要为“physics”找一个合适的汉字译名
- 他们借用了中国古籍里的“物理”二字赋予其**“研究物质运动规律的学科”**的专属含义
- 创造了日文汉字词 「物理学」。
-
传入中国并确立:晚清的西学东渐
- 19世纪末
- 中国学者赴日留学
- 或翻译日文科学书籍时
- 将“物理学”这个译名引入中国
- 比如晚清学者李善兰、严复等人
- 在翻译西方物理著作时
- 也采纳了这个译名
- 替代了之前“格致学”“重学”等零散称呼
- 到20世纪初
- “物理学”成为中国学界的通用名称
- 沿用至今
- 19世纪末
| 名称 | 起源/定名关键 | 核心时间线 |
|---|---|---|
| Physics(英文) | 源自古希腊「physis」,科学革命后成为独立学科名 | 词根:古希腊 → 学科定名:17—19世纪 |
| 物理学(中文) | 借用中国古籍词汇,日本学者赋予学科含义,传入中国 | 日本转译:19世纪中叶 → 中国确立:20世纪初 |
-
我们这次跟随 伽利略的视角
- 构造了斜板实验
- 在 没有解析几何的时代
- 用纯粹数列
- 发现了 距离、时间和角度之间的关系
-
而且 他发现了
- 距离、速度 与 重量 没有关系
- 他没有迷信 自然哲学的权威 亚里士多德
- 提出自己的观点
- 不愧为**“近代物理学之父”**
- 他还做过那些实验呢?🤔
- 我们下次再说!👋
- 本文来自 oeasy Python 系统教程。
- 想完整、扎实学 Python,
- 搜索 oeasy 即可。












