use*_*384 7 java algorithm math latent-semantic-indexing
对不起,如果我的问题听起来很愚蠢:)你可以向我推荐任何伪代码或者在java中实现LSI的好算法吗?我不是数学专家.我试着在维基百科和其他网站上阅读一些关于LSI(潜在语义索引)的文章,他们充满了数学.我知道LSI充满了数学.但是,如果我看到一些源代码或算法.我更容易理解事情.这就是我在这里问的原因,因为有很多GURU在这里!提前致谢
ffr*_*end 13
LSA的概念基于一个假设:在同一文档中出现的两个词越多,它们就越相似.实际上,我们可以预期单词"编程"和"算法"将更频繁地出现在相同的文档中,比如"编程"和"养狗".
对于文档也是如此:两个文档具有的更常见/相似的单词,它们本身就越相似.因此,您可以通过单词的频率表达文档的相似性,反之亦然.
知道了这一点,我们就可以构造一个共生矩阵,其中列名表示文档,行名称 - 单词,每个cells[i][j]
表示words[i]
文档中单词的频率documents[j]
.频率可以通过多种方式计算,IIRC,原始LSA使用tf-idf索引.
有了这样的矩阵,你可以通过比较相应的列找到两个文档的相似性.如何比较它们?同样,有几种方法.最受欢迎的是余弦距离.你必须记住从学校数学,矩阵可以被视为一堆向量,所以每列只是一个多维空间中的向量.这就是为什么这个模型被称为"矢量空间模型".更多关于VSM和余弦距离这里.
但我们对这种矩阵有一个问题:它很大.非常非常大.使用它的计算成本太高,所以我们必须以某种方式减少它.LSA使用SVD技术来保持最"重要"的向量.在还原矩阵准备好使用之后.
因此,LSA的算法看起来像这样:
如果您要自己编写LSA库,那么首先要做的是Lucene搜索引擎,这将使第1步和第2步更容易,以及一些具有SVD功能的高维矩阵的实现,如Parallel Colt或UJMP.
还要注意从LSA长大的其他技术,如随机索引.RI使用相同的想法并显示大致相同的结果,但不使用完整矩阵阶段并且是完全递增的,这使得它在计算上更有效.
小智 2
这可能有点晚了,但我一直喜欢 Sujit Pal 的博客http://sujitpal.blogspot.com/2008/09/ir-math-with-java-tf-idf-and-lsi.html我已经写了一些我的网站,如果你有兴趣的话。
这个过程比通常写的要简单得多。实际上,您所需要的只是一个可以对矩阵进行单值分解的库。
如果您有兴趣,我可以解释一些简短的要点:
1)您创建一个矩阵/数据集/等,其中包含各种文档的字数 - 不同的文档将是您的列,行是不同的单词。
2) 创建矩阵后,您可以使用 Jama(适用于 Java)或 SmartMathLibrary(适用于 C#)等库并运行单值分解。这一切所做的就是将你的原始矩阵分解成三个不同的部分/矩阵,它们本质上代表你的文档、你的单词和一种乘数(西格玛),这些被称为向量。
3) 一旦你有了单词、文档、sigma 向量,你就可以通过复制向量/矩阵的较小部分,然后将它们相乘来同等地缩小它们 (k)。通过缩小它们,可以使您的数据标准化,这就是 LSI。
这里有一些相当明确的资源:
http://lsa.colorado.edu/papers/JASIS.lsi.90.pdf http://www.soe.ucsc.edu/classes/cmps290c/Spring07/proj/Flynn_talk.pdf
希望这对您有所帮助。
埃里克