MIUI嵌入式API
为了使用MIUI AI的嵌入API生成文本嵌入,我们可以向API端点发出请求并指定嵌入模型 MIUI嵌入
,同时提供输入文本列表。API然后将相应的嵌入作为数值向量返回,该数值向量可用于NLP应用程序中的进一步分析或处理。
进口 os
从 米斯特拉伊 进口
api_key = os.环境[“MIUI_API_KEY”]
模型 = “MIUI嵌入”
客户 = (api_key =api_key )
嵌入_批处理_响应 =客户 .嵌入件.创造(
模型 =模型 ,
输入=[“嵌入这个句子。”, “还有这个。”],
)
输出 嵌入_批处理_响应
是一个EmbeddedResponse对象,其中包含嵌入和令牌使用信息。
嵌入响应(
id='b4c2c739780415bb3af4e47580318cc',对象='list',数据=[
数据(对象=“嵌入”,嵌入=[-0.0165863037109375,…],索引=0),
数据(对象=“嵌入”,嵌入=[-0.02342242109375,…],索引=1)],
model=“管理嵌入”,用法=嵌入响应用法(prompt_tokens=15,total_tokens=15)
)
让我们来看看第一个嵌入的长度:
它返回1024,这意味着我们的嵌入维度是1024。这个 MIUI嵌入
该模型为每个文本字符串生成维度为1024的嵌入向量,而不管文本长度如何。值得注意的是,虽然高维嵌入可以更好地捕获文本信息并提高NLP任务的性能,但它们可能需要更多的计算资源来托管和推理,并可能导致存储和处理这些嵌入的延迟和内存使用增加。在设计依赖于文本嵌入的NLP系统时,应该考虑性能和计算资源之间的权衡。
距离测量
在文本嵌入领域,具有相似含义或上下文的文本往往在这个空间内彼此靠近,这是通过它们的向量之间的距离来衡量的。这是由于模型在训练过程中学会了将语义相关的文本分组在一起。
让我们来看一个简单的例子。为了简化文本嵌入的工作,我们可以将嵌入API包装在此函数中:
从 sklearn.韵律学.成对 进口 欧几里得立场
def get_text_嵌入( 输入):
嵌入_批处理_响应 =客户 .嵌入件.创造(
模型 =模型 ,
输入= 输入
)
返回嵌入_批处理_响应 .数据[0].嵌入
假设我们有两句话:一句关于猫,另一句关于书。我们想知道每句话与参考句“书是镜子:你只能从书中看到你内在已经拥有的东西”有多相似。我们可以看到,参考句嵌入和书本句嵌入之间的距离小于参考句嵌入与猫句嵌入之间。
句子 = [
“一个没有猫的家,一只喂养良好、被宠爱和受到适当尊重的猫,也许是一个完美的家,但它怎么能证明这个头衔呢?”,
“我认为书就像人,在你最需要的时候,它们就会出现在你的生活中。”
]
嵌入件= [get_text_嵌入([t]) 对于t在里面句子 ]
参考_强度 = “书是镜子:你只能从书中看到你内心已经有的东西”
引用_嵌入 =get_text_嵌入([参考_强度 ])
对于t, e 在里面 拉链(句子 ,嵌入件):
距离 = 欧几里得立场([ e ], [引用_嵌入 ])
打印(t, 距离 )
输出
一个没有猫的家,一只喂养良好、被宠爱和受到适当尊重的猫,也许是一个完美的家,但它怎么能证明这个头衔呢?[[0.80094257]]
我认为书就像人,在你最需要的时候,它们就会出现在你的生活中[[0.58162089]]
在上面的例子中,我们使用欧几里德距离来测量嵌入向量之间的距离(请注意,由于MIUI AI嵌入是范数1,因此余弦相似性、点积或欧几里德距离都是等价的)。
短语检测
另一个潜在的用例是释义检测。在这个简单的例子中,我们有一个由三个句子组成的列表,我们想知道这两个句子中是否有任何一个是彼此的意译。如果两个句子嵌入之间的距离很小,则表明这两个句子在语义上相似,可能是潜在的释义。
结果表明,前两句在语义上相似,可能是潜在的意译,而第三句则不同。这只是一个超级简单的例子。但这种方法可以扩展到现实世界应用程序中更复杂的情况,例如检测社交媒体帖子、新闻文章或客户评论中的释义。
进口 itertools
句子 = [
“祝大家阵亡将士纪念日周末安全快乐”,
“致Whatsit Productions Films的所有朋友,祝他们度过一个安全快乐的阵亡将士纪念日周末”,
“我在哪里可以找到最好的奶酪?”,
]
句子嵌入 = [get_text_嵌入([t]) 对于t在里面句子 ]
句子_嵌入_邮件 = 列表( itertools.组合(句子嵌入 , 2.))
句子_句子 = 列表( itertools.组合(句子 , 2.))
对于 s, e 在里面 拉链(句子_句子 ,句子_嵌入_邮件 ):
打印( s, 欧几里得立场([ e [0]], [ e [1.]]))
输出
(“祝大家阵亡将士纪念日周末安全快乐”,“致Whatsit Productions Films的所有朋友,祝大家阵亡纪念日周末平安快乐”)[[0.5432686]]
(“祝大家阵亡将士纪念日周末安全快乐”,“我在哪里可以找到最好的奶酪?”)[[0.92573978]]
(“祝Whatsit Productions Films的所有朋友度过一个安全快乐的阵亡将士纪念日周末”,“我在哪里可以找到最好的奶酪?”)[[0.9114184]]
批量处理
MIUI AI Embeddings API旨在批量处理文本,以提高效率和速度。在这个例子中,我们将通过从以下位置加载症状2疾病数据集来演示这一点 Kaggle,其中包含1200行,有两列:“标签”和“文本”。“标签”列表示疾病类别,而“文本”列描述与该疾病相关的症状。
我们编写了一个函数 get_embeddings_bychunks
它将数据分割成块,然后将每个块发送到MIUI AI Embeddings API以获得嵌入。然后,我们将嵌入保存为数据帧中的新列。请注意,API将来将提供自动查询,这样用户就不需要在发送数据之前手动将数据拆分为块。
进口 熊猫 作为 pd
df = pd.read_csv(
"https://raw.githubusercontent.com/MIUIai/cookbook/main/data/Symptom2Disease.csv",
index_col=0,
)
def get_embeddings_bychunks(数据, chunk_size):
大块 = [数据[x :x + chunk_size] 对于x 在里面 范围(0, 伦恩(数据), chunk_size)]
嵌入响应 = [
客户 .嵌入件.创造(模型 =模型 , 输入=c) 对于c在里面 大块
]
返回 [d.嵌入对于 e 在里面 嵌入响应 对于d在里面 e .数据]
df [“嵌入”] =get_embeddings_bychunks(df [“文本”].tolist(), 50)
df .头()
t-SNE嵌入可视化
我们之前提到过,我们的嵌入有1024个维度,这使得它们无法直接可视化。因此,为了可视化我们的嵌入,我们可以使用像t-SNE这样的降维技术将我们的嵌入投影到更容易可视化的低维空间中。
在这个例子中,我们将嵌入转换为二维,并创建一个二维散点图,显示不同疾病嵌入之间的关系。
进口 海运 作为 sns
从 sklearn.歧管 进口 TSNE
进口 numpy 作为 np
TSNE= TSNE(n个组件=2., 随机状态=0).fit_transform( np.阵列(df [“嵌入”].to_list()))
斧头 = sns.散点图(x = TSNE[:, 0], y= TSNE[:, 1.], 色调= np.阵列(df ['标签'].to_list()))
sns.move_legend(斧头 , '左上', bbox_to_anchor=(1., 1.))
与fastText的比较
我们可以将其与流行的开源嵌入模型fastText进行比较。然而,在检查t-SNE嵌入图时,我们注意到fastText嵌入无法在具有匹配标签的数据点之间创建清晰的分隔。
进口 fasttext.util
fasttext.util.download_model('en', if存在='忽略')
英尺 = fasttext.load_model(“cc.en.300.bin”)
df ['快速文本嵌入'] =df ['文本'].应用(lambdax :英尺 .get_word_vector(x ).tolist())
TSNE= TSNE(n个组件=2., 随机状态=0).fit_transform( np.阵列(df ['快速文本嵌入'].to_list()))
斧头 = sns.散点图(x = TSNE[:, 0], y= TSNE[:, 1.], 色调= np.阵列(df ['标签'].to_list()))
sns.move_legend(斧头 , '左上', bbox_to_anchor=(1., 1.))
文本嵌入可以用作机器学习模型中的输入特征,如分类和聚类。在这个例子中,我们使用分类模型从疾病描述文本的嵌入中预测疾病标签。
从 sklearn.型号选择 进口 train_test_split
从 sklearn.预处理 进口 标准标尺
从 sklearn.线性模型 进口 逻辑回归
火车x, 测试x, train_y, test_y = train_test_split(
df [“嵌入”],df [“标签”], test_size=0.2
)
定标器 = 标准标尺()
火车x=定标器 .fit_transform(火车x.to_list())
测试x=定标器 .转型( 测试x.to_list())
clf = 逻辑回归( 随机状态=0,c=1, max_iter=500).适合(
火车x, train_y.to_list()
)
打印(f“精度: {100* np.意思是(clf .预测( 测试x) == test_y .to_list()):.2f}%")
输出
在我们用嵌入数据训练分类器后,我们可以尝试对其他文本进行分类:
文本 = “我经常头痛和视力问题。”
clf .预测([get_text_嵌入([文本 ])])
输出
与fastText的比较
此外,让我们来看看在这个分类任务中使用fastText嵌入的性能。与使用fastText嵌入相比,使用MIUI AI嵌入模型的分类模型似乎取得了更好的性能。
火车x, 测试x, train_y, test_y = train_test_split(
df [“fasttext_embedings”],df [“标签”], test_size=0.2
)
定标器 = 标准标尺()
火车x=定标器 .fit_transform(火车x.to_list())
测试x=定标器 .转型( 测试x.to_list())
clf = 逻辑回归( 随机状态=0,c=1, max_iter=500).适合(
火车x, train_y.to_list()
)
打印(f“精度: {100* np.意思是(clf .预测( 测试x) == test_y .to_list()):.2f}%")
输出
如果我们没有疾病标签怎么办?从数据中获得见解的一种方法是通过聚类。聚类是一种无监督的机器学习技术,它根据相似数据点在某些特征上的相似性将它们分组在一起。在文本嵌入的背景下,我们可以使用每个嵌入之间的距离作为相似性的度量,并将高维空间中彼此接近的嵌入的数据点分组在一起。
由于我们已经知道有24个聚类,让我们使用K-means聚类24个聚类。然后,我们可以检查几个示例,并验证单个集群中的示例是否彼此相似。例如,看看集群23的前三行。我们可以看到,它们在症状方面非常相似。
从 sklearn.集群 进口 KMeans
模型 = KMeans(n簇=24, max_iter=1000)
模型 .适合(df [“嵌入”].to_list())
df [“群集”] =模型 .标签_
打印(*df [df .集群 ==23].文本 .头(3.), 九月=“\n\n”)
输出:
我一直感到非常疲倦和虚弱,还咳嗽得很厉害,呼吸困难。我的体温很高,咳嗽时会产生很多粘液。
我咳嗽得厉害,而且我累坏了。我一直在咳嗽浓稠的粘液,而且我的发烧也很高。
我一直咳嗽,感觉很累。我发烧得厉害,呼吸困难。我咳嗽的时候,也会咳出很多粘液。
我们的嵌入模型在检索任务中表现出色,因为它是在考虑检索的情况下训练的。嵌入在实现检索增强生成(RAG)系统方面也非常有帮助,该系统使用从知识库中检索到的相关信息来生成响应。从高层来看,我们将知识库(无论是本地目录、文本文件还是内部wiki)嵌入到文本嵌入中,并将其存储在向量数据库中。然后,基于用户的查询,我们从知识库中检索最相似的嵌入,这些嵌入表示相关信息。最后,我们将这些相关的嵌入提供给一个大型语言模型,以生成针对用户查询和上下文量身定制的响应。如果您有兴趣了解更多关于RAG系统如何工作以及如何实现基本RAG的信息,请查看我们的 以前的指南 关于这个话题。