线性代数:描述多维金融世界的语言
想象一下,你如何向计算机描述一个包含100只股票的投资组合?或者如何表示整个市场过去一年的每日收益率?
线性代数 提供了一套优雅而高效的语言来完成这项任务。
向量 (Vectors) :表示有序 的金融数据,如资产权重或价格序列。
矩阵 (Matrices) :表示二维 数据集,如多只股票的收益率或协方差。
从金融概念到数学对象
图示显示一个投资组合被抽象成一个向量,而市场历史数据被抽象成一个矩阵。
投资组合 (Portfolio)
AAPL: 60%
GOOG: 30%
MSFT: 10%
w =
[
0.6
0.3
0.1
]
市场收益率 (Returns)
AAPL GOOG
Day1: +0.5% -0.2%
Day2: -0.1% +0.3%
R=
[
0.005, -0.002
-0.001, 0.003
]
基本构件 1:标量 (Scalar)
标量 是最简单的数学对象:一个单独的数字。
在金融语境中,它可以代表: - 无风险利率: \(r_f = 0.02\) - 某公司的股票价格: \(P_{AAPL} = 175.50\) - 一项资产的权重: \(w_1 = 0.4\)
我们通常用小写斜体字母表示标量,例如 \(a=1\) 或 \(x=3.14\) 。
标量可视化
一条数轴,上面标记了多个整数点,并在1.5的位置有一个蓝点,表示一个标量值。
-2
-1
0
1
2
x = 1.5
基本构件 2:向量 (Vector)
向量 是一列有序 的数字。这个“有序”的特性至关重要。
例如,一个两资产投资组合的权重向量: \[ \large{\mathbf{w} = \begin{bmatrix} 0.6 \\ 0.4 \end{bmatrix}} \] 这明确表示第一个资产(比如股票)占60%,第二个资产(比如债券)占40%。顺序不能颠倒。
我们通常用小写粗体字母 (如 \(\mathbf{x}\) )表示向量。其标准形式是一个用方括号包围的列。
\[ \large{\mathbf{x} = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix}} \]
向量的几何直观:空间中的箭头
我们可以把一个 \(n\) 维向量看作是 \(n\) 维空间中的一个点,或者更直观地,一个从原点 出发,指向该点的箭头 。
例如,向量 \(\mathbf{x} = \begin{bmatrix} 2 \\ 1 \end{bmatrix}\) 在二维空间中,代表从 \((0,0)\) 指向 \((2,1)\) 的箭头。
向量的几何表示
一个二维坐标系,其中一个从原点(0,0)指向点(2,1)的蓝色箭头代表向量x。
x₁
x₂
x =
(0,0)
行向量 vs. 列向量
默认情况下,我们通常将向量视为列向量 (如前页所示)。
通过转置 (Transpose) 操作(记为 \(T\) ),我们可以将其变为行向量 。
\[ \large{\mathbf{x} = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix} \quad \xrightarrow{\text{Transpose}} \quad \mathbf{x}^T = \begin{bmatrix} x_1, x_2, \dots, x_n \end{bmatrix}} \]
这个看似简单的区分在矩阵运算中至关重要,它决定了向量之间如何相乘。
在 Python 中创建向量
接下来,我们将在 Python 中使用 NumPy
库来创建和操作向量。NumPy
是 Python 科学计算的核心库。
我们将演示: 1. 如何创建一个基本的 NumPy 数组来表示向量。 2. 如何明确区分行向量和列向量的维度。 3. 如何执行转置操作。
在 Python 中创建向量
在Python中,一个向量就是一个NumPy数组。
import numpy as np
# 向量 x =
x = np.array([1 , 2 ])
print (f'向量 x: { x} ' )
print (f'向量 x 的维度: { x. shape} ' ) # (2,)
# 要明确创建一个列向量 (2x1 矩阵), 可以这样做:
x_col = np.array([[1 ], [2 ]])
print (f' \n 明确的列向量 x_col: \n { x_col} ' )
print (f'列向量的维度: { x_col. shape} ' ) # (2, 1)
# 转置操作
x_row = x_col.T
print (f' \n 转置后的行向量 x_row: \n { x_row} ' )
print (f'行向量的维度: { x_row. shape} ' ) # (1, 2)
向量 x: [1 2]
向量 x 的维度: (2,)
明确的列向量 x_col:
[[1]
[2]]
列向量的维度: (2, 1)
转置后的行向量 x_row:
[[1 2]]
行向量的维度: (1, 2)
向量加法:合并两种效应
假设一个投资组合的收益由两部分构成: 1. 市场整体变动带来的收益: \(\mathbf{r}_{\text{market}} = \begin{bmatrix} 0.02 \\ -0.01 \end{bmatrix}\) 2. 公司特有事件带来的收益: \(\mathbf{r}_{\text{firm}} = \begin{bmatrix} 0.005 \\ 0.015 \end{bmatrix}\)
总收益就是这两个向量的和,代表了两种效应的叠加。
向量加法的代数法则:逐元素相加
向量加法非常直观:将两个向量对应的元素相加。前提是两个向量的维度必须相同 。
\[ \large{\mathbf{x} + \mathbf{y} = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix} + \begin{bmatrix} y_1 \\ y_2 \\ \vdots \\ y_n \end{bmatrix} = \begin{bmatrix} x_1 + y_1 \\ x_2 + y_2 \\ \vdots \\ x_n + y_n \end{bmatrix}} \]
例如: \[ \large{\begin{bmatrix} 2 \\ 1 \end{bmatrix} + \begin{bmatrix} 0.5 \\ 1.5 \end{bmatrix} = \begin{bmatrix} 2 + 0.5 \\ 1 + 1.5 \end{bmatrix} = \begin{bmatrix} 2.5 \\ 2.5 \end{bmatrix}} \]
向量减法同理,也是逐元素相减。
向量加法的几何诠释:平行四边形法则
几何上,向量加法遵循“头尾相接”或“平行四边形”法则。将第二个向量的起点移动到第一个向量的终点,从原点到第二个向量终点的新箭头就是它们的和。
向量加法的几何表示
向量x和y通过平行四边形法则相加得到向量z。
x
y
x+y
向量加法在 Python 中的实现
NumPy
的设计使得向量运算和标量运算一样简单,使用 +
和 -
运算符即可。
# 定义两个向量
x = np.array([1.0 , 2.0 ])
y = np.array([0.5 , 1.5 ])
# 向量加法
z_add = x + y
print (f'x + y = { z_add} ' )
# 向量减法
z_sub = x - y
print (f'x - y = { z_sub} ' )
x + y = [1.5 3.5]
x - y = [0.5 0.5]
标量与向量的乘法:缩放向量
假设你决定将某个投资策略的风险敞口(由向量 \(\mathbf{x}\) 代表)加倍 。这在数学上如何表示?
这就是标量与向量的乘法:用一个标量 \(a\) 乘以一个向量 \(\mathbf{x}\) 。
\[ \large{a\mathbf{x} = a \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix} = \begin{bmatrix} ax_1 \\ ax_2 \\ \vdots \\ ax_n \end{bmatrix}} \]
它的作用是缩放 (scale) 向量的长度,而不改变其基本方向。
标量乘法的几何效果
如果 \(a > 1\) :向量被拉长 。
如果 \(0 < a < 1\) :向量被缩短 。
如果 \(a < 0\) :向量的方向反转 180度,并根据 \(|a|\) 的大小进行缩放。
标量乘法的几何效果
一个原始向量x,一个被2倍拉长的向量2x,以及一个方向相反且被-1倍缩短的向量-x。
x
2x
-x
标量乘法的 Python 实现
在 NumPy
中,标量与向量的乘法就像普通数字乘法一样,使用 *
运算符。
import numpy as np
# 原始向量
x = np.array([1.0 , 2.0 ])
# 标量
a1 = 2
a2 = - 1.5
# 标量乘法
x1 = a1 * x
print (f'Original x = { x} ' )
print (f' { a1} * x = { x1} ' )
x2 = a2 * x
print (f' { a2} * x = { x2} ' )
Original x = [1. 2.]
2 * x = [2. 4.]
-1.5 * x = [-1.5 -3. ]
线性组合:用基本向量构建一切
线性组合 (Linear Combination) 是线性代数中最核心的概念之一。它是将我们刚学过的两种运算——向量加法和标量乘法——结合起来。
给定一组向量 \(\{\mathbf{v}_1, \mathbf{v}_2, \dots, \mathbf{v}_k\}\) 和一组标量 \(\{c_1, c_2, \dots, c_k\}\) ,它们的线性组合是: \[ \large{\mathbf{z} = c_1\mathbf{v}_1 + c_2\mathbf{v}_2 + \dots + c_k\mathbf{v}_k} \] 金融应用 :一个投资组合的总回报,就是其持有的每项资产回报向量(\(\mathbf{v}_i\) )按其投资权重(\(c_i\) )进行的线性组合。
向量的点积:衡量“一致性”
点积 (Dot Product) ,也称内积 (Inner Product),是两个向量之间最重要的运算之一。它将两个维度相同 的向量相乘,得到一个标量 。
假设我们有两个向量: - 投资组合权重向量 \(\mathbf{w} = \begin{bmatrix} 0.6 \\ 0.3 \\ 0.1 \end{bmatrix}\) - 资产预期收益率向量 \(\mathbf{r} = \begin{bmatrix} 0.10 \\ 0.08 \\ 0.05 \end{bmatrix}\)
投资组合的总预期收益率 就是这两个向量的点积。
点积的几何意义:投影与角度
点积的真正威力在于它的几何意义。它与两个向量之间的夹角 \(\theta\) 密切相关: \[ \large{\mathbf{x}^T \mathbf{y} = \lVert\mathbf{x}\rVert \lVert\mathbf{y}\rVert \cos(\theta)} \] 这告诉我们: - 若 \(\mathbf{x}^T \mathbf{y} > 0\) (\(\cos\theta > 0\) ):向量方向大致相同 (夹角 \(< 90^\circ\) )。 - 若 \(\mathbf{x}^T \mathbf{y} = 0\) (\(\cos\theta = 0\) ):向量正交 (Orthogonal),即垂直 (夹角 \(= 90^\circ\) )。 - 若 \(\mathbf{x}^T \mathbf{y} < 0\) (\(\cos\theta < 0\) ):向量方向大致相反 (夹角 \(> 90^\circ\) )。
金融直觉 :如果两只股票的每日收益率向量点积为正,说明它们倾向于同向变动。
点积几何意义的可视化
点积衡量了一个向量在另一个向量方向上的投影长度。
点积的投影几何意义
向量y在向量x上的投影。点积的大小与这个投影的长度有关。
x
y
θ
y在x上的投影
(长度 = ||y|| cos(θ))
点积在 Python 中的实现
NumPy
提供了多种方式计算点积。在现代 Python (3.5+) 和 NumPy 中,推荐使用 @
运算符,因为它最清晰地表达了数学意图。
x = np.array([1 , 2 , 3 ])
y = np.array([- 1 , - 5 , 3 ])
# 方法 1: 使用 @ 运算符 (推荐)
dot_product_1 = x @ y
print (f'使用 @ 运算符: { dot_product_1} ' )
# 方法 2: 使用 np.dot() 函数
dot_product_2 = np.dot(x, y)
print (f'使用 np.dot(): { dot_product_2} ' )
# 方法 3: 逐元素相乘再求和 (展示了其定义)
dot_product_3 = np.sum (x * y)
print (f'逐元素相乘再求和: { dot_product_3} ' )
使用 @ 运算符: -2
使用 np.dot(): -2
逐元素相乘再求和: -2
向量范数:衡量向量的“大小”或“长度”
我们如何量化一个向量的“大小”?例如,一个代表投资组合每日收益波动的向量,我们如何衡量其整体波动幅度?
范数 (Norm) 就是一个衡量向量大小的函数,记作 \(\lVert\mathbf{x}\rVert\) 。它必须满足三个性质: 1. 正定性 :\(\lVert\mathbf{x}\rVert \ge 0\) ,且仅当 \(\mathbf{x} = \mathbf{0}\) 时等号成立。 2. 齐次性 :\(\lVert k\mathbf{x}\rVert = |k| \lVert\mathbf{x}\rVert\) 。 3. 三角不等式 :\(\lVert\mathbf{x} + \mathbf{y}\rVert \le \lVert\mathbf{x}\rVert + \lVert\mathbf{y}\rVert\) 。
L1 范数:曼哈顿距离
L1 范数 (或称 Manhattan Norm) 是向量中所有元素绝对值之和 。
\[ \large{\lVert\mathbf{x}\rVert_1 = \sum_{i=1}^n |x_i|} \]
直观理解 :想象在像曼哈顿这样的棋盘格城市中,从原点到一个点必须沿着街道走,L1范数就是你需要走过的总街区数。
例子: \(\mathbf{x} = \begin{bmatrix} 1 \\ -2 \end{bmatrix}\) \[ \large{\lVert\mathbf{x}\rVert_1 = |1| + |-2| = 1 + 2 = 3} \]
在机器学习中,L1范数常用于特征选择(Lasso回归),因为它倾向于产生稀疏解(许多权重为零)。
L2 范数:欧几里得距离
L2 范数 (或称 Euclidean Norm) 是我们最熟悉的“距离”概念。它是向量元素平方和的平方根 。
\[ \large{\lVert\mathbf{x}\rVert_2 = \sqrt{\sum_{i=1}^n x_i^2}} \] 几何意义 :它就是从原点到向量所指向的点的直线距离 。
例子: \(\mathbf{x} = \begin{bmatrix} 1 \\ -2 \end{bmatrix}\) \[ \large{\lVert\mathbf{x}\rVert_2 = \sqrt{1^2 + (-2)^2} = \sqrt{1 + 4} = \sqrt{5} \approx 2.236} \]
如果没有特别指明,通常所说的“范数”或“向量长度”都指L2范数。
L1 vs. L2 范数可视化
L1 和 L2 范数的差异可以通过“单位球”的形状直观地理解,即所有范数值为1的点的集合。
L1和L2范数的单位球
两个坐标系,左边显示L1范数的单位球(一个菱形),右边显示L2范数的单位球(一个圆形)。
L1 范数: ||x||₁ = 1
(菱形/Diamond)
L2 范数: ||x||₂ = 1
(圆形/Circle)
范数在 Python 中的计算
NumPy
的 linalg
模块可以方便地计算各种范数,通过 ord
参数指定范数的阶数。
x = np.array([1 , - 2 , 2 ])
# L1 范数 (ord=1)
l1_norm = np.linalg.norm(x, ord = 1 )
print (f'L1 Norm of x (|1|+|-2|+|2|): { l1_norm} ' )
# L2 范数 (ord=2 is default)
l2_norm = np.linalg.norm(x)
print (f'L2 Norm of x (sqrt(1²+2²+2²)): { l2_norm} ' )
L1 Norm of x (|1|+|-2|+|2|): 5.0
L2 Norm of x (sqrt(1²+2²+2²)): 3.0
单位向量:只关心方向
一个单位向量 (Unit Vector) 是一个长度(L2范数)为1的向量。它只保留了方向信息,而“抛弃”了大小信息。
如何将任意非零向量 \(\mathbf{x}\) 转换为单位向量 \(\hat{\mathbf{x}}\) ? 将其除以它自身的L2范数即可 。 \[ \large{\hat{\mathbf{x}} = \frac{\mathbf{x}}{\lVert\mathbf{x}\rVert_2}} \]
金融应用 :在构建风险因子模型时,我们有时需要将因子“标准化”,使其具有单位方差,这与单位向量的概念密切相关。
向量相似度:欧几里得距离
我们如何量化两个投资策略(表示为向量)的相似性?
方法一:欧几里得距离
计算两个向量终点之间的直线距离。这可以通过计算差向量的L2范数 来实现: \(d(\mathbf{x}, \mathbf{y}) = \lVert\mathbf{x} - \mathbf{y}\rVert_2\) 。 - 距离越小,向量越相似。 - 这个方法同时考虑了大小 和方向 。对于比较投资组合的绝对表现差异 可能很有用。
向量相似度:余弦相似度
方法二:余弦相似度 (Cosine Similarity)
这个方法只关心方向 ,不关心大小。它计算两个向量之间夹角的余弦值。
\[ \large{\cos(\theta) = \frac{\mathbf{x}^T \mathbf{y}}{\lVert\mathbf{x}\rVert_2 \lVert\mathbf{y}\rVert_2}} \] - 结果在 [-1, 1] 之间。 - 1 : 方向完全相同。 - 0 : 方向正交(无关)。 - -1 : 方向完全相反。
金融应用 :比较两只股票收益率序列的变动模式 时,余弦相似度比欧几里得距离更有用,因为它不受股票自身波动率大小的影响。
相似度计算可视化
下面的图表演示了这两种相似度度量的区别。
欧几里得距离 vs. 余弦相似度
两个场景对比:第一个场景两个向量方向相同但长度不同,第二个场景两个向量长度相似但方向不同。
方向一致,大小不同
x=
y=
余弦相似度 = 1.0
欧氏距离 = 1.41
方向垂直,大小相近
x=
y=[-1,2]
余弦相似度 = 0.0
欧氏距离 = 3.16
矩阵:二维数据表
矩阵 (Matrix) 是一个二维的数字数组,可以看作是向量的推广。我们用大写粗体字母表示矩阵,如 \(\mathbf{A}\) 。
一个 \(m \times n\) 的矩阵有 \(m\) 行和 \(n\) 列。 \[ \large{\mathbf{A} = \begin{bmatrix}
a_{11} & a_{12} & \dots & a_{1n} \\
a_{21} & a_{22} & \dots & a_{2n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{m1} & a_{m2} & \dots & a_{mn}
\end{bmatrix}} \] 金融应用 : - 一个 \(m \times n\) 矩阵可以表示 \(m\) 只股票过去 \(n\) 天的收益率数据。 - 一个 \(m \times m\) 的协方差矩阵 可以表示 \(m\) 只股票收益率之间的联动关系。
矩阵在 Python 中的表示
我们同样使用 NumPy
数组来表示矩阵,此时它是一个二维数组。
# 构造一个 2x3 的矩阵 (2 行, 3 列)
A = np.array([
[1 ,2 ,3 ],
[- 2 , 12 , 4 ]
])
print ('矩阵 A:' )
print (A)
# 获取矩阵的维度
print (f' \n 矩阵 A 的维度 (行, 列): { A. shape} ' )
矩阵 A:
[[ 1 2 3]
[-2 12 4]]
矩阵 A 的维度 (行, 列): (2, 3)
矩阵乘法:核心运算
矩阵乘法是线性代数中最常用也最复杂的运算之一。
规则 :要计算 \(\mathbf{C} = \mathbf{A}\mathbf{B}\) ,矩阵 \(\mathbf{A}\) 的列数 必须等于矩阵 \(\mathbf{B}\) 的行数 。
如果 \(\mathbf{A}\) 是 \(m \times p\) 矩阵,\(\mathbf{B}\) 是 \(p \times n\) 矩阵,则结果 \(\mathbf{C}\) 是一个 \(m \times n\) 矩阵。
计算 :结果矩阵 \(\mathbf{C}\) 中第 \(i\) 行第 \(j\) 列的元素 \((C)_{ij}\) ,是 \(\mathbf{A}\) 的第 \(i\) 行向量 与 \(\mathbf{B}\) 的第 \(j\) 列向量 的点积 。 \[ \large{(C)_{ij} = \sum_{k=1}^p a_{ik}b_{kj}} \]
矩阵乘法图解
计算 \(C_{11}\) :取 A 的第 1 行和 B 的第 1 列,做点积。
矩阵乘法可视化
展示了矩阵A的第一行和矩阵B的第一列如何相乘得到结果矩阵C的第一个元素。
A
(m × p)
a₁₁
a₁₂
a₂₁
a₂₂
×
B
(p × n)
b₁₁
b₁₂
b₂₁
b₂₂
=
C
(m × n)
C₁₁
C₁₁ = (a₁₁ × b₁₁) + (a₁₂ × b₂₁)
矩阵乘法示例
给定 \(\mathbf{A} \in \mathbb{R}^{2 \times 3}\) 和 \(\mathbf{B} \in \mathbb{R}^{3 \times 2}\) ,求 \(\mathbf{C} = \mathbf{AB}\) 。
\[ \large{\mathbf{A} = \begin{bmatrix} 1 & 0 & 2 \\ -2 & 12 & 4 \end{bmatrix}, \quad \mathbf{B} = \begin{bmatrix} 10 & -2 \\ 4 & 1 \\ 0 & 7 \end{bmatrix}} \]
\[ \large{C_{11} = (1 \cdot 10) + (0 \cdot 4) + (2 \cdot 0) = 10} \] \[ \large{C_{12} = (1 \cdot -2) + (0 \cdot 1) + (2 \cdot 7) = 12} \] \[ \large{C_{21} = (-2 \cdot 10) + (12 \cdot 4) + (4 \cdot 0) = 28} \] \[ \large{C_{22} = (-2 \cdot -2) + (12 \cdot 1) + (4 \cdot 7) = 4 + 12 + 28 = 44} \]
\[ \large{\mathbf{C} = \begin{bmatrix} 10 & 12 \\ 28 & 44 \end{bmatrix}} \]
矩阵乘法在 Python 中的实现
与向量点积一样,我们使用 @
运算符进行矩阵乘法。NumPy
会自动处理行与列的点积。
A = np.array([[1 ,2 ,3 ], [- 2 , 12 , 4 ]])
B = np.array([[10 , - 2 ],[1 ,2 ],[3 ,4 ]])
# 矩阵乘法
C = A @ B
print ('矩阵 A (2x3):' )
print (A)
print (' \n 矩阵 B (3x2):' )
print (B)
print (' \n 结果 C = A @ B (2x2):' )
print (C)
矩阵 A (2x3):
[[ 1 2 3]
[-2 12 4]]
矩阵 B (3x2):
[[10 -2]
[ 1 2]
[ 3 4]]
结果 C = A @ B (2x2):
[[21 14]
[ 4 44]]
矩阵与向量的乘法
矩阵与向量的乘法是矩阵乘法的特例。我们可以将一个 \(p\) 维列向量看作一个 \(p \times 1\) 的矩阵。
如果 \(\mathbf{A}\) 是 \(m \times p\) 矩阵,\(\mathbf{x}\) 是 \(p\) 维列向量,则结果 \(\mathbf{y} = \mathbf{Ax}\) 是一个 \(m\) 维列向量。
重要直觉 :矩阵-向量乘法 \(\mathbf{Ax}\) 是将输入向量 \(\mathbf{x}\) 通过矩阵 \(\mathbf{A}\) 所描述的线性变换 ,映射到输出向量 \(\mathbf{y}\) 。
矩阵与标量的乘法
这与向量和标量的乘法类似:将矩阵中的每一个元素 都与该标量相乘。
例如: \(a=2, \mathbf{B} = \begin{bmatrix} 10 & -2 \\ 4 & 1 \\ 0 & 7 \end{bmatrix}\) \[ \large{a\mathbf{B} = 2 \begin{bmatrix} 10 & -2 \\ 4 & 1 \\ 0 & 7 \end{bmatrix} = \begin{bmatrix} 20 & -4 \\ 8 & 2 \\ 0 & 14 \end{bmatrix}} \]
a = 2
B = np.array([[10 , - 2 ],[1 ,2 ],[3 ,4 ]])
aB = a * B
print (aB)
矩阵的逆:线性代数中的“除法”
对于一个标量 \(a \neq 0\) ,它的逆是 \(a^{-1}\) ,满足 \(a \cdot a^{-1} = 1\) 。 矩阵的逆(Inverse)是类似的概念。
定义 :对于一个方阵 (square matrix) \(\mathbf{A}\) (即 \(n \times n\) 矩阵),如果存在另一个 \(n \times n\) 矩阵 \(\mathbf{B}\) 使得 \(\mathbf{A}\mathbf{B} = \mathbf{B}\mathbf{A} = \mathbf{I}\) ,则称 \(\mathbf{A}\) 是可逆的 (invertible) ,并记 \(\mathbf{B} = \mathbf{A}^{-1}\) 。
\(\mathbf{I}\) 是 单位矩阵 (Identity Matrix) ,一个主对角线为1,其余为0的方阵。它在线性代数中扮演着数字“1”的角色。
单位矩阵 (Identity Matrix)
单位矩阵 \(\mathbf{I}\) 在矩阵乘法中的作用,就像数字 1 在普通乘法中的作用。任何矩阵乘以单位矩阵,都等于其自身。 \[ \large{\mathbf{AI} = \mathbf{IA} = \mathbf{A}} \] \[ \large{\mathbf{I}_3 = \begin{bmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1
\end{bmatrix}} \]
为何矩阵求逆很重要?
矩阵求逆的核心应用是求解线性方程组 。
考虑一个简单的线性方程组: \[ \large{\mathbf{Ax} = \mathbf{b}} \] 这里,\(\mathbf{A}\) 是系数矩阵,\(\mathbf{x}\) 是未知变量向量,\(\mathbf{b}\) 是常数向量。
如果我们知道 \(\mathbf{A}^{-1}\) ,我们可以两边左乘 \(\mathbf{A}^{-1}\) : \[ \large{\mathbf{A}^{-1}\mathbf{A}\mathbf{x} = \mathbf{A}^{-1}\mathbf{b}} \] \[ \large{\mathbf{I}\mathbf{x} = \mathbf{A}^{-1}\mathbf{b}} \] \[ \large{\mathbf{x} = \mathbf{A}^{-1}\mathbf{b}} \] 我们就直接解出了 \(\mathbf{x}\) !
金融应用 :在投资组合优化中,求解最优权重通常归结为求解一个大型线性方程组。
求解 2x2 矩阵的逆:一个例子
我们用一个例子来展示如何求解。求矩阵 \(\mathbf{A}\) 的逆 \(\mathbf{A}^{-1}\) 。 \[ \large{\mathbf{A} = \begin{bmatrix} 4 & 7 \\ 2 & 6 \end{bmatrix}} \] 我们设所求的逆矩阵为: \[ \large{\mathbf{A}^{-1} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}} \] 我们的目标是求解 \(a, b, c, d\) 。
求解 2x2 矩阵的逆:建立方程
根据定义 \(\mathbf{A}\mathbf{A}^{-1} = \mathbf{I}\) : \[ \large{\begin{bmatrix} 4 & 7 \\ 2 & 6 \end{bmatrix} \begin{bmatrix} a & b \\ c & d \end{bmatrix} = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}} \] 通过矩阵乘法,我们得到: \[ \large{\begin{bmatrix} 4a + 7c & 4b + 7d \\ 2a + 6c & 2b + 6d \end{bmatrix} = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}} \] 这给了我们两组独立的 \(2 \times 2\) 线性方程组。
求解 2x2 矩阵的逆:求解方程组
第一组 (求解 a, c): 1. \(4a + 7c = 1\) 2. \(2a + 6c = 0 \implies a = -3c\)
将 (2) 代入 (1): \(4(-3c) + 7c = 1 \implies -12c + 7c = 1 \implies -5c = 1 \implies c = -0.2\) 代回 (2): \(a = -3(-0.2) = 0.6\)
第二组 (求解 b, d): 3. \(4b + 7d = 0 \implies b = -7d/4\) 4. \(2b + 6d = 1\)
将 (3) 代入 (4): \(2(-7d/4) + 6d = 1 \implies -3.5d + 6d = 1 \implies 2.5d = 1 \implies d = 0.4\) 代回 (3): \(b = -7(0.4)/4 = -0.7\)
求解 2x2 矩阵的逆:最终结果
我们解出了 \(a=0.6, b=-0.7, c=-0.2, d=0.4\) 。 所以,逆矩阵为: \[ \large{\mathbf{A}^{-1} = \begin{bmatrix} 0.6 & -0.7 \\ -0.2 & 0.4 \end{bmatrix}} \]
验证 : \[ \large{\mathbf{A}\mathbf{A}^{-1} = \begin{bmatrix} 4 & 7 \\ 2 & 6 \end{bmatrix} \begin{bmatrix} 0.6 & -0.7 \\ -0.2 & 0.4 \end{bmatrix} = \begin{bmatrix} 2.4-1.4 & -2.8+2.8 \\ 1.2-1.2 & -1.4+2.4 \end{bmatrix} = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}} = \mathbf{I} \] 验证通过!
矩阵求逆的 Python 实现
在实际应用中,我们从不手动求逆。我们让计算机来做,这更快也更不容易出错。
A = np.array([[1 ,2 ],[3 ,4 ]])
# 使用 np.linalg.inv() 函数求逆
try :
A_inv = np.linalg.inv(A)
print ('矩阵 A:' )
print (A)
print (' \n 矩阵 A 的逆 A_inv:' )
print (np.round (A_inv, decimals= 2 ))
# 验证 A @ A_inv 是否为单位矩阵
I = A @ A_inv
print (' \n 验证 A @ A_inv (结果应接近单位矩阵):' )
# np.round() 用于处理微小的浮点数误差
print (np.round (I, decimals= 5 ))
except np.linalg.LinAlgError:
print ("矩阵 A 是奇异矩阵 (singular), 不可逆。" )
矩阵 A:
[[1 2]
[3 4]]
矩阵 A 的逆 A_inv:
[[-2. 1. ]
[ 1.5 -0.5]]
验证 A @ A_inv (结果应接近单位矩阵):
[[1. 0.]
[0. 1.]]
线性代数部分练习与应用
现在,让我们通过解决课本上的练习题来巩固我们学到的知识。这不仅是计算,更是将抽象概念应用到具体数字上的过程。
习题 2.5.1 向量运算 给定向量: \(\mathbf{x} = \begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix}, \quad \mathbf{y} = \begin{bmatrix} -0.5 \\ 2 \\ 0 \end{bmatrix}\)
请计算: 1. \(-2\mathbf{x}\) 2. \(\mathbf{x}+\mathbf{y}\) 3. \(\mathbf{x} \cdot \mathbf{y}\) (点积) 4. \(\mathbf{x}^T\mathbf{y}\)
练习 2.5.1 Python 求解
x = np.array([1.0 , 2.0 ,3.0 ])
y = np.array([- 0.5 , 2 , 0 ])
# 1. -2x
neg_2x = - 2 * x
print (f'1. -2x = { neg_2x} ' )
# 2. x + y
x_plus_y = x + y
print (f'2. x + y = { x_plus_y} ' )
# 3. x . y (点积)
dot_product = x @ y
print (f'3. x . y (dot product) = { dot_product} ' )
# 4. x^T y
# 在 NumPy 中, x.T @ y 对于一维数组和 x @ y 结果相同
# 但为了概念清晰,我们明确其数学含义
transpose_dot = x.T @ y
print (f'4. x^T y = { transpose_dot} ' )
print (' \n 结论: 向量的点积 (x.y) 和 x^T y 在计算上是等价的。' )
1. -2x = [-2. -4. -6.]
2. x + y = [0.5 4. 3. ]
3. x . y (dot product) = 3.5
4. x^T y = 3.5
结论: 向量的点积 (x.y) 和 x^T y 在计算上是等价的。
练习 2.5.2 矩阵运算
给定矩阵 \(\mathbf{A} = \begin{pmatrix} 0.3 & -2.9 & -10 \\ -3 & 1 & 0.5 \end{pmatrix}\) 和上题中的向量 \(\mathbf{x} = \begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix}\) 。
请回答和计算: 1. 该矩阵的维度是什么? 2. 计算 \(\mathbf{Ax}\) 。 3. 求 \(\mathbf{A}^T\) 。
练习 2.5.2 Python 求解
import numpy as np
# A(2x3)
A = np.array([
[0.3 , - 2.9 , - 10 ],
[- 3 , 1 , 0.5 ]
])
# x must have 3 elements to match A's columns
x = np.array([1.0 , 2.0 , 3.0 ])
# 1. 矩阵的维度
rows, cols = A.shape
print (f'1. 矩阵 A 的维度是: { rows} 行, { cols} 列' )
# 2. 计算 Ax
# A(2x3) @ x(3,) -> 结果是 (2,) 向量
Ax = A @ x
print (f' \n 2. Ax = { Ax} ' )
print (f' 计算过程 (第一行): (0.3*1) + (-2.9*2) + (-10*3) = { 0.3 * 1 - 2.9 * 2 - 10 * 3 } ' )
print (f' 计算过程 (第二行): (-3*1) + (1*2) + (0.5*3) = { - 3 * 1 + 1 * 2 + 0.5 * 3 } ' )
# 3. 求 A^T
A_T = A.T
print (f' \n 3. A 的转置 A^T 是: \n { A_T} ' )
print (f' A^T 的维度是: { A_T. shape} ' )
1. 矩阵 A 的维度是: 2 行, 3 列
2. Ax = [-35.5 0.5]
计算过程 (第一行): (0.3*1) + (-2.9*2) + (-10*3) = -35.5
计算过程 (第二行): (-3*1) + (1*2) + (0.5*3) = 0.5
3. A 的转置 A^T 是:
[[ 0.3 -3. ]
[ -2.9 1. ]
[-10. 0.5]]
A^T 的维度是: (3, 2)
微积分:捕捉金融世界的动态变化
金融市场瞬息万变。资产价格、利率、风险,所有这些都不是静止的。我们如何描述和分析这些变化 ?
微积分 ,特别是微分 ,是研究“变化率”的数学语言。
导数 (Derivative) :衡量当一个变量发生微小变化时,另一个函数变量会如何响应。
梯度 (Gradient) :导数在多维空间中的推广,它指向函数增长最快 的方向。
这对于金融中的优化问题 ——例如,最大化收益或最小化风险——至关重要。
一维微分:函数的变化率
微分 的直观意义是函数在某一点的瞬时变化率 ,也就是该点切线的斜率 。
函数 \(f(x)\) 在 \(x_0\) 处的微分(或导数)记为 \(f'(x_0)\) 或 \(\frac{df}{dx}|_{x_0}\) 。它描述了当 \(x\) 在 \(x_0\) 附近发生一个极小的变动时,\(f(x)\) 相应的变化量。
金融应用 :期权定价中的 “Delta” 就是期权价格(函数)相对于标的资产价格(变量)的导数。它告诉我们股票价格每变动1美元,期权价格会变动多少。
常见函数的导数
以下是一些我们需要熟记的求导法则: 1. 常数 : \(f(x) = c \implies f'(x) = 0\) 2. 线性函数 : \(f(x) = ax \implies f'(x) = a\) 3. 幂函数 : \(f(x) = x^n \implies f'(x) = nx^{n-1}\) 4. 加法法则 : \((f+g)' = f' + g'\) 5. 乘法法则 : \((fg)' = f'g + fg'\) 6. 自然对数 : \(f(x) = \ln(x) \implies f'(x) = \frac{1}{x}\) 7. 指数函数 : \(f(x) = e^x \implies f'(x) = e^x\)
链式法则:求解复合函数的导数
当我们处理嵌套函数(复合函数)时,例如 \(f(g(x))\) ,我们需要使用链式法则 (Chain Rule) 。
\[ \large{\frac{d}{dx}f(g(x)) = f'(g(x)) \cdot g'(x)} \]
直观解释 :“外层函数的导数(保持内层不变)”乘以“内层函数的导数”。
例子 :求 \(h(x) = (x^2+1)^3\) 的导数。 - 外层函数 \(f(g) = g^3 \implies f'(g) = 3g^2\) - 内层函数 \(g(x) = x^2+1 \implies g'(x) = 2x\) - \(h'(x) = f'(g(x)) \cdot g'(x) = 3(x^2+1)^2 \cdot (2x) = 6x(x^2+1)^2\)
多维微分:梯度 (Gradient)
当函数有多个输入变量时,例如 \(f(x_1, x_2, \dots, x_n)\) ,我们如何描述它的变化?
我们引入偏导数 (Partial Derivative) \(\frac{\partial f}{\partial x_k}\) ,它表示当只有变量 \(x_k\) 发生变动 而其他变量保持不变时,函数 \(f\) 的变化率。
将所有偏导数收集到一个向量中,就得到了梯度 (Gradient) ,记为 \(\nabla f(\mathbf{x})\) 。 \[ \large{\nabla f(\mathbf{x}) = \begin{bmatrix} \frac{\partial f}{\partial x_1} \\ \frac{\partial f}{\partial x_2} \\ \vdots \\ \frac{\partial f}{\partial x_n} \end{bmatrix}} \]
梯度的几何意义:最陡峭的登山路径
梯度向量 \(\nabla f(\mathbf{x})\) 指向函数 \(f\) 在点 \(\mathbf{x}\) 处增长最快的方向。
梯度的几何意义
一个表示山丘的等高线图。在某一点上,梯度向量指向最陡峭的上坡方向,负梯度指向最陡峭的下坡方向。
当前位置 (x)
∇f(x) (最陡峭上坡)
-∇f(x) (最陡峭下坡)
梯度下降法:机器学习的引擎
这个“最陡峭下坡”的概念是机器学习模型训练的核心算法——梯度下降 (Gradient Descent) ——的基础。
为了找到一个函数(例如,模型的“损失函数”)的最小值,我们从一个随机点开始,然后反复地沿着负梯度 方向小步移动。
\[ \large{\mathbf{x}_{\text{new}} = \mathbf{x}_{\text{old}} - \eta \nabla f(\mathbf{x}_{\text{old}})} \]
\(\eta\) (eta) 是学习率 (learning rate) ,控制我们每一步走多远。
这个简单的迭代过程,是训练从线性回归到深度神经网络等众多模型的基础。
寻找局部最大/最小值
一个可微函数的局部最大值或最小值(统称为极值点)在哪里出现?
一维情况 :在 \(f'(x_0) = 0\) 的点。即函数切线斜率为0(水平)的地方。
多维情况 :在 \(\nabla f(\mathbf{x}_0) = \mathbf{0}\) 的点。即梯度为零向量,在任何方向上函数值的瞬时变化率都为0。
这个条件是函数取得极值的必要条件 (Necessary Condition) ,但不是充分条件 (Sufficient Condition) 。一个梯度为0的点也可能是鞍点。
寻找极值的例子
我们来看一个函数 \(f(x) = x^3 - 6x^2 + 5x + 12\) 。
求导 :\(f'(x) = 3x^2 - 12x + 5\)
令导数为0 :\(3x^2 - 12x + 5 = 0\)
求解 :使用求根公式 \(x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}\) \[ \large{x = \frac{12 \pm \sqrt{(-12)^2 - 4(3)(5)}}{2(3)} = \frac{12 \pm \sqrt{144 - 60}}{6} = \frac{12 \pm \sqrt{84}}{6}} \] 所以极值点大约在 \(x \approx 0.47\) 和 \(x \approx 3.53\) 。
极值点可视化
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return x** 3 - 6 * x** 2 + 5 * x + 12
# 求解导数为0的点
# f'(x) = 3x^2 - 12x + 5 = 0
roots = np.roots([3 , - 12 , 5 ])
x_max, x_min = np.sort(roots)
# 绘图
x_vals = np.linspace(- 1 , 5 , 400 )
y_vals = f(x_vals)
plt.figure(figsize= (10 , 6 ))
plt.plot(x_vals, y_vals, label= '$f(x) = x^3 - 6x^2 + 5x + 12$' , color= '#0A369D' )
plt.plot(x_max, f(x_max), 'o' , color= '#F79F79' , markersize= 8 , label= f'局部最大值 at x= { x_max:.2f} ' )
plt.plot(x_min, f(x_min), 'o' , color= '#228B22' , markersize= 8 , label= f'局部最小值 at x= { x_min:.2f} ' )
plt.title('函数及其局部极值点' , fontsize= 16 )
plt.xlabel('x' , fontsize= 12 )
plt.ylabel('f(x)' , fontsize= 12 )
plt.axhline(0 , color= 'gray' , linestyle= '--' , linewidth= 0.5 )
plt.grid(True , linestyle= '--' , alpha= 0.6 )
plt.legend(fontsize= 12 )
plt.show()
练习 2.5.2.1 微积分计算
给定函数 \(f(x_1, x_2) = -5x_1^3 - x_2^2 + x_1x_2 - 5\) 。
当 \(x_1=5, x_2=-1\) 时,求: 1. \(\frac{\partial f(x_1, x_2)}{\partial x_1}\) 2. \(\nabla f(x_1, x_2)\)
练习 2.5.2.1 手动求解
1. 求关于 \(x_1\) 的偏导数 把 \(x_2\) 看作常数,对 \(x_1\) 求导: \[ \large{\frac{\partial f}{\partial x_1} = \frac{\partial}{\partial x_1}(-5x_1^3 - x_2^2 + x_1x_2 - 5)} \] \[ \large{= -5(3x_1^2) - 0 + (1 \cdot x_2) - 0 = -15x_1^2 + x_2} \] 代入 \(x_1=5, x_2=-1\) : \[ \large{\frac{\partial f}{\partial x_1} \bigg|_{(5, -1)} = -15(5^2) + (-1) = -15(25) - 1 = -375 - 1 = -376} \]
练习 2.5.2.1 手动求解 (续)
2. 求梯度 首先求关于 \(x_2\) 的偏导数 (把 \(x_1\) 看作常数): \[ \large{\frac{\partial f}{\partial x_2} = \frac{\partial}{\partial x_2}(-5x_1^3 - x_2^2 + x_1x_2 - 5)} \] \[ \large{= 0 - 2x_2 + (x_1 \cdot 1) - 0 = -2x_2 + x_1} \] 梯度向量是: \[ \large{\nabla f(x_1, x_2) = \begin{bmatrix} \frac{\partial f}{\partial x_1} \\ \frac{\partial f}{\partial x_2} \end{bmatrix} = \begin{bmatrix} -15x_1^2 + x_2 \\ -2x_2 + x_1 \end{bmatrix}} \] 代入 \(x_1=5, x_2=-1\) : \[ \large{\nabla f(5, -1) = \begin{bmatrix} -15(5^2) + (-1) \\ -2(-1) + 5 \end{bmatrix} = \begin{bmatrix} -376 \\ 2 + 5 \end{bmatrix} = \begin{bmatrix} -376 \\ 7 \end{bmatrix}} \]
练习 2.5.2.1 Python 求解 (使用 SymPy)
我们可以使用符号计算库 SymPy
来验证我们的结果。
import sympy as sp
# 定义符号变量
x1, x2 = sp.symbols('x1 x2' )
# 定义函数
f = - 5 * x1** 3 - x2** 2 + x1* x2 - 5
# 1. 求关于 x1 的偏导数
df_dx1 = sp.diff(f, x1)
print (f'df/dx1 = { df_dx1} ' )
# 代入数值
val_df_dx1 = df_dx1.subs({x1: 5 , x2: - 1 })
print (f'在 (5, -1) 处 df/dx1 的值为: { val_df_dx1} ' )
# 2. 求梯度
grad_f = [sp.diff(f, var) for var in (x1, x2)]
print (f' \n 梯度向量 ∇f = { grad_f} ' )
# 代入数值
val_grad_f = [expr.subs({x1: 5 , x2: - 1 }) for expr in grad_f]
print (f'在 (5, -1) 处 ∇f 的值为: { val_grad_f} ' )
df/dx1 = -15*x1**2 + x2
在 (5, -1) 处 df/dx1 的值为: -376
梯度向量 ∇f = [-15*x1**2 + x2, x1 - 2*x2]
在 (5, -1) 处 ∇f 的值为: [-376, 7]
统计学:在不确定性中寻找规律
金融市场充满了不确定性 和随机性 。明天的股价是多少?下个季度的GDP增长率如何?我们无法精确预测。
统计学 是科学地处理不确定性的工具。它帮助我们: - 描述数据 :用均值、方差等指标总结数据的特征。 - 推断关系 :用相关性、回归等方法发现变量间的联系。 - 量化风险 :概率论是衡量和管理金融风险的基础。
随机变量:不确定的数值结果
随机变量 (Random Variable) 是一个其数值取决于随机事件结果的变量。我们通常用大写字母表示,如 \(X\) 。
离散随机变量 :只能取有限个或可数个值。
例子:掷骰子的点数 (1, 2, 3, 4, 5, 6);一天内某支股票上涨的天数。
连续随机变量 :可以取某一区间内的任何值。
例子:明天S&P 500指数的收益率;一家公司未来的盈利。
随机变量的一个具体实现值(观测值)用小写字母表示,如 \(x_i\) 。
期望:随机变量的“平均”取值
期望 (Expectation) 或期望值 \(E(X)\) ,是随机变量 \(X\) 所有可能取值按其概率加权的平均值。它是对随机变量中心趋势的度量。
离散型 :\(E(X) = \sum_{k} x_k p(x_k)\)
例子:掷一个公平骰子,期望值是 \(1\cdot\frac{1}{6} + 2\cdot\frac{1}{6} + \dots + 6\cdot\frac{1}{6} = 3.5\) 。
连续型 :\(E(X) = \int_{-\infty}^{\infty} x f(x) dx\) ,其中 \(f(x)\) 是概率密度函数。
在金融中,预期收益率 (Expected Return) 就是资产未来收益率这个随机变量的期望值。
样本均值 vs. 期望
在现实世界中,我们通常不知道真实的概率分布,所以无法计算理论上的期望 \(E(X)\) 。
我们能做的是从总体中抽取一个样本 (sample) \(\{x_1, x_2, \dots, x_n\}\) ,然后计算样本均值 (sample mean) \(\bar{x}\) : \[ \large{\bar{x} = \frac{1}{n}\sum_{i=1}^n x_i} \] 根据大数定律 ,当样本量 \(n\) 足够大时,样本均值 \(\bar{x}\) 会非常接近总体的期望 \(E(X)\) 。
方差:衡量风险与波动
方差 (Variance) ,记为 \(\text{Var}(X)\) 或 \(\sigma^2\) ,衡量了随机变量的取值与其期望值之间的偏离程度。方差越大,数据点越分散,不确定性(风险)越高。
理论方差 (概率论中) : \[ \large{\text{Var}(X) = E[(X - E(X))^2] = E(X^2) - [E(X)]^2} \]
样本方差 (统计学中) : \[ \large{s^2 = \frac{1}{n-1}\sum_{i=1}^n (x_i - \bar{x})^2} \] 注意分母是 \(n-1\) ,这是为了对总体方差进行无偏估计 。
标准差 (Standard Deviation) \(\sigma = \sqrt{\text{Var}(X)}\) ,是方差的平方根,其单位与原始数据相同,更易于解释。
偏差 (Bias) 与 方差 (Variance)
在评估一个统计模型时,我们关心两种主要的误差来源:偏差 和方差 。
偏差 (Bias) :模型的平均预测 与真实值 之间的差距。高偏差意味着模型过于简单,未能捕捉数据规律(欠拟合 )。
方差 (Variance) :模型在不同训练数据集上预测结果的变动程度 。高方差意味着模型对训练数据过于敏感,连噪声都学进去了(过拟合 )。
偏差-方差的权衡
一个好的模型需要在偏差和方差之间取得平衡。
偏差-方差权衡
三个靶子展示了理想模型、欠拟合模型和过拟合模型的射击结果。
低偏差, 低方差
(理想模型)
高偏差, 低方差
(欠拟合)
低偏差, 高方差
(过拟合)
相关性:衡量线性关系
相关性 (Correlation) 是量化两个变量之间变动一致性程度的指标。
正相关 :一个变量增加时,另一个变量也倾向于增加。
负相关 :一个变量增加时,另一个变量倾向于减少。
不相关 :两个变量之间没有明显的线性关系。
重要警告:相关性 \(\neq\) 因果性! (Correlation does not imply causation!) 一个经典的例子:夏天的冰淇淋销量和溺水人数高度正相关,但这不意味着吃冰淇淋会导致溺水。背后隐藏的变量是“天气炎热”。
相关性可视化
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42 )
x = np.random.rand(50 )
# Positive Correlation
y1 = x + np.random.normal(0 , 0.1 , 50 )
# No Correlation
y2 = np.random.rand(50 )
# Negative Correlation
y3 = - x + np.random.normal(0 , 0.1 , 50 )
fig, (ax1, ax2, ax3) = plt.subplots(1 , 3 , figsize= (15 , 5 ), sharex= True , sharey= True )
ax1.scatter(x, y1, alpha= 0.7 , c= '#0A369D' )
corr1 = np.corrcoef(x, y1)[0 , 1 ]
ax1.set_title(f'正相关 (ρ ≈ { corr1:.2f} )' , fontsize= 16 )
ax2.scatter(x, y2, alpha= 0.7 , c= '#888888' )
corr2 = np.corrcoef(x, y2)[0 , 1 ]
ax2.set_title(f'不相关 (ρ ≈ { corr2:.2f} )' , fontsize= 16 )
ax3.scatter(x, y3, alpha= 0.7 , c= '#DC143C' )
corr3 = np.corrcoef(x, y3)[0 , 1 ]
ax3.set_title(f'负相关 (ρ ≈ { corr3:.2f} )' , fontsize= 16 )
for ax in [ax1, ax2, ax3]:
ax.set_xlabel('X' )
ax.grid(True , linestyle= '--' , alpha= 0.6 )
ax1.set_ylabel('Y' )
plt.tight_layout()
plt.show()
Pearson 相关系数
Pearson 相关系数 \(\rho\) 是衡量两个连续变量 之间线性关系 强度的最常用指标。
\[ \large{\rho_{X,Y} = \frac{\sum_{i=1}^n (x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum_{i=1}^n (x_i - \bar{x})^2} \sqrt{\sum_{i=1}^n (y_i - \bar{y})^2}} = \frac{\text{Cov}(X,Y)}{\sigma_X \sigma_Y}} \] - \(\rho\) 的取值范围是 \([-1, 1]\) 。 - \(|\rho|\) 越接近 1,线性关系越强。 - \(\rho=1\) :完全正相关。 - \(\rho=-1\) :完全负相关。 - \(\rho \approx 0\) :没有线性关系。
回归分析中的重要指标
在用模型(例如线性回归)进行预测时,我们需要一些指标来评估模型的好坏。这些指标都围绕着残差 (Residual) ——真实值与预测值之间的差异——来构建。
残差平方和 (RSS) : 衡量模型整体误差的大小。
总离差平方和 (TSS) : 衡量数据本身的总波动。
判定系数 (R²) : 衡量模型解释了数据总波动的百分比。
判定系数 R²
判定系数 (Coefficient of Determination, R²) 是衡量模型拟合优度的核心指标。它表示因变量 \(y\) 的总变异中,可以被自变量 \(x\) 解释的比例 。
\[ \large{R^2 = 1 - \frac{\text{RSS}}{\text{TSS}} = \frac{\text{TSS} - \text{RSS}}{\text{TSS}}} \] - \(R^2\) 的取值范围通常在 [0, 1] 之间。 - \(R^2 = 0.9\) 意味着模型解释了数据总方差的 90%。 - \(R^2\) 越高,模型的解释能力越强。 - 优点 :它是一个相对值,克服了 MSE 没有上界的缺点,使得不同模型和数据集之间的比较成为可能。
统计学部分练习:真实金融数据分析
理论知识需要通过实践来巩固。现在我们不再使用书上的小数据集,而是用真实的金融数据来计算这些统计量。
任务:分析苹果公司 (AAPL) 和 S&P 500 指数 (SPY) 在 2023 年的日收益率关系。
我们将使用 yfinance
库获取数据,并计算: 1. 各自的平均日收益率和标准差。 2. 它们之间的 Pearson 相关系数。
获取并处理金融数据
import yfinance as yf
import pandas as pd
import numpy as np
# 下载 AAPL 和 SPY 在2023年的每日调整后收盘价
try :
data = yf.download(['AAPL' , 'SPY' ], start= '2023-01-01' , end= '2024-01-01' )['Adj Close' ]
if data.empty:
raise ValueError ("No data downloaded." )
# 计算对数日收益率 (更适合金融时间序列分析)
returns = np.log(data / data.shift(1 )).dropna()
print ("数据下载和处理成功:" )
print (returns.head())
print (f"列名: { returns. columns. tolist()} " )
print (f"数据形状: { returns. shape} " )
except Exception as e:
print (f"数据下载失败,将使用模拟数据。错误: { e} " )
# 创建模拟数据以保证可运行性
dates = pd.date_range(start= '2023-01-01' , end= '2023-12-31' , freq= 'B' )
spy_returns = np.random.normal(0.0005 , 0.01 , len (dates))
aapl_returns = 0.7 * spy_returns + np.random.normal(0 , 0.008 , len (dates))
returns = pd.DataFrame({'AAPL' : aapl_returns, 'SPY' : spy_returns}, index= dates)
print ("已生成模拟数据:" )
print (returns.head())
print (f"列名: { returns. columns. tolist()} " )
print (f"数据形状: { returns. shape} " )
数据下载失败,将使用模拟数据。错误: 'Adj Close'
已生成模拟数据:
AAPL SPY
2023-01-02 -0.015130 -0.002147
2023-01-03 0.018947 0.027702
2023-01-04 0.007802 0.006757
2023-01-05 -0.005912 -0.008072
2023-01-06 -0.023686 -0.010209
列名: ['AAPL', 'SPY']
数据形状: (260, 2)
练习 2.5.3 统计量计算
我们以 AAPL 为 \(y\) ,SPY 为 \(x\) 。
# 检查可用的列名
print (f"当前数据框的列名: { returns. columns. tolist()} " )
# 确保我们有正确的列名
if 'AAPL' in returns.columns and 'SPY' in returns.columns:
# 1. 平均值和标准差
mean_aapl = returns['AAPL' ].mean()
std_aapl = returns['AAPL' ].std()
mean_spy = returns['SPY' ].mean()
std_spy = returns['SPY' ].std()
print (f'AAPL 平均日收益率: { mean_aapl:.5f} (年化 ~ { mean_aapl* 252 :.2%} )' )
print (f'AAPL 日收益率标准差 (风险): { std_aapl:.5f} (年化 ~ { std_aapl* np. sqrt(252 ):.2%} )' )
print (f'SPY 平均日收益率: { mean_spy:.5f} (年化 ~ { mean_spy* 252 :.2%} )' )
print (f'SPY 日收益率标准差 (风险): { std_spy:.5f} (年化 ~ { std_spy* np. sqrt(252 ):.2%} )' )
# 2. 相关系数
correlation = returns['AAPL' ].corr(returns['SPY' ])
print (f' \n AAPL 与 SPY 日收益率的相关系数: { correlation:.4f} ' )
else :
print (f"错误:数据框中缺少必要的列。当前列名: { returns. columns. tolist()} " )
print ("请检查数据下载是否成功,或者确认列名是否正确。" )
当前数据框的列名: ['AAPL', 'SPY']
AAPL 平均日收益率: 0.00028 (年化 ~6.94%)
AAPL 日收益率标准差 (风险): 0.01104 (年化 ~17.53%)
SPY 平均日收益率: 0.00124 (年化 ~31.37%)
SPY 日收益率标准差 (风险): 0.00996 (年化 ~15.81%)
AAPL 与 SPY 日收益率的相关系数: 0.6837
结果解读与可视化
相关系数通常在 0.7 左右,这是一个相当强的正相关关系。这符合我们的经济直觉:作为市场的重要组成部分,苹果公司的股价走势与大盘指数高度相关。
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize= (8 , 6 ))
sns.regplot(data= returns, x= 'SPY' , y= 'AAPL' ,
scatter_kws= {'alpha' :0.5 , 'color' : '#0A369D' },
line_kws= {'color' : '#DC143C' })
plt.title(f'AAPL vs. SPY Daily Returns (2023) \n Correlation = { correlation:.2f} ' , fontsize= 16 )
plt.xlabel('SPY Daily Return' , fontsize= 12 )
plt.ylabel('AAPL Daily Return' , fontsize= 12 )
plt.grid(True , linestyle= '--' , alpha= 0.6 )
plt.show()
章节总结:我们的数学工具箱
今天,我们重新审视了构建现代金融和量化分析的三大数学支柱:
线性代数 :提供了描述和操作多维金融数据的语言。
微积分 :让我们能够分析和优化动态变化的金融系统。
统计学 :使我们能在不确定性中量化规律、风险和关系。
数学工具箱总结
一个中心标题“数学工具箱”,分支出三个代表线性代数、微积分和统计学的图标。
金融量化分析的数学工具箱
线性代数
微积分
统计学
结束语
这些不是孤立的工具。在接下来的课程中,我们将看到它们如何协同工作,构建起强大的金融机器学习模型。
请务必花时间用Python复现今天的每一个例子。 这些基础越扎实,我们后面学习复杂模型时就会越轻松。
谢谢大家。
好的,同学们,我们今天的内容就到这里。我们快速但深入地回顾了线性代数、微积分和统计学。请务必记住,这些不是为了考试而记忆的公式,而是你们未来分析金融市场、构建交易策略的基石。课后请大家务必花时间用Python复现今天的每一个例子。这些基础越扎实,我们后面学习复杂模型时就会越轻松。谢谢大家。