算法系列——无监督学习——11.LSA

一、概述

LSA(Latent Semantic Analysis,潜在语义分析)是一种自然语言处理技术。作为一种降维算法,它常被用于信息搜索领域。使用LSA能够从大量的文本数据中找出单词之间的潜在关联性。

LSA是在1988年被提出的算法,用于信息搜索领域。当时信息搜索的做法是,事先对作为搜索对象的文本中包含的单词建立索引(index),如果索引与搜索关键字相同,就将该文本加入到搜索结果中。


但是这种方法有一个缺点:如果对搜索对象建立的索引与搜索关键字有一点点不同,那就无法很好地找到信息。假设有一篇索引中包含“车”的文章,在使用“汽车”这个搜索关键字搜索时,就会出现搜索结果中没有这篇文章的问题(同义性的问题)。虽然我们人类都知道“车”和“汽车”是含义基本上相同的单词,但是一个词一个词地教给计算机“这个单词和这个单词含义相似”的做法是不现实的。


而使用LSA就可以根据大量文本自动计算单词和单词的相似度,以及单词和文本的相似度。通过LSA对文本和单词的矩阵进行降维,将其变换为潜在语义空间(下图所示)。这种变换使用矩阵分解进行。矩阵分解是指将某个矩阵表示为多个矩阵的乘积的形式。矩阵分解是如何用于无监督学习的降维算法的呢?下面的“算法说明”部分将进行介绍。

在单词空间中,车和汽车都被当作正交维度处理,而在语义空间中,二者被表示为相似的单词。

二、算法说明

下面结合具体的例子来讲解矩阵分解和降维。
首先将以下文本变换为矩阵X。矩阵X的各元素是文本中出现的单词的个数(如表所示)。
·坐汽车去公司
·坐车去的
·在餐厅吃汉堡牛肉饼
·在餐厅吃意大利面

其中,U是包含单词和归纳的特征的变换信息的矩阵,D是包含信息的重要度的矩阵,V是包含归纳的特征和文本的变换信息的矩阵。另外,D是一个对角矩阵,(1, 1)、(2, 2)等对角线上的元素之外的元素都是0,对角元素按信息的重要度从大到小排列。在使用3个矩阵降维时,我们重点关注D。下面思考这样一个需求:原始数据有4个特征,但我们希望将其降维到2个特征。

 “汽车”和“车”拥有变量B的值,“汉堡牛肉饼”和“意大利面”拥有变量A的值。A和B的特征值显示了各个单词之间的关联性

三、示例代码

下面使用Python代码解决前面探讨的问题。假设有一个使用8个变量(= 单词的个数)表示的数据集,现在用2个潜在变量来表示它。

from sklearn.decomposition import TruncatedSVD
data =[[1, 0, 0, 0],
       [1, 0, 0, 0],
       [1, 1, 0, 0],
       [0, 1, 0, 0],
       [0, 0, 1, 1],
       [0, 0, 1, 0],
       [0, 0, 1, 1],
       [0, 0, 0, 1]]
n_components = 2  # 潜在变量的个数
model = TruncatedSVD(n_components=n_components)
model.fit(data)
print(model.transform(data))  # 变换后的数据
print(model.explained_variance_ratio_)  # 贡献率
print(sum(model.explained_variance_ratio_))  # 累计贡献率

另外,与PCA一样,我们也可以检查LSA变换后的矩阵中包含多少原始信息。使用了scikit-learn 的上述代码输出的累计贡献率约为0.67,表明这2个变量包含了约67%的原始数据的信息。

四、详细说明

使用LSA时的注意事项
“算法说明”部分提到的矩阵分解是一种叫作奇异值分解的技术。使用了奇异值分解的LSA在信息检索中的应用备受关注,它具有以新的空间表示文本等优点。但在实际使用中,需要注意一些问题。


一是变换后的矩阵有时难以解释。在通过奇异值分解降维时,各个维度可能是正交的,矩阵中的元素也可能是负值。因此,与之相比,还是后面即将介绍的NMF和LDA等算法的结果更容易解释。


二是LSA的计算成本有时很高。特别是在用于文本时,由于原始矩阵的维度就是单词的个数,所以LSA必须在非常大的矩阵上进行奇异值分解。

还有一个与计算成本有关的问题:随着新词的加入,原有的矩阵必须重新创建,我们必须在此基础上重新计算,所以模型的更新难度很大。

 

### LSA算法原理 潜在语义分析(Latent Semantic Analysis, LSA)是一种用于挖掘文本数据中隐藏模式的技术。其核心思想是从文档集合中提取出潜在的概念或主题,从而克服传统基于关键词匹配的方法所带来的局限性。LSA假设词语和概念之间并非一一对应的关系,而是通过一种复杂的映射关联在一起。 #### 文档-术语矩阵构建 LSA的第一步是创建一个文档-术语矩阵 \( X \),其中每一行代表一篇文档,每一列代表一个独特的词汇项。矩阵中的每个元素表示某个单词在某篇文档中的出现频率或其他权重形式(如TF-IDF)。这一过程可以通过以下方式完成: \[ X_{ij} = f(w_i, d_j) \] 这里 \( w_i \) 表示第i个词,\( d_j \) 表示第j篇文档,函数f可以根据具体需求定义为词频或者更高级的加权方案[^1]。 #### 奇异值分解(SVD) 一旦得到了文档-术语矩阵 \( X \),下一步就是对其进行奇异值分解(Singular Value Decomposition, SVD)。SVD将原始矩阵分解成三个部分: \[ X = U\Sigma V^T \] - \( U \): 左奇异向量构成的矩阵,反映的是文档空间内的主要方向。 - \( Σ \): 对角线上包含奇异值的矩阵,这些数值反映了各个维度的重要性程度。 - \( V^T \): 右奇异向量转置后的矩阵,体现的是词汇空间的主要趋势[^2]。 通过对上述三者的选择性保留,可以达到降低维度的目的,即只选取前k个最大奇异值及其对应的左、右奇异向量形成新的低秩近似矩阵。此操作不仅减少了存储开销还可能增强泛化能力[^3]。 #### 新坐标系的理解 从几何角度来看,SVD实际上完成了这样一个任务——把原本杂乱无章的数据点投射到一个新的正交基底上,在那里它们能够更好地分离并展示内在结构。正如参考资料里提到,“SVD的作用就相当于是一个坐标系变换的过程”,它使得原来可能存在冗余甚至噪声干扰的信息变得清晰有序[^4]。 ### Python 实现代码 下面给出一段简单的Python代码用来演示如何利用Scikit-Learn库执行LSA流程: ```python from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.decomposition import TruncatedSVD import numpy as np def perform_lsa(corpus, n_components=2): vectorizer = TfidfVectorizer(stop_words='english') dt_matrix = vectorizer.fit_transform(corpus) svd_model = TruncatedSVD(n_components=n_components, algorithm='randomized', n_iter=100, random_state=42) lsa_result = svd_model.fit_transform(dt_matrix) explained_variance_ratio = svd_model.explained_variance_ratio_ return lsa_result, explained_variance_ratio corpus = [ 'The sky is blue.', 'The sun is bright today.', 'The sun in the sky is very bright.' ] lsa_results, variance_ratios = perform_lsa(corpus, n_components=2) print("LSA Results:\n", lsa_results) print("Explained Variance Ratios:", variance_ratios) ``` 这段脚本首先使用`TfidfVectorizer`类生成TF-IDF加权的稀疏矩阵;接着调用`TruncatedSVD`对象来进行截断版的SVD运算以获取指定数量的新特征组合结果以及各成分解释总变异的比例情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿梭的编织者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值