相似性搜索(2)

news/2025/2/25 5:57:46

在本篇中,我们通过播客相似性搜索为例,进一步研究基于chroma 的相似性搜索:

参考:

https://www.kaggle.com/code/switkowski/building-a-podcast-recommendation-engine/notebook

数据集来源:

https://www.kaggle.com/code/switkowski/building-a-podcast-recommendation-engine/input

数据的预处理 

import pandas as pd 
#print(os.listdir("./input"))
from IPython.core.interactiveshell import InteractiveShell
def preprocessor(file):
    InteractiveShell.ast_node_interactivity = "all"
    podcasts = pd.read_csv('./input/podcasts.csv')
    podcasts = podcasts[podcasts.language == 'English']#选择英语的项目
    podcasts = podcasts.dropna(subset=['description'])#删除缺失 description 的项目
    podcasts = podcasts.drop_duplicates('itunes_id')#删除重复的itunes_id
    sum(podcasts.description.isnull())
    podcasts['description_length'] = [len(x.description.split()) for _, x in podcasts.iterrows()]
    #podcasts['description_length'].describe()#显示description_length的统计摘要
    podcasts = podcasts[podcasts.description_length >= 20]#选择长度>20的项目
    podcasts = podcasts[0:10].reset_index(drop=True)#选择前10个项目,并且重新index 编号,不连续的index 变成连续 
    return podcasts
new_list=preprocessor('./input/podcasts.csv')
for index,row in new_list.iterrows():
    print("index:",index)
    print (row["description"])

搜索

#https://www.kaggle.com/code/switkowski/building-a-podcast-recommendation-engine?select=episodes.csv
#https://www.aicrowd.com/challenges/spotify-million-playlist-dataset-challenge#task
import pandas as pd 
import os

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import linear_kernel
print(os.listdir("./input"))

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
podcasts = pd.read_csv('./input/podcasts.csv')
podcasts = podcasts[podcasts.language == 'English']
podcasts = podcasts.dropna(subset=['description'])
podcasts = podcasts.drop_duplicates('itunes_id')
sum(podcasts.description.isnull())
podcasts['description_length'] = [len(x.description.split()) for _, x in podcasts.iterrows()]
podcasts['description_length'].describe()
podcasts = podcasts[podcasts.description_length >= 20]
favorite_podcasts = ['The MFCEO Project', 'Up and Vanished', 'Lore']
favorites = podcasts[podcasts.title.isin(favorite_podcasts)]
favorites
podcasts = podcasts[~podcasts.isin(favorites)].sample(15000)
data = pd.concat([podcasts, favorites], sort = True).reset_index(drop = True)
tf = TfidfVectorizer(analyzer = 'word', ngram_range = (1, 3), min_df = 0, stop_words = "english")
tf_idf = tf.fit_transform(data['description'])
tf_idf
similarity = linear_kernel(tf_idf, tf_idf)
similarity
x = data[data.title == 'Up and Vanished'].index[0]
similar_idx = similarity[x].argsort(axis = 0)[-4:-1]
for i in similar_idx:
    print(similarity[x][i], '-', data.title[i], '-', data.description[i], '\n')
print('Original - ' + data.description[x])
x = data[data.title == 'Lore'].index[0]
similar_idx = similarity[x].argsort(axis = 0)[-4:-1]
for i in similar_idx:
    print(similarity[x][i], '-', data.title[i], '-', data.description[i], '\n')
print('Original - ' + data.description[x])

使用TfidfVectorizer将选出来的播客的描述矢量化。

使用linear_kernel 找出两两之间播客描述的相似性。

找出与“Up and Vanished” ,“Lore”相似的播客

        倒数第4个到倒数第1个。

        similar_idx = similarity[x].argsort(axis = 0)[-4:-1]

 将结果打印出来

for i in similar_idx:
    print(similarity[x][i], '-', data.title[i], '-', data.description[i], '\n')

将 “Up and Vanished” ,“Lore”的标题和描述打印出来。

DeepSeek 的解释笔记

TfidfVectorizer

TfidfVectorizer 是 自然语言处理(NLP) 中常用的工具,用于将文本数据转换为数值特征向量。它是 scikit-learn 库中的一个类,结合了 TF(词频,Term Frequency) 和 IDF(逆文档频率,Inverse Document Frequency) 两种统计方法,能够有效地表示文本数据并捕捉其重要特征。

TfidfVectorizer 的主要参数

以下是 TfidfVectorizer 的一些常用参数:

  • input: 输入类型,可以是文件名、文件对象或文本内容(默认是 content)。

  • encoding: 文本编码方式(默认是 utf-8)。

  • lowercase: 是否将文本转换为小写(默认是 True)。

  • stop_words: 是否移除停用词(如“的”、“是”等),可以设置为 'english' 或自定义列表。

  • max_df: 忽略在超过一定比例的文档中出现的单词(用于去除常见词)。

  • min_df: 忽略在少于一定数量的文档中出现的单词(用于去除罕见词)。

  • ngram_range: 指定 n-gram 的范围,例如 (1, 1) 表示只使用单词,(1, 2) 表示使用单词和二元词组。

  • max_features: 限制特征向量的最大维度(即最多保留多少个单词)。

使用示例

以下是一个简单的示例,展示如何使用 TfidfVectorizer 将文本数据转换为 TF-IDF 特征矩阵:

from sklearn.feature_extraction.text import TfidfVectorizer

# 示例文本数据
documents = [
    "我喜欢机器学习",
    "机器学习很有趣",
    "自然语言处理是机器学习的一个分支"
]

# 初始化 TfidfVectorizer
vectorizer = TfidfVectorizer()

# 拟合并转换文本数据
tfidf_matrix = vectorizer.fit_transform(documents)

# 查看结果
print("TF-IDF 特征矩阵:")
print(tfidf_matrix.toarray())  # 转换为稠密矩阵并打印

print("\n词汇表:")
print(vectorizer.get_feature_names_out())  # 打印词汇表

输出结果

TF-IDF 特征矩阵:
[[0.         0.         0.70710678 0.70710678 0.         0.        ]
 [0.57735027 0.57735027 0.         0.         0.57735027 0.        ]
 [0.         0.         0.         0.         0.40824829 0.81649658]]

词汇表:
['一个' '分支' '喜欢' '很有趣' '是' '机器学习']

 

  • TF-IDF 特征矩阵:每一行对应一个文档,每一列对应一个单词,值是该单词的 TF-IDF 权重。

  • 词汇表:列出了所有被提取的单词。


应用场景

  1. 文本分类
    将文本转换为 TF-IDF 特征后,可以用于训练分类模型(如朴素贝叶斯、支持向量机等)。

  2. 信息检索
    计算查询词与文档的 TF-IDF 相似性,用于搜索引擎排名。

  3. 文本聚类
    使用 TF-IDF 特征对文本进行聚类分析。

  4. 推荐系统
    计算用户评论或商品描述的 TF-IDF 特征,用于推荐相似商品。


优点

  1. 简单高效:能够快速将文本数据转换为数值特征。

  2. 捕捉关键词:通过 TF-IDF 权重,能够突出文档中的重要单词。

  3. 降噪:通过移除停用词和低频词,减少噪声。


局限性

  1. 无法捕捉语义:TF-IDF 只考虑词频和文档频率,无法理解单词的语义。

  2. 稀疏性问题:对于大规模语料库,TF-IDF 矩阵可能会非常稀疏,导致计算效率下降。

  3. 依赖预处理:需要配合分词、去停用词等预处理步骤才能发挥最佳效果。


总结

TfidfVectorizer 是一个强大的工具,能够将文本数据转换为数值特征,适用于文本分类、聚类、信息检索等任务。它是 NLP 中常用的特征提取方法之一,尤其适合处理中小规模的文本数据。如果需要捕捉语义信息,可以结合词嵌入(如 Word2Vec、BERT)等方法使用。

开启新对话

linear_kernel 

linear_kernel 的主要用途是计算两个向量或矩阵之间的线性核(Linear Kernel),也就是它们的点积(dot product)。它在机器学习和数据科学中常用于衡量样本之间的相似性,尤其是在使用核方法(Kernel Methods)或支持向量机(SVM)时。 

假设我们有以下两个矩阵 XX 和 YY,分别表示两组样本的特征向量:

python
复制
import numpy as np
from sklearn.metrics.pairwise import linear_kernel

# 样本特征矩阵
X = np.array([[1, 2, 3], [4, 5, 6]])  # 2个样本,每个样本有3个特征
Y = np.array([[7, 8, 9], [10, 11, 12]])  # 2个样本,每个样本有3个特征

# 计算线性核
kernel_matrix = linear_kernel(X, Y)
print(kernel_matrix)

输出结果:

[[ 50  68]
 [122 167]]

这里的输出是一个相似性矩阵,其中每个元素 (i,j)(i,j) 表示 XX 中第 ii 个样本与 YY 中第 jj 个样本的点积(即线性核值)。


优点

  1. 简单高效
    线性核的计算非常简单,只需要计算点积,因此计算速度快。

  2. 适合线性可分数据
    如果数据本身是线性可分的,线性核可以直接用于分类或回归任务。

  3. 可解释性强
    线性核的结果易于解释,因为它直接反映了样本在特征空间中的方向相似性。


局限性

  1. 不适合非线性数据
    如果数据是非线性可分的,线性核可能无法捕捉复杂的模式。此时可以使用其他核函数,如 RBF 核(高斯核)或多项式核。

  2. 表达能力有限
    线性核只能捕捉线性关系,无法处理更复杂的特征交互。


总结

   linear_kernel 是一个简单但非常有用的工具,主要用于计算样本之间的线性相似性。它在支持向量机、文本分类、推荐系统等任务中都有广泛应用。如果你的数据是线性可分的,或者你需要一个高效的相似性度量方法,linear_kernel 是一个很好的选择。

结论

    DeepSeek 对于程序猿学习帮助非常大,从本文开始,我会在博文中添加一些DeepSeek 提示的笔记。

在下面,我们会进一步地讨论急于大模型Embedding 的相似性搜索的编程

 

 

 


http://www.niftyadmin.cn/n/5865064.html

相关文章

【JavaEE】SpringMVC 请求传参

目录 一、请求二、传递单个参数三、传递多个参数四、传递对象五、RequestParam注解 后端参数重命名(后端参数映射)六、传递数组七、传递集合,RequestParam八、传递JSON数据8.1 JSON字符串和Java对象互转8.1.1 Test注解8.1.2 Java对象转JSON8.…

opencv交叉编译报错:undefined reference to `png_riffle_palette_neon

序偶NEON 概述 NEON(Nested Enhanced Vector Instruction Set)是 ARM 架构中的一种高级 SIMD(Single Instruction, Multiple Data,单指令多数据)扩展技术。它专为加速多媒体和信号处理任务而设计,允许在单…

【一起学Rust | 框架篇 | Tauri2.0框架】在Tauri应用中设置Http头(Headers)

文章目录 前言一、配置准备1. 检查版本2. 使用条件3. 支持的请求头(并不是全部支持) 二、使用步骤1. 如何配置header2. 框架集成1. 对于Vite系列、Nuxt、Next.js这种前端框架Vite系列框架Angular系列框架Nuxt系列框架Next.js系列框架 2. 对于Yew和Leptos…

Quickwit获取Kafka数据源消息

介绍 Quickwit可以将数据从一个或多个源插入到索引中。创建索引后,可以使用CLI 命令quickwit source create添加源,支持的源有:file、kafka、kinesis、pulsar。 本章讲解如何从Quickwit搜索引擎中创建Kafka源和获取Kafka源主题数据流&#…

【NLP 38、激活函数 ④ GELU激活函数】

别盲目,别着急,慢慢走,没事的 —— 25.2.24 一、定义与数学表达式 GELU(Gaussian Error Linear Unit,高斯误差线性单元)是一种结合概率分布的非线性激活函数,其核心思想是通过输入值服从标准正…

牛客周赛 Round 82(思维、差分、树状数组、大根堆、前后缀、递归)

文章目录 牛客周赛 Round 82(思维、差分、树状数组、大根堆、前后缀、递归)A. 夹心饼干B. C. 食堂大作战(思维)D. 小苯的排列计数(差分、树状数组)E. 和和(大根堆,前缀和)F. 怎么写线性SPJ &…

小程序高度问题背景scss

不同的机型&#xff0c;他的比例啥的都会不一样&#xff0c;同样的rpx也会有不同的效果。所以这里选择了取消高度。 <view class"box-border" :style"{padding-top: ${navHeight}px,}"><!-- 已登录 --><view v-if"userStore.userInfo&…

Image Collections操作

在Google Earth Engine&#xff08;GEE&#xff09;中处理影像集合&#xff08;Image Collections&#xff09;是遥感数据分析的核心操作。以下是详细的步骤和示例代码&#xff0c;涵盖影像集合的常见操作&#xff1a; 1. 影像集合基础 影像集合是GEE中存储多幅影像的数据结构…