9

我想在 PHP 中实现潜在语义分析(LSA),以便找出文本的主题/标签。

这是我认为我必须做的。它是否正确?如何在 PHP 中编写代码?我如何确定选择哪些词?

我不想使用任何外部库。我已经实现了 Singular Value Decomposition (SVD)

  1. 从给定文本中提取所有单词。
  2. 加权单词/短语,例如使用tf–idf。如果加权太复杂,只取出现次数。
  3. 建立一个矩阵:列是数据库中的一些文档(越多越好?),行都是唯一的单词,值是出现次数或权重。
  4. 执行奇异值分解 (SVD)。
  5. 使用矩阵 S (SVD) 中的值进行降维(如何?)。

我希望你能帮助我。非常感谢您!

4

4 回答 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} 进行近似。

(这里,'-> 素数,不是转置)

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

这就是LSA算法的本质。

这个结果矩阵 U' * Sigma' * V' 可用于“改进的”余弦相似度搜索,或者您可以选择其中每个文档的前 3 个单词,例如。这是否不仅仅是一个简单的 tf-idf 是一个有争议的问题。

对我来说,LSA 在现实世界的数据集中表现不佳,因为多义性和主题太多的数据集。它的数学/概率基础是不健全的(它假设正态分布(高斯),这对字数没有意义)。

您的里程肯定会有所不同。

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

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

  2. 手动查看 U' 矩阵,并提出描述每个“主题”的术语。例如,如果该向量的最大部分是“布朗克斯、洋基队、曼哈顿”,那么“纽约市”可能是一个很好的术语。将它们保存在关联数组或列表中。这一步应该是合理的,因为向量的数量是有限的。

  3. 假设您有一个文档的单词向量 (v1),那么 v1 * t(U') 将为该文档提供最强的“主题”。选择 3 个最高的,然后给出他们在上一步中计算的“主题”。

于 2009-06-24T15:17:29.607 回答
1

这个答案不是直接针对发布者的问题,而是针对如何自动标记新闻项目的元问题。OP 提到了命名实体识别,但我相信它们的含义更接近自动标记。如果他们真的是指NER,那么这个回应就是胡说八道:)

鉴于这些具有不同来源的限制(600 项/天,100-200 个字符/项),这里有一些标记选项:

  1. 用手。分析师每天可以轻松完成 600 次此类操作,可能需要几个小时。像亚马逊的 Mechanical Turk 或让用户这样做,也可能是可行的。拥有一些“手工标记”,即使它只有 50 或 100 个,也将成为比较下面自动生成的方法为您提供的任何内容的良好基础。

  2. 使用 LSA、Topic-Models(潜在 Dirichlet 分配)等来减少维度……我在现实世界的数据集上对 LSA 的运气真的很差,而且我对它的统计基础不满意。LDA 我发现要好得多,并且有一个 令人难以置信的邮件列表,它对如何将主题分配给文本有最好的思考。

  3. 简单的启发式方法...如果您有实际的新闻项目,则利用新闻项目的结构。关注第一句,扔掉所有常用词(停用词),从前两句中选出最好的 3 个名词。或者,见鬼,把第一句话中的所有名词都拿走,看看你会得到什么。如果文本都是英文的,那么对整个 shebang 进行词性分析,看看能得到什么。对于结构化项目,如新闻报道、LSA 和其他与订单无关的方法 (tf-idf) 会抛出大量信息。

祝你好运!

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

于 2009-06-23T13:40:53.427 回答
0

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

在这里我有点模糊。降维空间中术语(单词)的坐标是 U 还是 V,我认为取决于它们是在输入矩阵的行还是列中。顺便说一句,我认为单词的坐标将是 U 的行。即 U 的第一行对应于输入矩阵的第一行,即第一个单词。然后,您只需将该行的前 N ​​列作为单词在缩小空间中的坐标。

高温高压

更新:

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

有两个任务 - a) 要使用的标签集是什么?b) 如何选择最好的三个标签?我不太了解 LSI 将如何帮助您回答 (a)。您可以手动选择标签集。但是,如果您使用的是 LSI,标签可能应该是文档中出现的单词。然后对于 (b),您想要挑选出与文档中找到的单词最接近的标签。您可以尝试几种实现方式。选择最接近文档中任何单词的三个标签,其中接近度通过标签坐标(U 中的行)和单词坐标(U 中的行)之间的余弦相似度(参见 Wikipedia)来衡量。

于 2009-06-19T21:55:52.417 回答
0

在链接文本处有一个额外的 SO 线程,说明在 PHP 中执行此操作的风险。

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

于 2009-06-23T13:51:31.847 回答