本站原创文章,转载请说明来自《老饼讲解-机器学习》www.bbbdata.com
Cholesky矩阵分解是矩阵LU分解的一种,它将矩阵A分解为L*L^T的形式
本文介绍Cholesky分解的定义、分解的流程与公式推导,并展示Cholesky分解的具体代码实现
通过本文,可以快速了解Cholesky矩阵分解是什么,分解的算法流程以及如何用代码实现Cholesky分解
本节讲解Cholesky矩阵分解是什么,以及对矩阵进行Cholesky分解的流程
Cholesky分解的定义
Cholesky分解就是将正定对称矩阵分解成两个三角矩阵,如下:
A是正定对称矩阵,求一个下三角矩阵 L,使得
简单来说,就是将A分解成,其中:
,
Cholesky矩阵分解流程
Cholesky矩阵分解流程,就是L的求解流程
它对L进行逐列求解,即先求第1列,再求第2列,再求第3列....
其中,每列的求解分为两步:
1. 先求对角元素
2. 再求非对角元素
假设前i-1列已求出,按如下流程求第i列:
一、求解 L第列对角元素
的求解公式如下:
解说:即第i个对角元素为:根号(-L第i行前(i-1)个元素的平方和)
举例:
二、求解 L第i列所有元素
在求得后,第 列的求解公式如下:
解说:即L第i列为:(A的第i列- L前(i-1)列*各自第i行的元素)/
矩阵形式为:
✍️关于首列的计算公式
特别地,第1列的计算公式为
本节讲解Cholesky分解流程中的公式是如何推导出来的
Cholesky分解-对角元素的公式推导
对于L的对角元素,公式的推导过程如下:
Aii等于L的 i 行乘的 i 列
的 i 列就是L的第i行的转置
i之后的元素是0,所以只要累加到i即可
根据上式,即可得到
Cholesky分解-非角元素的公式推导
假设前(i-1)列已求出,且也已求得,
现求L第i列的所有元素,则有:
A的i列为 L乘以的 i 列
L与互为转置
A的i列为L每列乘以各自第i行元素后再相加
L的i行i列之后的元素为0,故不需i之后的列
独立抽出第i列
根据上式,即可得到:
将上式写成矩阵形式,则为:
本节展示如何用用python代码实现Cholesky分解
python代码实现Cholesky分解
按上文的Cholesky分解流程,使用python编写Cholesky分解的程序
具体代码如下:
# -*- coding: utf-8 -*-
"""
本代码用于展示如何实现Cholesky分解
本代码来自《老饼讲解-机器学习》www.bbbdata.com
"""
import numpy as np
# Cholesky分解函数
def CholeskyDecompose(A):
r,c = A.shape # 获取矩阵的行数、列数
L = np.zeros((r,r)) # 初始化L
L[0,0] = np.sqrt(A[0,0]) # 计算L11
L[:,0] = A[:,0]/L[0,0] # 计算L第1列的其余元素
for i in range(1,r): # 逐列计算
L[i,i] = np.sqrt(A[i,i]-sum(L[i,:i+1]*L[i,:i+1])) # 计算第i列的对角元素Lii
L[:,i] = (A[:,i]-L[:,:i]@L[i,:i].T)/L[i,i] # 计算第i列的非对角元素
return L # 返回结果
# 测试样例
if __name__ == "__main__":
# 生成要分解的A
np.random.seed(0) # 设置随机种子
rnd_mat = np.random.randint(0,10,(5,5)) # 生成一个随机矩阵
L_true = np.tril(rnd_mat,0) # 将上三角置0,即得到下三角矩阵
A = L_true@L_true.T # 将L*L^T组合成A
# Cholesky分解
L = CholeskyDecompose(A) # 调用函数对A进行Cholesky分解
print('\n----生成的L-----:\n',L_true) # 打印生成的L
print('\n----LL^T组合成的A-----:\n',A) # 打印由LL^T得到的A
print('\n----从A分解得到的L-------:\n',L) # 打印从A中分解得到的L
代码运行结果如下:
从结果中可以看到,我们先用合成了A
然后用Cholesky分解A,就能分解出原始的L,说明程序是有效的
好了,以上就是矩阵LU分解中的Cholesky分解了~
End