机器学习-入门

【分解】矩阵LU分解(三):Cholesky分解

作者 : 老饼 发表日期 : 2023-02-05 04:55:08 更新日期 : 2024-12-23 17:23:58
本站原创文章,转载请说明来自《老饼讲解-机器学习》www.bbbdata.com



Cholesky矩阵分解是矩阵LU分解的一种,它将矩阵A分解为L*L^T的形式

本文介绍Cholesky分解的定义、分解的流程与公式推导,并展示Cholesky分解的具体代码实现

通过本文,可以快速了解Cholesky矩阵分解是什么,分解的算法流程以及如何用代码实现Cholesky分解





    01. 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列的计算公式为
 
   
 






      02. Cholesky矩阵分解-公式推导    

 




本节讲解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列  
 
 根据上式,即可得到:                                              
      
  
 将上式写成矩阵形式,则为:                                        
 







      03. Cholesky矩阵分解-代码实现    





本节展示如何用用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
代码运行结果如下:
 Cholesky分解代码运行结果 
从结果中可以看到,我们先用合成了A
然后用Cholesky分解A,就能分解出原始的L,说明程序是有效的






好了,以上就是矩阵LU分解中的Cholesky分解了~








 End 






联系老饼