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

caw*_*caw 9 php tagging linguistics lsa semantics

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

以下是我认为我必须做的事情.它是否正确?如何在PHP中编写代码?如何确定要选择的单词?

我不想使用任何外部库.我已经实现了奇异值分解(SVD).

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

我希望你能帮助我.非常感谢你提前!

Gre*_*ind 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 :)
Run Code Online (Sandbox Code Playgroud)

然后还原性......实际的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
Run Code Online (Sandbox Code Playgroud)

这将返回新基础的等级,即之前的min(d,w),现在我们将近似{ii}.

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

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

这是LSA算法的本质.

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

对我来说,LSA在真实世界的数据集中表现不佳,因为多义词和主题太多的数据集.它的数学/概率基础是不合理的(它假定正常 - 高斯(Gaussian)分布,这对于字数没有意义).

你的里程肯定会有所不同.

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

  1. 使用SVD和简化启发式构建U'Sigma'V'尺寸减小的矩阵

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

  3. 假设您有一个文档的向量(v1),那么v1*t(U')将为该文档提供最强的"主题".选择最高3,然后按照上一步计算出的"主题".