PHP中的奇异值分解(SVD)

时间:2009-06-06 16:25:02

标签: php svd eigenvector eigenvalue

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

我已经自己编写了SVD的某些部分。 Here's the code我对行动过程发表了评论。此代码的某些部分并不完全正确。

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

6 个答案:

答案 0 :(得分:9)

SVD-蟒 是一个非常清晰,简洁的SVD实现。 它实际上是伪代码,应该很容易理解 并比较/绘制你的php实现,即使你不太了解python。

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'包含您的奇异值列表 当然,这只能让你成为潜在语义分析及其亲属的一部分。 您通常希望减少奇异值的数量,然后使用一些适当的距离 度量标准,用于衡量文档,文字,文档和文字等之间的相似性。 你得到的矢量之间角度的余弦很受欢迎。

Latent Semantic Mapping (pdf)

是迄今为止我读过的关于你剩下的步骤的最清晰,最简洁,最翔实的论文 需要按照SVD进行研究。

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

最后如上面的bellegarda论文所述,请记住,你不必重新计算 每次获得新文档或请求时都会显示svd。取决于你想要做什么,你可以 可能每周左右执行一次svd,在离线模式下,本地机器, 然后上传结果(尽管有尺寸/带宽问题)。

无论如何祝你好运!

答案 1 :(得分:5)

当你说“我不在乎时间限制”时要小心。 SVD是O(N^3)操作(如果它是矩形O(MN^2)矩阵,则为m*n),这意味着您可能很容易遇到问题可能需要很长时间的情况。如果100 * 100的情况需要一分钟,1000 * 1000的情况将是10 ^ 3分钟,或接近17个小时(并且可能更糟,实际上,因为您可能没有缓存)。对于类似PHP的东西,前因子 - 乘以N^3以计算所需FLOP计数的数字可能非常非常大。

话虽如此,当然可以用PHP编写代码 - 该语言具有所需的数据结构和操作。

答案 2 :(得分: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架构师作者Cal Evans:“PHP是一种Web脚本语言...... [但是]我使用PHP作为脚本语言编写DOS等效的BATCH文件或Linux等效的shell脚本。我已经发现我需要做的大部分工作都可以在PHP中完成。甚至还有一个项目允许你通过PHP(PHP-GTK项目)构建桌面应用程序。“

答案 3 :(得分:2)

关于问题1:绝对有可能。是否合理取决于您的情况:您的矩阵有多大?您打算多久运行一次代码?它是在网站上运行还是从命令行运行? 如果您关心速度,我建议writing a simple extension包含对GNU Scientific Library的调用。

答案 4 :(得分:1)

是的,它是可行的,但在PHP中实施SVD并不是最佳方法。正如你在这里看到的,PHP比C慢,也比C ++慢,所以如果你能用其中一种语言做它并将它们称为函数来获得结果,那就更好了。您可以找到算法here的实现,因此您可以通过它来指导自己。

关于函数调用可以使用:

  • exec()函数

系统功能非常有用且功能强大,但其中一个最大的问题是程序中的所有结果文本都直接转到输出流。在某些情况下,您可能希望格式化生成的文本并以不同的方式显示它,或者根本不显示它。

  • system()函数

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

  • passthru()函数

PHP提供的一个与我们迄今为止看到的相似的功能是passthru功能。与其他函数一样,此函数执行您告诉它的程序。但是,它会立即将此程序的原始输出发送到PHP当前正在使用的输出流(即Web服务器方案中的HTTP或PHP命令行版本中的shell)。

答案 5 :(得分:0)

  1. 是。这完全可以用PHP实现。 我不知道执行的合理时间框架和计算的大小。 我可能不得不实施算法来获得一个好主意。

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

  3. 就像一个旁听的问题。您使用的是哪个版本的PHP?