向量数据库 PieCloudVector 进阶系列丨打造音乐推荐系统

news2024/12/22 22:58:14

在上一篇内容中,我们介绍了 PieCloudVector 如何助力构建基于图片数据的商品推荐系统,详细描述从数据集的准备到数据向量化处理,再到向量数据的存储和相似性搜索的完整流程。本文将进一步探讨如何将 PieCloudVector 应用于音频数据,以实现音频内容的识别和分类。

音频数据是一种丰富且动态的非结构化数据形式,PieCloudVector 作为大模型时代的分析型数据库升维,其在音频数据处理上的应用,不仅能够提升音频内容识别的准确性,还能增强音频分类的效率。本文为《PieCloudVector 进阶系列》的第二篇,将以音频数据为例, 详细介绍利用向量数据库助力音频数据的向量化处理、存储以及相似性搜索的过程。 (本文演示数据均来自 Hugging Face)

基于 PieCloudVector 打造音乐推荐系统

音频数据在转化成向量的过程中,其采样率(即每秒采样数量)是控制数据质量和向量大小的关键之一。采样率越大,数据质量越高,但数据大小也随着变大。本文使用的实例数据是来自 Hugging Face 的 MInDS-14 数据集[1],该数据包含了 14 种不同语言的电子银行领域客户音频数据,共 14 个意图种类(intent_class)。

本文将对音频数据向量化,通过音频相似度对比实现音乐推荐系统。下面将从「数据集准备」、「数据降维与存储」、「音频相似性搜索」三个方面进行介绍。完整逻辑如下图所示:

image.png

完整逻辑过程

1.数据集准备

首先,我们将对音频数据进行读取和调整,使其转变为向量存入数据库,以便后续的计算。Hugging Face 和后续的步骤需要以下两个 Python 包:

  • soundfile
  • librosa

从 Hugging Face 下载 MInDS-14 数据。由于该数据集较小,这里我们加载所有共 563 条训练数据。

from datasets import load_dataset
dataset_minds = load_dataset("PolyAI/minds14", "en-US", split="train")

为避免反复下载数据,可将该数据集保存至本地。

dataset_minds.save_to_disk('minds14_dataset')
# 读取本地数据
dataset_minds = load_from_disk('minds14_dataset')

本数据集包括以下特征:路径、音频、转录、英文转录、意图种类和语言,这里我们将重点关注“audio”(音频)、“intent_class”(意图种类)、“lang_id”(语言)这几个特征。

dataset_minds.features

{ 'path': Value(dtype='string', id=None),
  'audio': Audio(sampling_rate=8000, mono=True, decode=True, id=None), 
  'transcription': Value(dtype='string', id=None),
  'english_transcription': Value(dtype='string', id=None),
  'intent_class': Classlabel(names=['abroad', 'address', 'app_error', 'atm_limit', 'balance', 'business_loan', 'card_issues', 'cash_deposit', 'direct_debit', freeze', 'high_value_payment', 'joint_account', 'latest_transactions', pay_bill'], id=None),
  'lang_id': ClassLabel(names=['cs-CZ', 'de-DE', 'en-AU', 'en-GB', 'en-US', 'es-ES', fr-FR', it-IT', 'ko-KR','nl- NL', 'pl-PL', 'pt-PT, 'ru-RU', 'zh-CN'], id=None)}

2.数据降维与存储

由于音频格式在 Hugging Face 数据集中是个较为复杂的数据格式,我们需要先对数据音频部分进行处理。这里我们以数据集中第一条数据为例:

In: dataset_minds.['audio'][0]

Out: {'path': '/Users/arlena.wang/.cache/huggingface/datasets/downloads/extracted/fa6d050e601cf0ccf2c2b01238375a56579232af95e398fcef126ea4224e4185/en-US~JOINT_ACCOUNT/602ba55abb1e6d0fbce92065.wav',
      'array': array([ 0. , 0.00024414, -0.00024414, ..., -0.00024414, 0. , 0. ]), 
      'sampling_rate': 8000}

一条音频数据中,包含音频文件路径、音频波形矩阵,以及波形所对应的采样率。Jupyter Notebook 的 IPython 工具包中提供了 Audio 功能,可以在代码界面生成一个播放器,播放音频文件或音频向量,方便我们了解音频内容。针对数据集中第一条数据,我们使用其对应的音频矩阵和采样率作为输入,播放音频:

from IPython.display import Audio
Audio(data=dataset_minds['audio'][0]['array'], rate=dataset_minds['audio'][0]['sampling_rate'])

该数据集中,波形的采样率为 8000。虽然较高的采样率能够提供更精确的音频数据,但如果音频文件较长,将导致生成的矩阵规模庞大,增加后续计算的负担。第一条数据 8000 的采样率对应的音频向量长度达到了 8 万以上。

print(print(dataset_minds['audio'][0]['sampling_rate']))
# 8000
print(len(dataset_minds['audio'][0]['array']))
# 86699

降低采样率是降低数据维度的办法之一。利用 Python 音频处理库 Librosa,不仅可以加载、处理音频文件,也可用于音频分析。以第一条和第二条数据为例,我们将使用 Librosa 来重新调整音频数据的采样率,以便将数据大小优化至适合向量存储的尺寸。需注意的是,不同音频文件在相同的采样率下,矩阵的长度会有所不同。

In: from librosa import resample
    print(len(resample(dataset_minds['audio'][0]['array'], orig_sr=8000, target_sr=2000)))
    print(len(resample(dataset_minds['audio'][1]['array'], orig_sr=8000, target_sr=2000)))
    
Out: 32513
     19968

调整过采样率的每条数据对应的向量长度也是不同的。如果想直接将这个阶段的音频向量保存至 PieCloudVector,需要将音频向量的维度进行统一。

以下方程调用了 Librosa 中的 fix_length 工具,可将音频向量调整为统一大小,以最长的向量为基准,未达到该长度的部分由零值来填补。填补的方式不止零值一种,可以根据数据的特质来选择合适的填补方式。

from librosa import resample
from librosa.util import fix_length

max_len = 0
for item in dataset_minds['audio']:
    if len(item['array']) > max_len:
        max_len = len(item['array'])

def resample_audio_fix(audio):
    audio["audio_fix"] = fix_length(resample(audio['audio']['array'], orig_sr=8000, target_sr=2000, fix=True, scale=True), size=max_len)
    return audio

updated_fix_dataset = dataset_minds.map(resample_audio_fix)

当前音频向量中存在大量零值,我们可以通过降维技术(例如 PCA 降维算法)来减少向量的维度。这样的处理不仅能降低计算成本,而且通过精简数据,可提升K最近邻(KNN)算法的性能。加入降维处理后的流程如下图所示:

image.png

加入降维处理后的流程

尽管将采样率降低到了 2000,音频向量的长度仍然达到了数万级别。这对于数据库中的向量存储以及后续的向量搜索来说,都是一个巨大的挑战。因此,需要采用另一种音频处理方法——梅尔频谱(Mel Spectrogram)。这是一种极为便利、应用广泛音频处理方式,能够将音频数据转换成类似“图片”的形式,从而显著降低数据的维度。

梅尔频谱是一种利用快速傅里叶变换将数据从时间维度转换为频率维度的算法。可通过以下文章来详细了解这种算法:

  • Understanding the Mel Spectrogram[2]
  • 理解梅尔频谱[3]

使用该方法有两种处理选择:

  • 使用 Diffussion 模型,将数据转换为梅尔频谱,通过在数据中加入随机性来提升数据转换的效率和准确性。这种方式更贴近数据的特征,但对算力的消耗较大。

  • 直接使用 Librosa 梅尔频谱转换函数。

下面演示如何使用Diffusion模型将数据转换为梅尔频谱。

import torch
from IPython.display import Audio
from diffusers import DiffusionPipeline

device = "cuda" if torch.cuda.is_available() else "cpu"
pipe = DiffusionPipeline.from_pretrained("teticio/audio-diffusion-256").to(device)
output = pipe(
    raw_audio=dataset_minds['audio'][0]['array'],
    start_step=int(pipe.get_default_steps() / 2),
    mask_start_secs=1,
    mask_end_secs=1,
)

转换后的梅尔频谱如下图:

image.png

转换后的梅尔频谱

由于 Diffussion 模型比较庞大,消耗算力,我们决定选择 Librosa 库中的梅尔频谱转换函数进行音频处理。以第一条音频数据为例,转换后,我们将得到一个 128 x 170 的矩阵。

In: melspectrogram(y=dataset_minds['audio'][0]['array'], sr=8000).shape

Out: (128, 170)

使用 Huggingface 的 map 工具,转换数据集中的每一条数据。

from librosa.feature import melspectrogram
import PIL
def transform_audio(audio):
    audio["audio_image"] = PIL.Image.fromarray(melspectrogram(y=audio['audio']['array'], sr=8000).astype('uint8'))
    return audio

updated_dataset = dataset_minds.map(transform_audio)

转换完成后,我们可以使用 PIL 工具来可视化转换后的向量。

display(updated_dataset["audio_image"][0])

image.png

这意味着我们可以采用类似于处理图像数据的方法来对音频数据进行建模和计算。具体来说,我们将再次利用之前在图像数据案例中使用的 Embedding 模型,对音频数据进行进一步的数据提炼。

from imgbeddings import imgbeddings
ibed = imgbeddings()

# 第一条音频数据
embedding_0 = ibed.to_embeddings(updated_dataset["audio_image"][0])

可以看到,转换过后的音频数据是一个维度为 768 的向量。

In: embedding_0.shape

Out: (1, 768)

转换数据中的所有梅尔频谱矩阵。

embedding = ibed.to_embeddings(updated_dataset['audio_image'])

转换后,我们将 768 维度的向量、意图类别、语言信息写入 PieCloudVector。首先,我们在 PieCloudVector 中创建相应的表。

CREATE TABLE if not exists vec_test.banking_audio (id bigserial PRIMARY KEY, embedding vector(768), intent_class varchar(50), lang_id varchar(10));
truncate table vec_test.banking_audio;

在 Python 端连接向量数据库 PieCloudVector,写入数据,具体代码如下:

import psycopg2

embeddings_lst = embedding.tolist()

conn = psycopg2.connect('postgresql://user:passwd@192.163.**.**:5432/pgvec_test')
cur = conn.cursor()

for i in range(len(embeddings_lst)):
    cur.execute('INSERT INTO vec_test.banking_audio (embedding, intent_class, lang_id) values (%s,%s,%s)', (embeddings_lst[i], updated_dataset["intent_class"][i], updated_dataset["lang_id"][i]))

conn.commit()
conn.close()

3.音频相似性搜索

我们通过 KNN + L2 Distance 查找与第 1 条数据最相近的 10 条语音,进行对比。

from sqlalchemy import create_engine, text as sql_text
import pandas as pd

engine = create_engine('postgresql://user:passwd@192.163.**.**:5432/pgvec_test', echo=False).connect()
audio_id = pd.read_sql_query(sql=sql_text('select id, intent_class, lang_id  from vec_test.banking_audio where id != 1 order by embedding <-> ' + "'" + str(embedding_0.tolist()[0]) + "'" + ' limit 10'),
                     con=engine)

结果如下:

image.png

第 1 条数据是关于一位女性询问联合账户相关的事宜,她的意图及语言种类如下:

In: updated_dataset.features["intent_class"].int2str(int(audio_id.loc[0, 'intent_class']))

Out: 'direct_debit'

In: updated_dataset.features["lang_id"].int2str(int(audio_id.loc[0, 'lang_id']))

Out: 'en-US'

在我们查询的最相近的十条记录中,所有音频皆为美式英语,对应编号 4,但意图各不相同。我们可以通过简单计算来查询出现频率最高的意图种类。

audioid_lst = audio_id['id'].to_list()

def most_common(lst):
    return max(set(lst), key=lst.count)

label = most_common([updated_dataset['intent_class'][i] for i in audioid_lst])
print(updated_dataset.features["intent_class"].int2str(int(label)))

结果为’atm_limit’。

In: updated_dataset.features["intent_class"].int2str(int(label))

Out: 'atm_limit'

再次使用 Audio 函数播放与第 1 条数据最接近的第 355 条数据。第 355 条数据是一条 11 秒长度的音频,同样是女声,也同样是询问有关’direct_debit’的事宜。

Audio(data=updated_dataset['audio'][354]['array'], rate=dataset_minds['audio'][354]['sampling_rate'])

音频相似搜索在文本内容的识别上能力有限,但它更擅长捕捉声音波形层面的相似性,特别适合用于比较音频的音色和语言特征。如果输入的音频是音乐,可以通过同样的方式有效地为用户推荐相似的音乐,它能够识别出音乐作品中的旋律和节奏等关键元素,并与数据库中的音乐进行匹配,从而推荐风格相近的音乐给用户。这些推荐的音乐在听觉体验上与用户喜欢的音乐相似,有助于提升用户的满意度和体验。

在下篇文章中,我们将探索如何利用 PieCloudVector 的文本数据处理能力,打造 ChatBot。 欢迎关注!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2231821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python之数据结构与算法(数据结构篇)-- 栈

一、栈的概念 这里我们不去了解教科书上面的“教条概念”&#xff0c;其实“栈”的概念和古代的时候的“客栈”是有异曲同工之妙的。 在这里我们把客栈看成“栈”&#xff0c;旅客看作“栈元素” 1.当旅客进来住店时&#xff0c;叫做“入栈”&#xff1b; 2.当旅客退房时&#…

Java调用chatgpt

目前openai的chatgpt在国内使用有一定难度&#xff0c;不过国内的大模型在大部分情况下已经不弱于chatgpt&#xff0c;而且还更便宜&#xff0c;又能解决国内最敏感的内容安全问题。本文后续以spring ai调用国内chatgpt厂商实现为例&#xff0c;讲解怎么构建一个java调用chatgp…

web前端多媒体标签设置(图片,视频,音频)以及图片热区(usemap)的设置

多媒体标签运用 在HTML中有以下常见多媒体标签&#xff1a; <img> &#xff08;图像标签&#xff09; - 作用&#xff1a;用于在网页中嵌入图像。 - 示例&#xff1a; <img src"image.jpg" alt"这是一张图片"> 。其中 src 属性指定图像的…

安卓开发之数据库的创建与删除

目录 前言&#xff1a;基础夯实&#xff1a;数据库的创建数据库的删除注意事项 效果展示&#xff1a;遇到问题&#xff1a;如何在虚拟机里面找到这个文件首先&#xff0c;找到虚拟机文件的位置其次&#xff0c;找到数据库文件的位置 核心代码&#xff1a; 前言&#xff1a; 安…

基于SSM+微信小程序的订餐管理系统(点餐2)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM微信小程序的订餐管理系统实现了管理员和用户。管理端实现了 首页、个人中心、用户管理、菜品分类管理、菜品信息管理、订单信息管理、配送信息管理、菜品评价管理、订单投诉管理、…

《AI在企业战略中的关键地位:以微软和阿里为例》

内容概要 在当今商业环境中&#xff0c;人工智能&#xff08;AI&#xff09;的影响力如滔滔洪水&#xff0c;愈演愈烈。文章将揭示AI在企业战略中的崛起&#xff0c;尤其以微软和阿里巴巴为代表的企业&#xff0c;这两家科技巨头通过不同方式&#xff0c;将智能技术融入其核心…

华为荣耀曲面屏手机下面空白部分设置颜色的方法

荣耀部分机型下面有一块空白区域&#xff0c;如下图红框部分 设置这部分的颜色需要在themes.xml里面设置navigationBarColor属性 <item name"android:navigationBarColor">android:color/white</item>

【ESP32】ESP-IDF开发 | I2C从机接收i2c_slave_receive函数的BUG导致程序崩溃解决(idf-v5.3.1版本)

1. 问题 在调试I2C外设的demo时&#xff0c;按照官方文档的描述调用相关API&#xff0c;烧录程序后发现程序会不断崩溃&#xff0c;系统log如下。 初步分析log&#xff0c;原因是访问到了不存在的地址。一开始我以为是自己的代码问题&#xff0c;反反复复改了几次都会出现同样的…

企业数字化转型实施中的挑战与解决方案:架构引领的战略路径

在企业推动数字化转型的过程中&#xff0c;通常会面临复杂的挑战。随着技术的不断演进和业务环境的变化&#xff0c;企业架构&#xff08;Enterprise Architecture, EA&#xff09;成为帮助企业应对这些挑战的关键工具。通过提供一个全面的战略蓝图&#xff0c;EA使企业能够在保…

桑基图在医学数据分析中的更复杂应用示例

桑基图&#xff08;Sankey Diagram&#xff09;能够有效地展示复杂的流动关系&#xff0c;特别适合用于医学数据分析中的多种转归和治疗路径的可视化。接下来&#xff0c;我们将构建一个稍微复杂的示例&#xff0c;展示不同疾病患者在治疗过程中的流动&#xff0c;以及他们的治…

[SICTF Round4] PWN

这PWN题似乎是给我出的&#xff0c;4个一血1个2血。密码又过于简单。逆向太难了又不大会。 Stack fengshui main可以溢出覆盖rbpret所以它每一步都需要移栈。 可用的ROP里没有pop rdi,在4004c0里有错位的01 5d c3 &#xff1a;add DWORD PTR [rbp-0x3d], ebx 并且有对应的p…

消息中间件类型介绍

ActiveMQ&#xff1a; ActiveMQ可是个老将了&#xff0c;它功能全面、稳定可靠&#xff0c;还支持多种协议和编程语言。如果你需要一个兼容性好、易于集成的消息中间件&#xff0c;ActiveMQ可是个不错的选择。 RabbitMQ&#xff1a; RabbitMQ以其简单易用和高性能著称。它支持丰…

【设计模式系列】组合模式(十二)

目录 一、什么是组合模式 二、组合模式的角色 三、组合模式的典型应用 四、组合模式在Mybatis SqlNode中的应用 4.1 XML映射文件案例 4.2 Java代码使用案例 一、什么是组合模式 组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;其核…

Ghidra无头模式(自动化批处理执行重复性任务)

Ghidra无头模式&#xff08;自动化批处理执行重复性任务&#xff09; 与Ghidra GUI探索单个项目中的单个文件不同&#xff0c;Ghidra headless analyzer&#xff08;Ghidra无头分析器&#xff09;更加适合批处理和用脚本控制Ghidra。 &#xff08;一&#xff09;启动analyzeHea…

【大众点评】店铺评论 加密参数生成逆向分析

点击好评 https://www.dianping.com/ajax/json/shopDynamic/allReview 分析参数_token 直接搜_token 共17个&#xff0c;优先看和请求相关的 给第一个_token打上断点&#xff0c;然后切换评论&#xff0c;就直接断住了 n h(i, e.sendData) _token: n 现在给它打上断点&am…

Fsm3

采用读热码编写方式&#xff1a; module top_module(input clk,input in,input areset,output out); ////reg [3:0]A 4d0001;// reg [3:0]B 4d0010;//reg [3:0]C 4d0100;// reg [3:0]D 4d1000; //1、首先用读热码定义四个状态变量parameter A 4d0001 ,B 4d0010, C 4d01…

在腾讯云服务器上部署MaxKB项目(基于LLM大语言模型的知识库问答系统)

前言 一&#xff0c; MaxKB介绍 MaxKB是基于LLM大语言模型的知识库问答系统&#xff0c;旨在成为企业的最强大脑。它支持开箱即用&#xff0c;无缝嵌入到第三方业务系统&#xff0c;并提供多模型支持&#xff0c;包括主流大模型和本地私有大模型&#xff0c;为用户提供智能问…

【大众点评】加密参数生成逆向分析

点击好评 https://www.dianping.com/ajax/json/shopDynamic/allReview 分析参数_token 直接搜_token 共17个&#xff0c;优先看和请求相关的 给第一个_token打上断点&#xff0c;然后切换评论&#xff0c;就直接断住了 n h(i, e.sendData) _token: n 现在给它打上断点&am…

【Python+Pycharm】2024-Python安装配置教程

【PythonPycharm】2024-Python安装配置教程 一、下载装 Python 1、进入Python官网首页&#xff0c;下载最新的Python版本 Download Python | Python.org 选择对应版本下载 安装 测试安装情况 python如果安装失败 在系统环境变量添加安装路径 where pythonwin7安装路径添加…

Python中如何计算整商:详解整除运算及其应用场景

目录 一、整除运算的基本概念 1. 语法 2. 工作原理 二、整除运算的详细解析 1. 整数之间的整除 2. 浮点数之间的整除 3. 整数与浮点数之间的整除 三、整除运算的应用场景 1. 数据处理中的取整操作 2. 循环中的步进控制 3. 分页显示数据 4. 时间计算中的取整 四、整…