网站首页 > 博客文章 正文
器学习和数值编程中的基本算法之一是矩阵分解。这个想法是将源矩阵 M 分解为两个矩阵 A 和 B,使 A * B = M。矩阵分解没有任何直接用途,但分解是矩阵求逆和其他几个基本算法的关键组成部分。
在我居住的太平洋西北部的一个下雨周末(是的,PNW 中的“下雨”是多余的)我决定使用 Python 实现一个矩阵分解函数。有几种分解算法。我使用了克劳特的算法。
我的演示程序从矩阵 M 开始:
[3.0 7.0 2.0 5.0]
[1.0 8.0 4.0 2.0]
[2.0 1.0 9.0 3.0]
[5.0 4.0 7.0 1.0] ])
得到的 LUM(“下-上”)分解和辅助排列数组是:
[ 5.0000 4.0000 7.0000 1.0000 ]
[ 0.2000 7.2000 2.6000 1.8000 ]
[ 0.4000 -0.0833 6.4167 2.7500 ]
[ 0.6000 0.6389 -0.6017 4.9048 ]
[ 3 1 2 0 ]
LUM 的下半部分(对角线下方的元素,对角线上有虚拟 1s)是分解的第一部分:
[ 1.0000 0.0000 0.0000 0.0000 ]
[ 0.2000 1.0000 0.0000 0.0000 ]
[ 0.4000 -0.0833 1.0000 0.0000 ]
[ 0.6000 0.6389 -0.6017 1.0000 ]
LUM的上半部分是:
[ 5.0000 4.0000 7.0000 1.0000 ]
[ 0.0000 7.2000 2.6000 1.8000 ]
[ 0.0000 0.0000 6.4167 2.7500 ]
[ 0.0000 0.0000 0.0000 4.9048 ]
当您将低乘以高时,结果几乎是原来的 M,除了一些行被置换:
[ 5.0000 4.0000 7.0000 1.0000 ]
[ 1.0000 8.0000 4.0000 2.0000 ]
[ 2.0000 1.0000 9.0000 3.0000 ]
[ 3.0000 7.0000 2.0000 5.0000 ]
要恢复原始矩阵,您可以根据排列数组 [3 1 2 0] 中的信息重新排列行。
当我实现 Crout 的分解时,我在交换矩阵的两行时遇到了一个令人讨厌的语法问题。我花了一个小时调试。详细信息可能会填满整篇博客文章,因此我只需要注意交换矩阵的两行需要小心。
艺术中的分解。左图:艺术家 Cane Dojcilovic。中心:由艺术家阿尔贝托·塞维索 (Alberto Seveso) 创作。右图:艺术家 Antonio Saraiva。
演示代码。用正确的符号替换“lt”(小于)、“gt”等。
# crout.py
# crout 的分解
将numpy导入为np
def mat_decompose (m) :
# 矩阵行列式和逆矩阵的 Crout LU 分解
# 在 lum[][] 中存储组合的下和上
# 将行排列存储到 perm[]
# 切换是 +1(偶数)或 -1 行排列数
#lower在对角线上获得虚拟的1.0s(0.0s以上)#upper在对角线
上获得lum值(0.0s以下)
切换 = + 1 # 偶数
n = len(m)
lum = np.copy(m)
perm = np.arange(n)
for j in range( 0 ,n -1 ): # 按列处理。注意 n-1
max = np.abs(lum[j][j]) # 或 lum[i,j]
piv = j
对于我在范围第(j + 1,n)的:
xij = np.abs(lum[i][j])
如果xij "gt"最大值:
最大值 = xij; piv = 我
if piv != j: # 交换行 j, piv
lum[[j,piv]] = lum[[piv,j]] # 特殊语法
t = perm[piv] # 交换物品
烫[piv] = 烫[j]
烫发[j] = t
切换 = -切换
xjj = lum[j][j]
if np.abs(xjj) "gt" 1.0e-5 : # if xjj != 0.0
for i in range(j+ 1 ,n):
xij = lum[i][j] / xjj
lum[i][j] = xij
用于?在范围第(j + 1,n)的:
lum[i][k] -= xij * lum[j][k]
返回(切换,lum,烫发)
def get_lower (lum) :
n = len(lum)
结果 = np.zeros((n,n))
for i in range(n):
for j in range(n):
if i == j:
结果[i][j] = 1.0
elif i "gt" j:
结果[i][j] = lum[i][j]
返回结果
def get_upper (lum) :
n = len(lum)
结果 = np.zeros((n,n))
for i in range(n):
for j in range(n):
if i "lte" j:
结果[i][j] = lum[i][j]
返回结果
def 放松(lu, perm) :
结果 = np.copy(lu)
对于我在范围(LEN(烫发)):
j = 烫发[i]
结果[i] = lu[j]
返回结果
def main () :
print( "\n开始Crout的矩阵分解演示" )
np.set_printoptions(formatter={ 'float' : '{: 0.4f}' .format})
m = np.array([[ 3.0 , 7.0 , 2.0 , 5.0 ],
[ 1.0 , 8.0 , 4.0 , 2.0 ],
[ 2.0 , 1.0 , 9.0 , 3.0 ],
[ 5.0 , 4.0 , 7.0 , 1.0 ]])
打印(“\纳米=”)
打印(米)
(toggle, lum, perm) = mat_decompose(m)
打印(“\nlum =”)
打印(流明)
打印(“\nperm =”)
打印(烫发)
下 = get_lower(lum)
打印(“\n较低=”)
打印(下)
上 = get_upper(lum)
打印(“\nupper =”)
打印(上)
lu = np.matmul(下,上)
打印(“\n下*上=“)
打印(卢)
原始 = 放松(lu,烫发)
打印(“\n原始=”)
打印(原件)
打印(“\n结束演示”)
如果__name__ == "__main__":
主要的()
- 上一篇: 推荐系统经典技术:矩阵分解(矩阵分解算法原理)
- 下一篇: 进阶隐式矩阵分解——探讨如何实现更快的算法
猜你喜欢
- 2024-09-18 基于Householder变换实现超定矩阵的QR分解的算法
- 2024-09-18 伟弘精益小知识:利用矩阵表分解和制定各个部门绩效KPI
- 2024-09-18 用Spark学习矩阵分解推荐算法(矩阵分解模型)
- 2024-09-18 基于矩阵分解的推荐算法(基于矩阵分解的推荐系统)
- 2024-09-18 矩阵分解系列:目录(矩阵分解表)
- 2024-09-18 通俗易懂的讲解奇异值分解(SVD)和主成分分析(PCA)
- 2024-09-18 30 分钟学会机器学习 SVD 矩阵分解(Python代码)
- 2024-09-18 推荐系统基础:使用PyTorch进行矩阵分解
- 2024-09-18 矩阵分解推荐算法(矩阵分解推荐算法代码)
- 2024-09-18 进阶隐式矩阵分解——探讨如何实现更快的算法
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)