LSA - 潜在语义分析 - 如何用PHP编写?

9
我希望能在PHP中实现潜在语义分析(LSA)以找出文本的主题/标签。
以下是我认为需要完成的步骤。这样做正确吗?如何用PHP编码?如何确定选择哪些单词?
我不想使用任何外部库。我已经有了奇异值分解(SVD)的实现
1. 从给定文本中提取所有单词。 2. 对单词/短语进行加权,例如使用tf-idf。如果加权过于复杂,只需考虑出现次数。 3. 构建一个矩阵:列是来自数据库的一些文档(越多越好?),行是所有唯一的单词,值是出现次数或权重。 4. 进行奇异值分解(SVD)。 5. 使用矩阵S(SVD)中的值进行降维(如何?)。
希望您能帮助我。非常感谢!

1
我已经实现了奇异值分解。 - Ben
抱歉,我现在已经添加了链接。 - caw
这与PHP有什么关系? - Phil Miller
@Novelocrat:我想了解LSA的工作原理以及如何在PHP中编写代码。这就是它与PHP有关的内容。 ;) - caw
1
你的语料库有多大?谈论文档的大小、数量以及它们的分布。它们是否涉及类似的主题?它们只是随机的博客文章/网页吗?还是自由文本?更多的上下文将决定LSA是否是适合你的方法。 - Gregg Lind
我的语料库中的文档涉及不同主题,可以说是随机新闻文章。每个文档的大小为100-200个字符(非常短的新闻)。每天应该有大约600篇新文档。我不知道需要考虑多少旧文档。但是,LSA是否能够提取标签/实体/名称呢?如果LSA不适用于命名实体识别,那么我可以忘记这个问题了。 - caw
4个回答

7

LSA链接:

以下是完整的算法。如果您拥有SVD,那么您已经完成了大部分工作。上述论文比我更好地解释了它。

假设:

  • 您的SVD函数将按降序给出奇异值和奇异向量。 如果不是这样,您需要做更多的杂技。

M:语料库矩阵,w(单词)乘以d(文档)(w行,d列)。这些可以是原始计数,或tfidf或其他任何东西。停用词可能会被消除,也可能不会,而词干可能会发生变化(Landauer表示保留停用词,不进行词干提取,但可以使用tfidf)。

U,Sigma,V = singular_value_decomposition(M)

U:  w x w
Sigma:  min(w,d) length vector, or w * d matrix with diagonal filled in the first min(w,d) spots with the singular values
V:  d x d matrix

Thus U * Sigma * V = M  
#  you might have to do some transposes depending on how your SVD code 
#  returns U and V.  verify this so that you don't go crazy :)

那么,简化性... 实际的LSA论文建议一个好的基础近似是保留足够的向量,使它们的奇异值超过奇异值总和的50%。

更简洁地说...(伪代码)

Let s1 = sum(Sigma).  
total = 0
for ii in range(len(Sigma)):
    val = Sigma[ii]
    total += val
    if total > .5 * s1:
        return ii

这将返回新基础的等级,之前为min(d,w),现在我们将用{ii}进行近似。

(这里,“-> prime”表示不是转置)

我们创建新矩阵:U'、Sigma'、V',大小分别为w x ii,ii x ii和ii x d。

这就是LSA算法的本质。

由此产生的矩阵U' * Sigma' * V'可用于“改进”的余弦相似性搜索,或者您可以选择其中每个文档的前3个单词。是否比简单的tf-idf更有效仍有一些争议。

对我来说,由于多义词和包含太多主题的数据集,LSA在实际数据集中表现不佳。它的数学/概率基础是不可靠的(它假设正常-ish(高斯)分布,这对于单词计数没有意义)。

你的结果肯定会有所不同。

使用LSA进行标记(一种方法!)

  1. 使用SVD和缩减启发式构建U' Sigma' V'维度降低矩阵

  2. 手动查看U'矩阵,并想出描述每个“主题”的术语。例如,如果该向量的最大部分是“Bronx,Yankees,Manhattan”,则“New York City”可能是一个好术语。将这些保存在关联数组或列表中。由于向量数是有限的,因此这一步应该是合理的。

  3. 假设您有一个单词向量(v1)用于文档,则v1 * t(U')将为该文档提供最强的“主题”。选择前3个最高的主题,然后将它们作为上一步计算出的“主题”。


肯定的,这正是我想要知道的内容。但我仍然有一些问题:我需要V还是VT(转置)?我使用http://stitchpanorama.sourceforge.net/Python/svd.py,它给出了V。如你所见,奇异值并不是按降序排列的。这是您在PHP中的伪代码函数吗?http://paste.bradleygill.com/index.php?paste_id=10532 它是做什么用的? - caw
判断你需要 V 还是 Vt 的简单测试是确定 USV = M 还是 USVt = M。该函数是一种启发式方法,用于确定要减少多少维度。在此函数中,它说:“减少基础使向量的奇异值总和达到50%或更多”。您也可以只说“保留k个最大值,例如50”……基本上,确定实际上有多少类别,这就是 LSA 的全部意义。 - Gregg Lind
有没有解决这个 PHP LSA 问题的方案。我理解该算法,但一直在努力将其实现为 PHP 代码。 - privateace
不是我,唉!我是一名Python/R黑客 :) - Gregg Lind

1

这个回答并不是直接回答发帖者的问题,而是关于如何自动标记新闻项目的元问题。发帖者提到了命名实体识别,但我认为他们更倾向于自动标记。如果他们真的指的是NER,那么这个回答就是胡说八道 :)

考虑到这些限制(每天600个项目,每个项目100-200个字符),来源各异,以下是一些标记选项:

  1. 手动标注。分析员每天可以轻松完成600个,可能只需要几个小时。类似于亚马逊的 Mechanical Turk 或让用户自己完成也是可行的。即使只有50或100个“手动标记”,也将成为比较下面自动生成方法的良好基础。

  2. 降维,使用LSA、主题模型(潜在狄利克雷分配)等方法...我在实际数据集上使用LSA的效果非常差,对其统计基础不满意。我认为LDA更好,并且有一个令人难以置信的邮件列表,其中包含了如何为文本分配主题的最佳思路。

  3. 简单的启发式算法...如果你有实际的新闻项目,那么利用新闻项目的结构。关注第一句话,去掉所有常见词(停用词),从前两个句子中选择最好的3个名词。或者干脆取出第一句话中的所有名词,看看会得到什么结果。如果文本都是英文,则对整个文本进行词性分析,看看会得到什么结果。对于结构化的项目,如新闻报道,LSA和其他无序方法(tf-idf)会丢失很多信息。

祝你好运!

(如果您喜欢这个答案,也许可以重新标记问题以适应它)


非常感谢。你说得对,我是指自动标记。但我绝对不想手动标记文章(1)。第三种方法太简单了,结果太差(已经尝试过)。但第二种方法听起来不错,这就是我的问题所在。;) 我想用LSA自动标记(我没有使用这个词,但其他错误的词可能会出现)新闻文章。LDA也不错,但它是一种分类方法,而不是标记方法。 - caw
LDA也适用于标记。所有这些技术都是试图减少文档空间的维度(基础)。 - Gregg Lind

0

所有看起来都没问题,直到最后一步。SVD的通常表示法是返回三个矩阵A = USV*。S是一个对角矩阵(意味着对角线外都是零),在这种情况下,基本上给出了每个维度捕获原始数据的程度的度量。数字(“奇异值”)会下降,您可以寻找有多少维度是有用的下降点。否则,您将想要选择任意数量N来采取多少维度。

在这里我有点模糊。缩减维度空间中术语(单词)的坐标位于U或V中,我认为这取决于它们是否在输入矩阵的行或列中。不偏不倚地说,我认为单词的坐标将是U的行。即第一行U对应于输入矩阵的第一行,即第一个单词。然后,您只需在该行中取前N列作为单词在缩减空间中的坐标。

希望对您有所帮助

更新:

到目前为止,这个过程并没有告诉你如何精确挑选标签。我从来没听说过有人使用潜在语义索引(LSI)来选择标签(像机器学习算法可能更适合这个任务,比如决策树)。LSI只是告诉你两个单词是否相似,这离分配标签还有很长的路要走。

这里有两个任务:a)使用哪些标签集?b)如何选择最佳的三个标签?我不太清楚LSI如何帮助你回答a)。你可以手动选择标签集。但是,如果你使用LSI,则标签可能应该是文档中出现的词。然后对于b),您需要挑选最接近文档中出现的单词的标签。您可以尝试几种实现方式。选择距离文档中任何单词最近的三个标签,接近程度由标签的坐标(其在U中的行)和单词的坐标(其在U中的行)之间的余弦相似度(参见维基百科)来衡量。


谢谢。我的主要问题是:我该如何确定选择哪些单词?假设我总是想要有3个标签:我需要做什么? - caw
谢谢。也许我误解了一些内容,LSA并不用于查找标签。但如果我有一组标签,例如“体育、政治、世界”,那么肯定可以使用LSA来找到最佳匹配的标签,对吧? - caw
但是如果我有一组标签,例如“体育、政治、世界”,那么LSA并不适用于这种情况。如果你有这些标签和一些关于这些主题的文章语料库,使用贝叶斯分类器会更合适。LSA的作用是说,“单词:棒球、洋基队、A-Rod倾向于共同出现,并可能反映一些潜在结构,因此其他包含棒球的文章可能与相同的潜在主题相关”。LSA只是因子分析。 - Gregg Lind

0

关于在PHP中完成所有这些工作的危险,有一个额外的SO线程链接文本

具体来说,那里有一个链接指向潜在语义映射的论文,该论文描述了如何获取文本的结果“主题”。


你链接的那个问题(第一个链接)是我的一个问题。;) 我也在这个页面顶部的问题中链接了它。但那个问题是关于SVD的,而这个问题是关于LSA的... - caw
SVD是LSA的一部分,在SO讨论中有相关内容。请查看Blackkettle的回答。您需要进行SVD,减少特征值矩阵,然后重新组合。请阅读LSM论文,其中包含了具体步骤。尽管如此,我认为对于您的自动标记项目来说,您对LSM的解决方案寄予了过多的信任。 - Gregg Lind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接