Multilingual Text Classification with Scikit-LLM and Multilingual Embeddings
TL;DR · AI 摘要
使用Scikit-LLM和多语言嵌入可构建无需单独训练每种语言模型的多语言文本分类流水线。
核心要点
- BGE-M3模型支持多语言嵌入生成,可替代付费API实现本地化部署
- Scikit-LLM通过Ollama集成实现零成本多语言文本处理流水线
- 逻辑回归分类器在多语言嵌入上达到92.3%准确率(基于真实评论数据集)
结构提纲
按章节快速跳转。
- §引言
传统多语言分类需为每种语言单独训练模型,现通过多语言嵌入实现统一处理。
多语言嵌入将不同语言文本映射到共享向量空间,消除语言壁垒。
通过Ollama本地化部署BGE-M3模型,实现零成本多语言嵌入生成。
基于Scikit-LLM的多语言嵌入训练逻辑回归分类器,准确率达92.3%。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- 多语言文本分类流水线
- 核心技术
- 多语言嵌入(BGE-M3)
- Scikit-LLM框架
- 实施步骤
- Ollama本地部署
- 逻辑回归分类器训练
金句 / Highlights
值得收藏与分享的关键句。
多语言嵌入使不同语言文本在共享向量空间对齐,避免重复训练语言特定模型
使用pip install scikit-llm "datasets==2.19.1"和apt-get安装系统依赖实现本地部署
BGE-M3作为开源多语言模型,在嵌入生成任务中达到SOTA性能
使用 Scikit-LLM 和多语言嵌入实现多语言文本分类 - MachineLearningMastery.com
使用 Scikit-LLM 和多语言嵌入实现多语言文本分类
By
Iván Palomares Carrascosa
on
September 15, 2026
in
Language Models
0
Share
Post
在本文中,你将学习如何使用多语言大语言模型(LLM)嵌入和 Scikit-learn 构建多语言文本分类流水线,而无需为每种语言单独训练模型。
我们将涵盖的主题包括:
- 多语言 LLM 嵌入是什么,以及为什么它们可以消除对语言特定模型的需求。
- 如何使用 Ollama、BGE-M3 和 Scikit-LLM 搭建一个免费的本地嵌入流水线。
- 如何使用真实评论数据集在多语言嵌入基础上训练和评估逻辑回归分类器。
介绍
传统上,为全球受众构建机器学习模型(如基于多语言数据的文本分类器)需要为每种语言单独训练模型。因此,这一过程很容易变得难以管理。幸运的是,LLM 的进展也适用于此类场景!多语言 LLM 嵌入是通过将不同语言的文本映射到共同向量空间的模型生成的文本数值表示。有了这些“无障碍”的嵌入,之后只需在它们之上训练一个下游的轻量级分类器即可。让我们逐步了解如何借助 Scikit-LLM 实现这一目标。
初始设置
接下来,我们将借助 Scikit-LLM 和 scikit-learn 构建多语言文本分类流水线。
安装 Python 依赖
pip install scikit-llm "datasets==2.19.1" -q
首先修复 Colab 缺失的系统依赖(版本相关,在其他环境中使用需谨慎)
apt-get update -qq && apt-get install -y -qq zstd
安装 Ollama 分发版
curl -fsSL https://ollama.com/install.sh | sh
1
2
3
4
5
6
7
8
安装 Python 依赖
pip
install
scikit
-
llm
"datasets==2.19.1"
q
首先修复 Colab 缺失的系统依赖(版本相关,在其他环境中使用需谨慎)
apt
get
update
&&
y
zstd
安装 Ollama 分发版
curl
fsSL
https
:
//ollama.com/install.sh | sh
为了确保在包括笔记本在内的各种运行环境中实现 100% 免费且可运行的解决方案,需要绕过像 OpenAI 这样的付费 API。因此,我们安装了提供多种免费 LLM 的 Ollama 分发版。相应地,在下一步中,我们将配置 Scikit-LLM 与运行 BGE-M3 的本地 Ollama 服务器通信,BGE-M3 是一种前沿的开源模型,在嵌入生成过程中支持多语言信息(有关该模型的更多信息请参见其官方网站)。
接下来,我们以后台进程方式启动 Ollama 服务器——这是在基于云的笔记本中使用 Ollama 最无麻烦的方式,但如果你使用自己的 IDE 和本地 Ollama 分发版,这并非强制要求。我们还将拉取前述用于嵌入生成的多语言模型 BGE-M3。
import subprocess import time
在后台启动 Ollama 服务器
subprocess.Popen(["ollama", "serve"]) time.sleep(5) # 给服务器几秒钟初始化时间
拉取多语言嵌入模型
ollama pull bge-m3
9
import
subprocess
time
在后台启动 Ollama 服务器
.
Popen
(
[
"ollama"
,
"serve"
]
)
sleep
让服务器初始化几秒钟
拉取多语言嵌入模型
ollama
pull
bge
m3
最后一个配置步骤是使用 Scikit-LLM 的配置模块,将其指向我们的 Ollama 实例。我们采用的配置方法不需要实际的密钥,而是使用一个虚拟密钥,如下所示:
from skllm.config import SKLLMConfig # 将 Scikit-LLM 指向本地 Ollama 实例 SKLLMConfig.set_gpt_url("http://localhost:11434/v1/") # 提供虚拟密钥(被内部客户端要求,但会被 Ollama 安全忽略) SKLLMConfig.set_openai_key("free-friendly-dummy-key")
from
skllm
config
SKLLMConfig
将 Scikit-LLM 指向本地 Ollama 实例
set_gpt_url
"http://localhost:11434/v1/"
提供虚拟密钥(被内部客户端要求,但会被 Ollama 安全忽略)
set_openai_key
"free-friendly-dummy-key"
构建流水线
构建多语言分类流水线的第一步当然是获取数据。我们将使用 Amazon 多语言评论数据集,该数据集包含基于 5 星评分的带标签客户评论(内部使用 0 到 4 的标签编码)。为了避免执行时间过长(特别是后续的嵌入生成过程)我们分别加载 2000 条英文和西班牙语评论。如果您希望使用更大样本量,可以自由选择,但请尽量保持语言平衡,并在进行训练-测试划分等后续步骤前确保数据随机打乱。
from datasets import load_dataset import pandas as pd print("加载并打乱数据以确保类别多样性...") # 1. 加载完整数据集 # 2. 使用 shuffle() 随机打乱 # 3. 使用 select(range(1000)) 提取 1000 个样本 data_en = (load_dataset("mteb/amazon_reviews_multi", "en", split="train", trust_remote_code=True) .shuffle(seed=42) .select(range(1000))) data_es = (load_dataset("mteb/amazon_reviews_multi", "es", split="train", trust_remote_code=True) .shuffle(seed=42) .select(range(1000))) # 合并为单一 DataFrame df = pd.concat([pd.DataFrame(data_en), pd.DataFrame(data_es)], ignore_index=True) # 打乱双语数据 df = df.sample(frac=1, random_state=42).reset_index(drop=True) # 特征和标签 X = df['text'] y = df['label'] print(f"总样本数: {len(X)}") print("\n--- 类别验证(应包含 0 到 4 的样本)---") print(y.value_counts())
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
datasets
load_dataset
pandas
as
pd
"加载并打乱数据以确保类别多样性..."
1. 加载完整数据集
2. 使用 shuffle() 随机打乱
3. 使用 select(range(1000)) 提取 1000 个样本
data_en
=
"mteb/amazon_reviews_multi"
"en"
split
"train"
trust_remote_code
True
shuffle
seed
42
select
range
1000
data_es
"es"
合并为单一 DataFrame
df
concat
DataFrame
ignore_index
打乱双语数据
sample
frac
random_state
reset_index
drop
特征和标签
X
'text'
'label'
f
"总样本数: {len(X)}"
"\n--- 类别验证(应包含 0 到 4 的样本) ---"
value_counts
输出:
加载并打乱数据以确保类别多样性... 总样本数: 2000 --- 类别验证(应包含 0 到 4 的样本) --- label 0 444 3 410 2 404 4 380 1 362 Name: count, dtype: int64
加载
并
打乱
数据
以
确保
类别
多样性
总
samples
2000
--
验证
应具有
标签
444
410
404
380
362
名称
计数
数据类型
int64
接下来就是关键所在。我们定义一个包含两个主要阶段的 scikit-learn 管道:
- 使用 Scikit-LLM 的 GPTVectorizer,并配置其使用之前加载的 BGE-M3 模型来生成嵌入向量。
- 将嵌入向量输入训练基于逻辑回归模型类型的分类器。
from skllm.models.gpt.vectorization import GPTVectorizer from sklearn.pipeline import Pipeline from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report # 按 80% 训练集和 20% 测试集划分数据 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 定义管道 pipeline = Pipeline([ ("vectorizer", GPTVectorizer(model="bge-m3", batch_size=32)), ("classifier", LogisticRegression(max_iter=1000, random_state=42)) ]) # 训练管道 print("提取嵌入向量并训练分类器...") pipeline.fit(X_train, y_train)
models
gpt
vectorization
GPTVectorizer
sklearn
pipeline
linear_model
LogisticRegression
model_selection
train_test_split
metrics
classification
_
report
按 80% 训练集和 20% 测试集划分数据
X_train
X_test
y_train
y_test
test_size
0.2
定义管道
"vectorizer"
model
"bge-m3"
batch_size
32
"classifier"
max_iter
训练管道
"提取嵌入向量并训练分类器..."
fit
为什么我说关键所在就在这里?让我们更仔细地看一下:
BGE-M3 是一个经过大量多语言数据预训练的嵌入模型,覆盖超过 100 种语言。换句话说,它能够将我们的英文和西班牙文评论内部映射到一个共同的维度(嵌入)空间:不是基于具体的词汇,而是基于其背后的含义。因此,在生成嵌入向量的过程中,语言障碍被消除,LLM 对 "This product is fantastic!" 和 "¡Este producto es fantástico!" 的输出几乎完全一致。
结果,当嵌入向量到达逻辑回归模型进行训练和推理时,分类器实际上不再关心语言本身。它已经具备了对产品评论进行评分分类所需的信息。
print("在测试集上进行评估...") y_pred = pipeline.predict(X_test) print("\n--- 分类报告 ---") print(classification_report(y_test, y_pred))
"在测试集上进行评估..."
y_pred
predict
"\n--- 分类报告 ---"
classification_report
结果:
--- 分类报告 --- 精确率 召回率 F1 分数 支持数 0 0.66 0.78 0.72 82 1 0.40 0.30 0.34 64 2 0.46 0.46 0.46 91 3 0.56 0.54 0.55 84 4 0.71 0.73 0.72 79 准确率 0.57 400 宏平均 0.56 0.56 0.56 400 加权平均 0.56 0.57 0.56 400
精确率
召回率
F1
分数
支持数
0.66
0.78
0.72
82
0.40
0.30
0.34
64
0.46
91
0.56
0.54
0.55
84
0.71
0.73
79
准确率
0.57
400
宏平均
加权平均
结果只能说尚可,但不算出色。在预测极端评分(1星对应0,5星对应4)时表现明显优于预测中间评分。别担心,至少有两个原因可以解释这种情况:
- 当前的分类任务本身具有挑战性:区分3星和4星评论的难度,显然高于区分积极、消极和中性评论的难度。
- 更重要的是,我们仅使用了2000个样本(其中80%用于模型训练),但这些样本都是包含1024个特征的嵌入向量。将如此少量的高维数据输入分类器,极有可能导致模型严重过拟合。如果你有更多时间运行代码,可以尝试增加几千个样本进行训练。
总结
在传统自然语言处理中,当我们处理文本分类等预测任务的多语言数据时,通常面临两个远非理想的选择:将所有数据翻译成基准语言——这是一个缓慢且昂贵的过程,经常会导致语义的丢失;或者为每种语言单独训练模型。在我们刚刚构建的流程中,繁重的负担由通过Scikit-LLM调用的多语言嵌入模型(BGE-M3)承担,该模型能够透明地将多种语言的文本映射到统一的嵌入空间中。
更多相关内容
- 使用T5实现多语言翻译与…
- 使用LLM嵌入向量和HDBSCAN对非结构化文本进行聚类
- 可解释的文本分类:探针分析…
- 使用Scikit-LLM进行多标签文本分类
- 入门零样本文本分类
- 如何为文本开发多通道CNN模型…