如何使用LSI实现单语言查询下的英西双语检索功能
基于LSI的英西双语检索实现方案
核心原理
普通单语LSI只能识别同一种语言的语义关联,要实现跨语检索,核心是通过已有的翻译对照表+同源词,先把两种语言的同义词汇映射到同一个特征维度,再进行LSI隐空间训练,让同一语义的英西文档在隐空间中的向量距离接近,最终实现单语查询匹配双语内容。
分步实现逻辑
- 语料预处理与跨语映射构建
对所有英文、西班牙语文档分别做分词、去停用词、词形还原处理。将独立翻译对照表和同源词列表合并为双向跨语对齐映射表,每一个词都能映射到它的跨语同义词和自身。 - 构造跨语对齐的词袋矩阵
把每个文档中的所有词汇替换为对齐后的统一特征标识(比如统一用英文词作为特征键,没有对应翻译的词汇保留原词作为独立特征),再基于统一的特征集合生成所有文档的TF-IDF矩阵。 - LSI隐空间训练
对TF-IDF矩阵做截断SVD分解,保留预设维度的隐语义分量,得到所有文档在统一隐空间的归一化向量表示。 - 跨语查询检索
输入单语查询词后,执行和文档一致的预处理、对齐映射操作,转换为TF-IDF向量后映射到隐空间,和所有文档的隐空间向量计算余弦相似度,取相似度最高的前N条作为检索结果。
注意:如果双语语料规模足够大,同源词会在SVD分解过程中自动被映射到隐空间的相近位置,即使不做显式对齐也能得到基础的跨语检索效果,加入翻译对照表主要是为了大幅提升非同源同义词的检索准确率
伪代码示例
import numpy as np from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.decomposition import TruncatedSVD # 输入参数定义 bilingual_docs = [("en", "English document content"), ("es", "Contenido del documento en español"), ...] translation_dict = {"doctor": "médico", "casa": "house", ...} # 双向翻译映射 homograph_list = ["actor", "hospital", "general", ...] # 英西同形同源词 query = "medical staff" # 可输入任意一种语言的查询 query_lang = "en" top_n_result = 10 svd_latent_dim = 300 # 隐空间维度,可根据语料规模调整 # 1. 文本预处理函数:分词、去停用词、词形还原 def preprocess_text(text: str, lang: str) -> list: # 按对应语言执行预处理逻辑,返回清洗后的token列表 return processed_tokens # 2. 构建双向跨语对齐映射 cross_lang_align = {} # 加入翻译对照表的双向映射 for word_a, word_b in translation_dict.items(): cross_lang_align[word_a] = cross_lang_align.get(word_a, set()) | {word_b} cross_lang_align[word_b] = cross_lang_align.get(word_b, set()) | {word_a} # 加入同源词的自映射 for homo_word in homograph_list: cross_lang_align[homo_word] = cross_lang_align.get(homo_word, set()) | {homo_word} # 3. 生成所有文档的对齐后token与统一特征集 unified_features = set() processed_doc_tokens = [] for lang, content in bilingual_docs: tokens = preprocess_text(content, lang) aligned_tokens = [] for token in tokens: if token in cross_lang_align: # 取排序后的首个词作为统一特征键,保证同义跨语词映射到同一个特征 unified_key = sorted(list(cross_lang_align[token] | {token}))[0] aligned_tokens.append(unified_key) unified_features.add(unified_key) else: # 无对齐映射的词保留原词作为独立特征 aligned_tokens.append(token) unified_features.add(token) processed_doc_tokens.append(" ".join(aligned_tokens)) # 4. 训练LSI模型得到文档隐向量 vectorizer = TfidfVectorizer(vocabulary=list(unified_features)) tfidf_matrix = vectorizer.fit_transform(processed_doc_tokens) svd_model = TruncatedSVD(n_components=svd_latent_dim, random_state=42) doc_latent_vectors = svd_model.fit_transform(tfidf_matrix) # 归一化文档向量,方便后续余弦相似度计算 doc_latent_vectors = doc_latent_vectors / np.linalg.norm(doc_latent_vectors, axis=1, keepdims=True) # 5. 检索函数 def cross_lang_retrieve(query: str, query_lang: str) -> list: # 预处理查询词 q_tokens = preprocess_text(query, query_lang) # 对齐查询词 q_aligned = [] for t in q_tokens: if t in cross_lang_align: unified_key = sorted(list(cross_lang_align[t] | {t}))[0] q_aligned.append(unified_key) else: q_aligned.append(t) # 转换为TF-IDF并映射到隐空间 q_tfidf = vectorizer.transform([" ".join(q_aligned)]) q_latent = svd_model.transform(q_tfidf) q_latent = q_latent / np.linalg.norm(q_latent) # 计算余弦相似度 similarity_scores = np.dot(doc_latent_vectors, q_latent.T).flatten() # 取Top N结果 top_indices = similarity_scores.argsort()[-top_n_result:][::-1] return [(bilingual_docs[idx], similarity_scores[idx]) for idx in top_indices] # 调用示例 results = cross_lang_retrieve(query, query_lang)
内容的提问来源于stack exchange,提问作者Dor Cohen
相关产品推荐
相关产品推荐

