什么是潜在语义索引(LSI)以及它是如何工作的?
了解 LSI 的内部工作原理,查看实际的 Python 实现,并发现为什么这种基础技术在当今人工智能驱动的搜索领域仍然具有相关性。

潜在语义索引 (LSI) 是一种数学文档理解和检索方法。LSI 通常用于搜索引擎、电子商务、网站搜索以及其他需要搜索功能的应用程序。
本文全面概述了 LSI。具体而言,它回答了以下问题:
- 什么是 LSI,它如何工作?
- LSI 有哪些好处,以及它用于何处?
- 如何在 Python 中实现 LSI?(我们提供分步解释)
- LSI 的一些现代替代方案是什么?
那么,让我们直奔主题。
什么是潜在语义索引 (LSI)?
LSI 是一种信息检索方法,用于自然语言处理 (NLP) 中,以揭示文本主体中单词和概念之间的潜在(隐藏)关系。
与传统的基于关键词的方法不同,LSI 是一种语义搜索类型,它分析文档中术语之间的语义关系,以提取隐藏的概念并根据这些概念对文档进行分组。
LSI 使用奇异值分解 (SVD) 将复杂的、高维数据分解为更小的、隐藏的概念。这有助于识别单词和文档之间关系中的模式。LSI 解决了同义词和反义词的挑战,并将具有相同含义的单词投射到相似的更高维度中。
例如,相关术语“医生”和“内科医生”将被放置在 LSI 高维图中的更近位置,反映相同的概念。当用户搜索文档时,查询被投射到高维空间中,并返回最相关的文档。
LSI 是文档理解和检索的基础技术之一。由于其简单且计算成本较低的性质,它仍然被广泛使用。
现在您已经了解了什么是 LSI,让我们看看它如何工作。
潜在语义索引如何工作?
LSI 采用 SVD,这是一种数学技术,它将词-文档矩阵分解为更小的矩阵,捕获文档中词和概念之间的潜在关系。
下图演示了 LSI 的工作流程。
让我们通过示例讨论以上步骤:
步骤 1:导入数据集
第一步是创建一组要应用 LSI 的文档。
假设您有以下四个文档:
文档 1 | 猫和狗是可爱的宠物。 |
---|---|
文档 2 | 狗是忠诚的宠物。 |
文档 3 | 宠物带来欢乐和幸福。 |
文档 4 | 幸福和欢乐赋予生命意义。 |
步骤 2:预处理文档
文本文档可能包含对文档含义或概念没有贡献的停用词。在预处理中,您可以删除停用词,将文本转换为小写,并删除其他无用信息。
预处理后,我们的文档可能如下所示:
文档 1 | 猫狗可爱的宠物。 |
---|---|
文档 2 | 狗忠诚的宠物 |
文档 3 | 宠物带来欢乐幸福 |
文档 4 | 幸福欢乐带来生命意义。 |
步骤 3:创建词-文档矩阵
在创建词-文档矩阵之前,您需要为所有文档创建一组唯一的单词。这组词通常被称为词汇表。我们样本数据集中的文档词汇表如下所示:
PATCH /network ['bring', 'cats', 'dogs', 'happiness', 'joy', 'life', 'loyal', 'meaning', 'pets' 'wonderful']
下一步是创建一个形状为 N x M 的词-文档矩阵,其中 N 是文档数量,M 是词汇表大小。矩阵中的每一行对应于单词在文档中出现的频率。该矩阵捕获文档中单词共现的模式,这对于识别潜在概念至关重要。
我们数据集的词-文档矩阵如下所示:
步骤 4:奇异值分解
SVD 算法将矩阵分解为更小的矩阵。在 LSI 中,SVD 将词-文档矩阵 A 分解为三个矩阵:A=UΣVT
- 矩阵 U:将文档与潜在概念关联起来。它也称为文档-概念相似度矩阵。该矩阵显示文档与特定概念的关联程度。
- 矩阵 Σ:一个对角矩阵,其奇异值表示每个概念的强度。
- VT:将术语与潜在概念关联起来,通常称为术语-概念相似度矩阵。它显示一个术语与特定概念的关联程度。
我在此不会深入探讨 SVD 的数学细节。然而,我们数据集中两个概念的三个检索到的矩阵如下所示。
步骤 5:分析 LSI 矩阵
重要的是要注意,LSI 中不会自动生成概念名称。相反,您必须查看分组的文档或术语并推断概念。
例如,您可以看到文档 1 和文档 2 属于概念 2,因为它们在文档-概念相似度矩阵中第二列的值更高。同样,文档 3 和文档 4 属于概念 1。
文档 1 和 2 提及动物和宠物。文档 3 和 4 更多地是关于幸福和快乐。因此,我们可以将这两个概念命名为:宠物动物和生活与幸福。这使得 LSI 能够检索最相关内容的文档,即使精确的术语不匹配。
您将在后面的部分中看到上述示例的完整 Python 应用程序;现在,让我们看看 LSI 的一些用途和好处。
潜在语义索引用于何处?
最新的语义索引用于各种 NLP 领域,包括文本摘要、自动文档分类、在线客户支持和垃圾邮件过滤。
以下是一些 LSI 派上用场的用例:
- 搜索引擎:LSI 语义分析用户查询和文档,以提高搜索引擎性能。这有助于搜索引擎理解用户的搜索意图并检索更相关的网页和相关搜索。
- 自动文档分类:LSI 搜索算法有效地将文档分类到预定义的类别中。它们通常用于无监督情感分类、电子邮件分类和其他目的。
- 在线客户支持:与搜索引擎一样,LSI 可以在客户管理系统中将搜索者的查询与相关解决方案进行匹配。
- 垃圾邮件过滤:LSI 根据语义内容检测和过滤垃圾邮件。
- 信息可视化:通过 LSI 生成的文档集群可以在低维空间中绘制,以查看文档之间的关系。
现在我们已经了解了 LSI 的一些用途,接下来讨论它的优点。
潜在语义索引有哪些优势?
LSI 的主要优点如下:
- 基于概念的聚类:LSI 将相关文档分组在一起,使组织和分析大型数据集更容易。
- 处理同义词和多义词:LSI 可以有效地处理同义词。例如,“汽车”和“机动车”这两个词将具有相似的语义表示。
- 可扩展性:LSI 是一种利用高计算能力高效扩展的数学技术,使其成为电子发现和企业搜索系统等应用的理想选择。
- 抗错能力强:LSI 依赖于语义含义,因此对拼写错误不那么敏感,从而改善了搜索和检索系统中的用户体验。
- 跨领域的多功能性:应用于搜索引擎、教育、金融等领域。
以下部分显示了 LSI 和潜在语义分析之间的主要区别。
LSI 和 LSA 有何区别?
LSI 和潜在语义分析 (LSA) 经常互换使用。这两种技术的核心都使用 SVD。但是,它们的应用和侧重点略有不同。
LSI 最初是一种信息检索和搜索技术,旨在解决文档的语义理解和同义词等挑战。LSI 的主要应用是根据用户的搜索查询检索语义相似的文档。
另一方面,潜在语义分析超越了信息检索,专注于其他 NLP 任务,例如语音识别、文档聚类和分类以及认知建模。
让我们看看如何在 Python 中实现 LSI。
在 Python 中实现潜在语义索引
本节将通过一个实际示例演示如何在 Python 中实现 LSI 算法。
安装和导入所需的库
我们将使用 Python Scikit Learn 库和 NLTK 工具包在 Python 中实现 LSI。以下脚本安装这些库。
PATCH /network !pip install -qU scikit-learn nltk pandas
以下脚本导入运行本文中提到的 Python 脚本所需的模块和类。
PATCH /network import numpy as np from sklearn.feature_extraction.text import CountVectorizer from sklearn.decomposition import TruncatedSVD from sklearn.metrics.pairwise import cosine_similarity from nltk.corpus import stopwords from nltk.tokenize import word_tokenize import nltk import matplotlib.pyplot as plt import pandas as pd nltk.download('stopwords') nltk.download('punkt') nltk.download('punkt_tab')
让我们一步一步地实现 LSI。值得一提的是,这些是您在前面解释 LSI 工作原理的部分中看到的步骤。在这里,它们在 Python 中实现。
步骤 1:导入文档
第一步是收集您要实施 LSI 的文档。这些可以是您的个人、业务或客户文档。
本节将使用一个包含四个虚拟文档的小数据集,每个文档包含一个句子。
PATCH /network # Example documents documents = [ "Cats and dogs are wonderful pets.", "Dogs are loyal pets.", "Pets bring joy and happiness.", "Happiness and joy bring meaning to life." ]
步骤 2:预处理文档
在预处理步骤中,我们将从文档中删除停用词和标点符号,如以下脚本所示:
PATCH /network # Preprocessing: Tokenization and stopword removal stop_words = set(stopwords.words('english')) def preprocess(doc): words = word_tokenize(doc.lower()) return ' '.join([word for word in words if word.isalnum() and word not in stop_words]) processed_docs = [preprocess(doc) for doc in documents] processed_docs
输出
步骤 3:创建词-文档矩阵
您可以使用 Sklearn 库中 CountVectorizer()
类的 fit_transform()
方法创建词-文档矩阵。您可以使用 get_feature_names_out()
方法检索文档词汇表。
PATCH /network vectorizer = CountVectorizer() term_document_matrix = vectorizer.fit_transform(processed_docs) feature_names = vectorizer.get_feature_names_out() print(feature_names) term_document_array = term_document_matrix.toarray() df_term_document = pd.DataFrame(term_document_array, columns=feature_names, index=[f"Doc {i+1}" for i in range(len(term_document_array))]) print(df_term_document)
输出
以上输出显示了文档的词汇表(唯一词列表)和词-文档矩阵,演示了每个文档的词频。
步骤 4:应用奇异值分解
您可以使用 Sklearn 库中的 TrancatedSVD
类来实现 SVD。您必须传递要从文档中提取的概念数量。
在下面的脚本中,我们提取了两个概念。输出显示了概念强度矩阵、文档-概念相似度矩阵和术语-概念相似度矩阵。概念强度矩阵显示概念 1 在文档中略微更占主导地位。
PATCH /network svd = TruncatedSVD(n_components=2, random_state=42) lsi_matrix = svd.fit_transform(term_document_matrix) # Display Results print(" Singular Values (Concept Strength): ", svd.singular_values_) print(" Document-Concept Similarity Matrix: ", lsi_matrix) print(" Term-Concept Similarity Matrix: ", svd.components_.T)
我们将在下一步分析文档-概念和术语-概念相似度矩阵。
步骤 5:分析 LSI 矩阵
让我们绘制一个 2D 图,在概念轴上显示文档。
PATCH /network # Extract values for Concept 1 (x-axis) and Concept 2 (y-axis) x = lsi_matrix[:, 0] # Values for Concept 1 y = lsi_matrix[:, 1] # Values for Concept 2 # Create a scatter plot plt.figure(figsize=(8, 6)) plt.scatter(x, y, color='blue', label='Documents') # Annotate each document for i, (x_val, y_val) in enumerate(zip(x, y)): plt.text(x_val + 0.02, y_val, f'Doc {i+1}', fontsize=9) # Add gridlines, labels, and title plt.axhline(0, color='gray', linestyle='--', linewidth=0.5) plt.axvline(0, color='gray', linestyle='--', linewidth=0.5) plt.title("Document-Concept Similarity") plt.xlabel("Concept 1") plt.ylabel("Concept 2") plt.grid() plt.legend() plt.show()
输出
输出显示文档 1 和 2 主要属于概念 2,而文档 3 和 4 属于概念 1。
为了了解每个概念中的信息,您可以绘制每个概念的术语。
PATCH /network terms = vectorizer.get_feature_names_out() concept1_weights = svd.components_[0] concept2_weights = svd.components_[1] fig, ax = plt.subplots(1, 2, figsize=(12, 6)) ax[0].barh(terms, concept1_weights, color='orange') ax[0].set_title("Term Weights for Concept 1") ax[0].set_xlabel("Weight") ax[1].barh(terms, concept2_weights, color='green') ax[1].set_title("Term Weights for Concept 2") ax[1].set_xlabel("Weight") plt.tight_layout() plt.show()
输出
上述输出显示,“宠物”、“快乐”、“幸福”、“带来”等相关关键词主要属于概念 1,该概念与生活和情感有关。
另一方面,“宠物”、“美好”、“猫”、“狗”等词语主要属于概念 2。我们可以推断出概念 2 是关于宠物和动物的。
现在您知道为什么文档 1 和 2 属于概念 2,而文档 3 和 4 属于概念 1 了。
就是这样。您已经使用自己的自定义文档开发了第一个 LSI 模型。
在下一步中,您将学习如何使用 LSI 针对用户查询检索相关搜索结果。
搜索和检索
您需要像预处理 LSA 文档一样预处理查询。
PATCH /network user_query = "Joyful pets bring happiness to life." # Example query preprocessed_query = preprocess(user_query) # Preprocess query print("Preprocessed Query:", preprocessed_query)
输出
接下来,使用您用于创建文档-概念和术语-概念相似度矩阵的 SVD 模型,将查询嵌入到 LSI 空间中。
然后,您可以使用余弦相似度或任何其他向量相似度函数,找到 LSI 空间中查询和文档之间的相似度。
PATCH /network query_vector = vectorizer.transform([preprocessed_query]) # Transform query to term-document matrix query_lsi = svd.transform(query_vector) # Map query to LSI latent space print(" Query in LSI Space (Concepts): ", query_lsi) # Use cosine similarity between the query and document vectors similarities = cosine_similarity(query_lsi, lsi_matrix) print(" Similarity Scores: ", similarities)
输出
最后,您可以根据文档与输入查询的相关性来检索和排序文档。在这种情况下,余弦相似度将作为检索文档的排序因子。
PATCH /network # Rank documents by similarity doc_indices = np.argsort(similarities[0])[::-1] # Sort by descending similarity print(" Ranked Document Indices (Most Relevant First):", doc_indices) # Output relevant documents print(" Top Relevant Documents:") for idx in doc_indices: print(f"Doc {idx + 1}: {documents[idx]} (Similarity: {similarities[0][idx]:.3f})")
输出
输出显示了针对输入查询的文档搜索排名。文档 3 与查询中的搜索词最相关,这是有道理的,因为它讨论了宠物和幸福。
现在,让我们看看 LSI 是否仍然重要。
潜在语义索引是否仍然重要?
LSI 易于实现且计算成本不高。这就是为什么在实现不需要深入理解词语和概念之间关系的简单文档理解和检索解决方案时,它仍然被使用。
然而,已经开发出更新的方法,以实现对文档更高级的理解。这些方法包括向量搜索、词嵌入以及基于机器学习和深度学习技术的变换器方法。这些方法在几乎所有基准上都优于 LSI。
Meilisearch 是一款先进的 AI 搜索引擎,它利用尖端的向量搜索方法,将最先进的搜索引擎功能集成到您的应用程序中。它实现了基于词嵌入和向量搜索的语义搜索技术,可以更深入地理解文档中的关系和概念,从而提高检索文档的相关性和鲁棒性。
Meilisearch 的 AI 搜索引擎可以无缝集成到电子商务、网站、应用程序搜索以及任何涉及搜索项目或文档的其他应用程序中。
总结
LSI 是搜索和检索应用程序的基础技术。它易于实现,并且计算成本低于基于深度学习的先进技术。然而,它在可扩展性、实时相关性和多语言理解方面存在问题。
但随着向量搜索和高级词嵌入的出现,Meilisearch 等工具正在重新定义文档理解和检索的可能性。Meilisearch 为文档搜索提供最先进的功能:
- 极速性能:在 50 毫秒内提供搜索结果,带来流畅的用户体验。
- 边输边搜:在用户输入时提供实时结果和即时反馈。
- 容错性:即使查询中存在拼写错误或打字错误,也能确保相关结果。
- 全面的语言支持:针对多种语言进行优化,包括拉丁语、中文、日语和希伯来语。
- 分面搜索和过滤:通过类别和过滤器实现直观导航。
- 自定义排名和相关性:允许定制排名和相关性规则,以获得精确的搜索结果。
- AI 就绪集成:与 AI 模型无缝协作,实现混合语义和全文搜索功能。