1. TF-IDF
1.1 原理
1.1.1 名词解释
TF:词频,某token在文档中出现的次数越多,则这个token的特征越能代表这篇文档自身的独特特征。 计算:token出现次数 / 文档总token数
IDF:逆文档频率,如果某个token在所有文档中都出现,那么这个token对于区分这些文档的特征最没有帮助。计算:1 + log(总文档数量/包含token的文档数量)
score = tf * idf,以此作为token字典中,每个token在每个文档中的分数计算公式。
1.1.2 TF-IDF的工作过程
1)根据输入的多个文档/语料,构建词汇表
2)遍历每个文档,计算词表中每个token在文档中出现的次数
3)计算每个文档的每个词在平滑后的 TF-IDF 值
4)对每个文档的 TF-IDF向量 进行L2标准化(方便求余弦距离)
1.1.3 通过TF-IDF方法实现信息检索的理解
tf-idf形成的token矩阵,本质是对所有文档的一种组织方法,也是一种embedding词嵌入方法。通过一个包含所有文档token的字典和score,构建每个文档的特征向量。当一个用户问题传过来之后,就可以通过同样的字典和score计算方法,构建一个新的向量,然后对用户问题生成的向量,依次遍历语料库中每个文档向量的余弦相似度。
1.2 实现
1.2.1 TF-IDF 文献检索代码实现
from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity # 示例文档集合 documents = [ "The quick brown fox jumps over the lazy dog.", "Never jump over the lazy dog quickly.", "The dog is quick and jumps over brown foxes." ] # 用户的查询问题 query = "quick brown fox" # 初始化TfidfVectorizer vectorizer = TfidfVectorizer() # 将文档集合转换为TF-IDF矩阵 tfidf_matrix = vectorizer.fit_transform(documents) # 将查询转换为TF-IDF向量 query_vector = vectorizer.transform([query]) print(query_vector) # 计算查询与每个文档之间的余弦相似度 cosine_similarities = cosine_similarity(query_vector, tfidf_matrix).flatten() # 打印每个文档的相似度得分 for i, score in enumerate(cosine_similarities): print(f"Document {i+1} similarity score: {score}") # 找到最相似的文档 most_similar_doc_index = cosine_similarities.argmax() print(f"Most similar document: Document {most_similar_doc_index + 1}")
1.2.2 TF-IDF的API参数理解
import jieba from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity """ TfidfVectorizer的Api参数 - 文档处理相关: 1. preprocessor:对传入的文档列表逐个进行预处理。(传入的文本必须是按照空格分隔完毕的,否则就要通过preprocessor预处理一下) 2. analyzer:preprocess之后,对每个文档的文本 按照单个字/词 切分。可选参数: 'char', 'word' 3. lowercase:默认True,将文本转换为小写(英文文本) 4. input:content、filename。然后 model.fit() 的时候,可以直接传入 文本内容列表、文件路径字符串列表 TfidfVectorizer的Api参数 - 词汇表构建相关: 1. token_pattern:对空格分隔的文档内容过滤,只有符合pattern格式的单词才可以放入词汇表。 2. ngram_range: 将连续的token组合为一个token 3. max_df=0.8: token出现的文档数 / 总文档数 的最大值 (有10个文档,构建词表时,选用的token最多出现在8个文档中。即:这个token在每个文档中都有就没意义了) 4. min_df: token出现的文档数 / 总文档数 的最小值 5. max_features:词汇表的最大token数量 6. vocabulary: 可以传入自定义词表 7. stop_words: 停用词,可以github搜一下别人的 TfidfVectorizer的Api参数 - 计算相关(直接用默认值,不要改): 1. norm: 文档向量标准化 2. use_idf:tf * idf,idf是否需要计算真实值,还是直接置为1 3. smooth_idf:是否进行 idf 平滑 4. sublinear_tf:计算tf时,直接用原始定义,还是加log对数化 """ # 语料库 corpus = [ '经济学是一门对产品和服务的生产、分配以及消费进行研究的社会科学。西方语言中的“经济学”一词源于古希腊的。', '经济学注重的是研究经济行为者在一个经济体系下的行为,以及他们彼此之间的互动。', '其他的对照还包括了经济理论与实用经济学、行为经济学与理性选择经济学、主流经济学与非主流经济学。' ] def preprocess(text): words = jieba.lcut(text) return " ".join(words) # 创建 TF-IDF 向量化实例 vectorizer = TfidfVectorizer() # vectorizer1 = TfidfVectorizer(preprocessor=preprocess, input='content') # 拟合并转换文本数据 tfidf_matrix = vectorizer.fit_transform(corpus) # 打印 词汇表 print("Feature names:", vectorizer.get_feature_names_out()) # 打印 TF-IDF 矩阵 print(tfidf_matrix) # 稀疏矩阵表示 print(tfidf_matrix.toarray()) # 稀疏矩阵表达 还原 原始矩阵
2. BM25
2.1 原理
BM25实际是对 TF-IDF 的改进优化,优化点如下:
1)文档长度归一化:引入参数b。tf-idf算法倾向于有长文档打出高分,bm25对文档长度做归一化。
2)控制词频饱和效应:引入参数 k1。bm25能够控制词频的影响,使得某个词语在文档中频繁出现不会无限制的提高文档的得分。
3)可调参数,可以调节引入的参数 b和k1,以获得更好的效果。
2.2 实现
# !pip install rank_bm25 from rank_bm25 import BM25Okapi corpus = [ "Hello there good man!", "It is quite windy in London", "How is the weather today?" ] tokenized_corpus = [doc.split(" ") for doc in corpus] bm25 = BM25Okapi(tokenized_corpus) # <rank_bm25.BM25Okapi at 0x1047881d0> query = "windy London" tokenized_query = query.split(" ") doc_scores = bm25.get_scores(tokenized_query) # array([0. , 0.93729472, 0. ]) res = bm25.get_top_n(tokenized_query, corpus, n=1) # ['It is quite windy in London']
标签:1.14,BM25,TF,token,TfidfVectorizer,文档,IDF,query From: https://www.cnblogs.com/zhangzhenw/p/18350650