9

我想在 PHP 中实现奇异值分解(SVD)。我知道有几个外部库可以为我做到这一点。但是我有两个关于 PHP 的问题:1) 你认为用 PHP 编写 SVD 是可能和/或合理的吗?2) 如果 (1) 是肯定的:你能帮我用 PHP 编码吗?

我已经自己编写了 SVD 的某些部分。这是我对操作过程进行评论的代码。此代码的某些部分并不完全正确。

如果你能帮助我,那就太好了。非常感谢您!

4

6 回答 6

9

SVD-python 是一个非常清晰、简洁的 SVD 实现。它实际上是伪代码,即使您不太了解 python,也应该很容易理解和比较/借鉴您的 php 实现。

SVD-python

也就是说,正如其他人所提到的,我不希望能够通过 php 实现来执行非常繁重的 LSA,这听起来像是一个非常有限的网络主机。

干杯

编辑:上面的模块本身并没有做任何事情,但是在开头的评论中有一个例子。假设您下载了 python 模块,并且可以访问它(例如在同一个文件夹中),您可以实现一个简单的示例,如下所示,

#!/usr/bin/python
import svd
import math

a = [[22.,10., 2.,  3., 7.],
     [14., 7.,10.,  0., 8.],
     [-1.,13.,-1.,-11., 3.],
     [-3.,-2.,13., -2., 4.],
     [ 9., 8., 1., -2., 4.],
     [ 9., 1.,-7.,  5.,-1.],
     [ 2.,-6., 6.,  5., 1.],
     [ 4., 5., 0., -2., 2.]]

u,w,vt = svd.svd(a)
print w

这里 'w' 包含你的奇异值列表。
当然,这只会让你部分了解潜在语义分析及其相关内容。您通常希望减少奇异值的数量,然后使用一些适当的距离度量来衡量您的文档、单词、文档和单词等之间的相似性。结果向量之间角度的余弦值非常流行。

潜在语义映射 (pdf)

是迄今为止我读过的最清晰、最简洁、信息量最大的论文,介绍了您需要按照 SVD 制定的剩余步骤。

Edit2:还请注意,如果您正在使用非常大的术语文档矩阵(我假设这是您正在做的事情),那么在离线模式下执行分解几乎肯定会更有效率,然后响应请求,仅以实时方式执行比较。虽然 svd-python 非常适合学习,但 svdlibc 更适合您进行如此繁重的计算。

最后,如上面的 bellegarda 论文中所述,请记住,您不必每次获得新文档或请求时都重新计算 svd。根据您要执行的操作,您可能每周左右执行一次 svd,在离线模式下,在本地计算机上执行一次,然后上传结果(尽管存在大小/带宽问题)。

反正祝你好运!

于 2009-06-15T14:46:24.207 回答
5

当你说“我不在乎时间限制是多少”时要小心。SVD 是一种O(N^3)运算(或者O(MN^2)如果它是一个矩形m*n矩阵),这意味着您很容易陷入问题可能需要很长时间的情况。如果 100*100 的情况需要一分钟,那么 1000*1000 的情况将需要 10^3 分钟,或者将近 17 小时(实际上可能更糟,因为您可能会超出缓存)。对于 PHP 之类的东西,前置因子——N^3为了计算所需的 FLOP 计数而乘以的数字可能非常非常大。

话虽如此,当然可以用 PHP 对其进行编码——该语言具有所需的数据结构和操作。

于 2009-06-14T11:43:48.887 回答
3

我知道这是一个旧的 Q,但这是我的 2 位:

1) 真正的 SVD 比使用微积分启发的近似值慢得多,例如,在 Netflix 奖中。见:http ://www.sifter.org/~simon/journal/20061211.html

这里有一个实现(用 C 语言):http: //www.timelydevelopment.com/demos/NetflixPrize.aspx

2) C 会更快,但 PHP 肯定可以做到。

PHP Architect 作者 Cal Evans:“PHP 是一种 Web 脚本语言……[但是]我使用 PHP 作为脚本语言来编写 DOS 等效的 BATCH 文件或 Linux 等效的 shell 脚本。我发现大多数“我需要做的事情都可以在 PHP 中完成。甚至还有一个项目允许您通过 PHP 构建桌面应用程序,即 PHP-GTK 项目。”

于 2013-07-07T01:26:07.043 回答
2

关于问题1:这绝对是可能的。是否合理取决于您的场景:您的矩阵有多大?您打算多久运行一次代码?它是在网站上运行还是从命令行运行?如果您确实关心速度,我建议您编写一个简单的扩展来包装对GNU Scientific Library的调用。

于 2009-06-06T17:52:43.740 回答
1

是的,这是可能的,但在 php 中实现 SVD 并不是最佳方法。正如您在此处看到的,PHP 比 C 慢,也比 C++ 慢,所以如果您可以使用其中一种语言执行此操作并将它们作为函数调用以获取结果,则可能会更好。你可以在这里找到算法的实现,这样你就可以引导自己完成它。

关于函数调用可以使用:

  • exec() 函数

system 函数非常有用且强大,但它最大的问题之一是程序生成的所有文本都直接进入输出流。在某些情况下,您可能希望格式化生成的文本并以某种不同的方式显示它,或者根本不显示它。

  • system() 函数

PHP 中的系统函数采用字符串参数和要执行的命令以及您希望传递给该命令的任何参数。此函数执行指定的命令,并将任何结果文本转储到输出流(Web 服务器情况下的 HTTP 输出,或者如果您将 PHP 作为命令行工具运行,则为控制台)。如果它发出文本输出,则此函数的返回是程序的最后一行输出。

  • passthru() 函数

PHP 提供的与我们目前看到的类似的一个有趣的函数是 passthru 函数。这个函数和其他函数一样,执行你告诉它的程序。但是,它会立即将来自该程序的原始输出发送到 PHP 当前正在使用的输出流(即 Web 服务器场景中的 HTTP 或 PHP 命令行版本中的 shell)。

于 2009-06-15T07:23:58.123 回答
0
  1. 是的。这完全有可能在 PHP 中实现。我不知道执行的合理时间范围以及它可以计算多大。我可能必须实现该算法才能得到一个粗略的想法。

  2. 是的,我可以帮你编码。但是你为什么需要帮助?你写的代码不行吗?

就像一个题外话。你用的是什么版本的PHP?

于 2009-06-12T12:23:15.207 回答