求解超定系统最小二乘的最快方法

2024-05-13

我有一个大小为 m*n 的矩阵 A(m 阶约为 100K,n 阶约为 500)和向量 b。另外,我的矩阵是病态的并且等级不足。现在我想找出 Ax = b 的最小二乘解,为此我比较了一些方法:

  • scipy.linalg.lstsq(时间/剩余):14s,626.982
  • scipy.sparse.linalg.lsmr(时间/残差):4.5s,626.982(相同精度)

现在我发现,当我没有形成正规方程的秩不足情况时,使用乔列斯基分解来解决它是解决我的问题的最快方法。所以我的问题是,如果我对最小范数解不感兴趣,那么当 A^TA 为奇异值时,有没有办法获得 (A^TAx=b) 的解(任何)。我尝试过 scipy.linalg.solve 但它给出了奇异矩阵的 LinAlgError 。另外我想知道 A 是否满足 m>>n、条件不良、可能不是完全排序,那么在时间、剩余精度(或任何其他指标)方面应该使用哪种方法。非常感谢任何想法和帮助。谢谢!


我想说解决这个问题的“正确”方法是使用 SVD,查看您的奇异值谱,并找出您想要保留多少个奇异值,即找出您想要的接近程度A^T x成为b。沿着这些思路:

def svd_solve(a, b):
    [U, s, Vt] = la.svd(a, full_matrices=False)
    r = max(np.where(s >= 1e-12)[0])
    temp = np.dot(U[:, :r].T, b) / s[:r]
    return np.dot(Vt[:r, :].T, temp)

然而,对于大小的矩阵(100000, 500),这实在是太慢了。我建议您自己实现最小二乘法,并添加少量正则化以避免矩阵变得奇异的问题。

def naive_solve(a, b, lamda):
    return la.solve(np.dot(a.T, a) + lamda * np.identity(a.shape[1]),
                    np.dot(a.T, b))

def pos_solve(a, b, lamda):
    return la.solve(np.dot(a.T, a) + lamda * np.identity(a.shape[1]),
                    np.dot(a.T, b), assume_a='pos')

这是我的工作站上的时序分析*:

>>> %timeit la.lstsq(a, b)
1.84 s ± 39.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
>>> %timeit naive_solve(a, b, 1e-25)
140 ms ± 4.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
>>> %timeit pos_solve(a, b, 1e-25)
135 ms ± 768 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

*我似乎没有scipy.sparse.linalg.lsmr在我的机器上,所以我无法与之比较。

它在这里似乎没有多大作用,但我在其他地方看到添加assume_a='pos'flag实际上可以给你带来很多好处。您当然可以在这里执行此操作,因为A^T A保证是半正定的,并且lamda使其正定。你可能需要玩lamda一点点使你的错误足够低。

就错误而言:

>>> xhat_lstsq = la.lstsq(a, b)[0]
>>> la.norm(np.dot(a, xhat_lstsq) - b)
1.4628232073579952e-13
>>> xhat_naive = naive_solve(a, b, 1e-25)
>>> la.norm(np.dot(a, xhat_naive) - b)
7.474566255470176e-13
>>> xhat_pos = pos_solve(a, b, 1e-25)
>>> la.norm(np.dot(a, xhat_pos) - b)
7.476075564322223e-13

PS:我生成了一个a and a b我自己的像这样:

s = np.logspace(1, -20, 500)
u = np.random.randn(100000, 500)
u /= la.norm(u, axis=0)[np.newaxis, :]
a = np.dot(u, np.diag(s))
x = np.random.randn(500)
b = np.dot(a, x)

My a不是完全奇异的,而是接近奇异的。

对评论的回应

我想你想做的是在一些线性等式约束下找到一个可行点。这里的问题是你不知道哪些约束是重要的。 A 的 100,000 行中的每一行都会给您一个新的约束,其中最多 500 个(但可能少得多(因为不确定性))实际上很重要。 SVD 为您提供了一种确定哪些维度重要的方法。我不知道还有其他方法可以做到这一点:您可能会在凸优化或线性编程文献中找到一些东西。如果您先验知道 A 的等级是r,那么你可以尝试只找到第一个r奇异值和相应的向量,如果r << n.

关于您的其他问题,最低范数解决方案不是“最佳”甚至“正确”的解决方案。由于您的系统是不确定的,因此您需要引入一些额外的约束或假设,这将帮助您找到独特的解决方案。最小范数约束就是其中之一。最小范数解通常被认为是“好的”,因为如果x是您尝试设计的一些物理信号,然后是x较低范数通常对应于具有较低的能量,然后转化为成本节省等。或者,如果x是您尝试估计的某个系统的参数,那么选择最小范数解意味着您assuming该系统在某种程度上是高效的,并且仅使用产生结果所需的最少能量b。希望一切都有意义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

求解超定系统最小二乘的最快方法 的相关文章

随机推荐

  • 标准和定制 GATT 特征

    我正在为 Android 手机和 Android 手表 wearOS 编写应用程序 这些应用程序将通过蓝牙相互通信 基本上Android手机上的应用程序将与WearOS设备绑定 然后与WearOS上的应用程序通信以启动指定功能 获取电池信息
  • 在 JavaScript 中使用 Pylons 全局变量(转义括号)

    我正在尝试访问 JavaScript 中 Python 全局变量中保存的字典中的结果 var selected jQuery target option selected text var list c persons by permiss
  • 如何定义/传递 sonata-admin 的实体管理器

    我跟着本教程 http symfony2 ylly fr sonataadminbundle fosuserbundle have a good base project jordscream 使用 FOSUserBundle 安装 Son
  • 恒定大小数组的运行中位数

    我正在尝试找到恒定大小数组的中位数 但数组总是在更新 我的意思是新号码被旧号码替换 我称这个过程为运行中位数 或者我们可以说动态中位数 这是我的代码 在代码内部 当 rand 函数生成 78 时 代码无法找到正确的中位数 78 41 67
  • 在recyclerview中notifydatachange期间保留连锁反应

    我开始修改我的应用程序以支持棒棒糖 基本上 我有一个带有 recyclerview 的文件浏览器片段 当用户打开这个片段时 他将看到其根目录上的所有文件夹 当用户单击该文件夹时 我需要获取所有子文件夹 文件并将它们显示给用户使用与notif
  • 当我尝试从列表中删除元素时,如何忽略 ValueError?

    如果我打电话 如何忽略 不在列表中 错误消息a remove x when x不在列表中a 这是我的情况 gt gt gt a range 10 gt gt gt a 0 1 2 3 4 5 6 7 8 9 gt gt gt a remov
  • cin >> num1, num2 有什么问题吗?

    include
  • SVG 在 Firefox 中渲染得很糟糕

    我正在制作带有滑动轮播的信息图表 li 我认为 尽管 FF 中 SVG 的错误已得到解决 但 SVG 在 Firefox 中显示为像素化 有人能看到这个问题的解决办法吗 URL http weaver wp weavertest com r
  • 克隆存储库而不将其设为原始远程存储库

    我正在从一台将被擦除的计算机上克隆一个 git 存储库 是否可以在不创建原始存储库的情况下克隆存储库origin master 或者我是否需要克隆它 然后删除远程分支 这是通过git remote rm origin Edit 存储库只有一
  • 如何使用 rspec 测试 ActionCable 和 Devise?

    在我的 Rails 5 1 应用程序中 我使用设备进行身份验证和 ActionCable 我的 ActionCable 连接如下所示 module ApplicationCable class Connection lt ActionCab
  • ImportError:在 Google 应用引擎中找不到 django.utils

    当我在 google app engine 项目中使用 django utils 中的 simplejson 时 出现此错误 Traceback most recent call last File base python27 runtim
  • 使用 Outlook 365 API 在组织中获取电子邮件的最佳方式

    我正在构建一个应用程序 用于从组织内部的电子邮件收集统计信息 我们假设这些组织使用 Outlook 365 我希望能够以最简单的方式执行以下操作 获取阅读组织中所有邮件的权限 获取电子邮件 附件并运行我的统计数据 Outlook 365 似
  • vim 退出时恢复 shell

    我刚刚在我的新计算机上安装了 Arch 但我不知道需要向 vimrc 添加什么命令 以便它在退出时恢复 shell 内容 在调用 vim 之前 也就是说 我希望我的 shell 看起来像这样 whoami root who root tty
  • 使用 Linq to Entities 查询创建 null ienumerable

    我正在开发一个使用实体框架的 ASP NET MVC 项目 我需要将从数据库中提取的值投影到PropertyValue类型 如下所示 public class PropertyValue public string StringValue
  • 将所有工作簿工作表复制到新工作簿 VBA

    我正在使用此代码将工作簿中的每张工作表复制到新工作簿中 它工作正常 但它颠倒了工作表的顺序 是否有办法阻止它这样做 Sub copy copies all the sheets of the open workbook to a new o
  • Java 数组操作

    我有一个名为 resize 的函数 它接受源数组 并将大小调整为新的宽度和高度 我认为我正在使用的方法效率低下 我听说有更好的方法可以做到这一点 无论如何 当scale是一个int时 下面的代码有效 然而 还有第二个函数称为 half 它使
  • Dart:如何在本机扩展中创建流

    在我的本机扩展中 我需要将整数流式传输到我的 Dart 控制台应用程序 在概念上非常相似 标准输入 如何创建向控制台应用程序公开的本机 Dart Stream 对象 我尝试为您创建一个示例并将其放在 github 上 https githu
  • r caret 包中的 train 函数的模型输出尺寸巨大

    我正在使用 bagFDA 模型进行训练train r caret 包中的函数 并将模型输出保存为 Rdata 文件 输入文件大约有 300k 条记录 有 26 个变量 但输出 Rdata 大小为 3G 我只是运行以下命令 modelout
  • VirtualAlloc 对齐方式与分配大小一致吗?

    当使用VirtualAlloc用于分配和提交具有页面边界的两倍大小的虚拟内存区域的 API 例如 void address VirtualAlloc 0 0x10000 MEM COMMIT PAGE READWRITE Get 64KB
  • 求解超定系统最小二乘的最快方法

    我有一个大小为 m n 的矩阵 A m 阶约为 100K n 阶约为 500 和向量 b 另外 我的矩阵是病态的并且等级不足 现在我想找出 Ax b 的最小二乘解 为此我比较了一些方法 scipy linalg lstsq 时间 剩余 14