阿拉伯语自然语言处理与英语、汉语等语言的处理方式不同。主要原因在于阿拉伯语具有较强的形态复杂性,词语内部经常包含前缀、后缀、冠词、代词附着形式以及丰富的屈折变化。如若不进行分词、规范化和词形处理等规范化操作,后续的词频统计、文本分类、命名实体识别、信息检索和语义分析都会受到影响。第一类是语言分析工具,例如 CAMeL Tools 和 Farasa。其二者主要负责文本规范化、分词、词干提取、词形分析、词性标注和命名实体识别。第二类是预训练语言模型,例如 AraBERT 和 MARBERT。主要用于文本分类、情感分析、语义表示、问答、NER 微调等任务。AraBERT 和 MARBERT 属于 BERT 系列的 Encoder-only 模型而非生成式大语言模型,简而述之其二者主要功能是文本理解,而不是长文本生成。conda create -n arabic_nlp python=3.11conda activate arabic_nlp
python -m venv arabic_nlpsource arabic_nlp/bin/activate
python -m venv arabic_nlparabic_nlp\Scripts\activate
pip install -U pippip install transformers torch
若后续使用 HuggingFace 模型,需要保证网络能够访问模型仓库,或者提前下载模型到本地。三、CAMeL Tools:Python 阿语 NLP 综合工具箱CAMeL Tools 是一个面向阿拉伯语自然语言处理的 Python 工具套件,适用于文本规范化、分词、词形分析、词性标注、命名实体识别、情感分析和方言识别等任务。适合作为阿语 NLP 项目的基础文本清洗和语料预处理sudo apt-get updatesudo apt-get install cmake libboost-all-dev
一般测试阶段使用 light 即可。如果需要更多组件,再安装 all。下面代码只依赖 CAMeL Tools 的工具函数from camel_tools.utils.dediac import dediac_arfrom camel_tools.utils.normalize import ( normalize_alef_ar, normalize_alef_maksura_ar, normalize_teh_marbuta_ar, )def normalize_arabic_text(text: str) -> str: """ 对阿拉伯语文本进行基础规范化。 处理内容: 1. 去除元音符号; 2. 统一不同形式的 ألف; 3. 统一 ألف مقصورة; 4. 规范化 تاء مربوطة。 """ text = dediac_ar(text) text = normalize_alef_ar(text) text = normalize_alef_maksura_ar(text) text = normalize_teh_marbuta_ar(text) return textif __name__ == "__main__": sample = "إِنَّ اللُّغَةَ العَرَبِيَّةَ جَمِيلَةٌ." result = normalize_arabic_text(sample) print(result)
这类规范化适合文本分类、检索、词频统计等任务。但如研究目标涉及字形差异、古典文本、元音符号或精细词法现象,就不应过度规范化。from camel_tools.tokenizers.word import simple_word_tokenizedef tokenize_arabic(text: str) -> list[str]: """ 使用 CAMeL Tools 进行简单词语切分 """ return simple_word_tokenize(text)if __name__ == "__main__": text = "تعد اللغة العربية من أهم اللغات في العالم." tokens = tokenize_arabic(text) print(tokens)
此法适合基础 tokenization,需要更深入的词形分析的话建议使用 CAMeL Tools 的 morphological analysis 或 disambiguation 模块。Farasa 是阿拉伯语 NLP 中常用的工具,主要用于分词、词干提取、词性标注、命名实体识别、词形还原和加元音符号等任务。在 Python 中使用 Farasa 常用两种方式:第一种: farasapy,即 Python 包装库第二种:使用subprocess调用 Farasa Java JAR 文件 | | |
|---|
| | 首次运行可能自动下载资源;依赖 Java;封装层可能受环境影响 |
|---|
| | 需要手动准备 JAR 文件和路径;需要理解命令行参数 |
|---|
Farasa 底层依赖 Java。先检查 Java 是否可用:系统能输出 Java 版本的话说明 Java 已加入 PATH。sudo apt-get updatesudo apt-get install openjdk-11-jdk
确认 java 命令可以在 PowerShell 或 CMD 中运行。from farasa.segmenter import FarasaSegmenterdef farasa_segment(text: str) -> str: """ 使用 farasapy 调用 Farasa Segmenter。 interactive=True 适合多次处理短文本。 """ segmenter = FarasaSegmenter(interactive=True) return segmenter.segment(text)if __name__ == "__main__": text = "ذهبت إلى الجامعة الأردنية صباح اليوم." result = farasa_segment(text) print(result)
第一次运行时,farasapy 可能会检查 Java 环境并下载 Farasa 工具资源from farasa.stemmer import FarasaStemmerdef farasa_stem(text: str) -> str: """ 使用 farasapy 调用 Farasa Stemmer。 """ stemmer = FarasaStemmer(interactive=True) return stemmer.stem(text)if __name__ == "__main__": text = "الطلاب يدرسون اللغة العربية في الجامعة." result = farasa_stem(text) print(result)
只是快速测试 Farasa,优先使用 farasapy。短文本、多次调用:使用 interactive=True;大文件、一次性处理:使用 standalone 模式,或直接调用 Java JAR;正式部署:优先考虑手动管理 JAR 路径,减少自动下载带来的不确定性。方法二:Python 直接调用 Farasa Java JAR这种方式适合工程项目,相比之下的特点是 Python 不通过 farasapy,而是直接调用本地 Farasa JAR 文件。Farasa Segmenter 的常见命令行形式是:java -jar farasaSeg.jar -i input.txt -o output.txt
java -Dfile.encoding=UTF-8 -jar Farasa.jar -i input.txt -o output.txt
因此,Python 中可以用 subprocess.run() 进行调用。project/├── run_farasa_java.py└── farasa/└── farasaSeg.jar
如果使用的是其他文件名,例如 Farasa.jar,只需要修改代码中的 JAR 路径。2. Python 调用 Java JAR 的完整代码from pathlibimport Pathimport subprocessimport tempfiledef run_farasa_jar( text: str, jar_path: str, java_cmd: str = "java", farasa_data_dir: str | None = None, timeout: int = 60,) -> str: """ 使用 Python subprocess 调用 Farasa Java JAR。 参数: text: 输入的阿拉伯语文本。 jar_path: Farasa JAR 文件路径 java_cmd: Java 命令,默认使用系统 PATH 中 java farasa_data_dir: 可选。如需要 FarasaDataDir,可传入数据目录。 timeout: 超时时间,单位秒。 返回: Farasa 输出文本。 """ jar = Path(jar_path).expanduser().resolve() if not jar.exists(): raise FileNotFoundError(f"找不到 Farasa JAR 文件:{jar}") with tempfile.TemporaryDirectory() as tmpdir: tmpdir_path = Path(tmpdir) input_file = tmpdir_path / "input.txt" output_file = tmpdir_path / "output.txt" input_file.write_text(text, encoding="utf-8") cmd = [ java_cmd, "-Dfile.encoding=UTF-8", "-jar", str(jar), "-i", str(input_file), "-o", str(output_file), ] env = None if farasa_data_dir is not None: import os env = os.environ.copy() env["FarasaDataDir"] =str(Path(farasa_data_dir).expanduser().resolve()) completed = subprocess.run( cmd, cwd=str(jar.parent), env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding="utf-8", timeout=timeout, ) if completed.returncode != 0: raise RuntimeError( "Farasa Java 调用失败。\n" f"命令:{' '.join(cmd)}\n" f"标准输出:{completed.stdout}\n" f"错误输出:{completed.stderr}" ) if not output_file.exists(): raise FileNotFoundError( "Farasa 没有生成输出文件。请检查 JAR 文件版本和命令行参数。" ) return output_file.read_text(encoding="utf-8").strip()if __name__ == "__main__": sample_text = "ذهبت إلى الجامعة الأردنية صباح اليوم." result = run_farasa_jar( text=sample_text, jar_path="./farasa/farasaSeg.jar", ) print(result)
3. 如果 JAR 需要 FarasaDataDir有些 Farasa 版本需要设置数据目录,可以这样写:result = run_farasa_jar( text="ذهبت إلى الجامعة الأردنية صباح اليوم.", jar_path="./farasa/Farasa.jar", farasa_data_dir="./farasa/FarasaData",)
直接调用 Java JAR 的优点是:不依赖 farasapy 的自动下载逻辑;可以固定 JAR 版本;便于处理大文件;便于记录命令行日志。如果提示找不到命令,需要安装 JDK 并加入 PATH。jar_path="./farasa/farasaSeg.jar"
如果报错中出现数据路径相关信息,需要设置 FarasaDataDirAraBERT 是基于 BERT 架构的阿拉伯语预训练语言模型,主要用于文本理解任务,包括文本分类、情感分析、命名实体识别、问答和语义匹配。AraBERT 适合用于分类、判断和编码文本语义。pip install transformers torch arabert
from arabert import ArabertPreprocessor def preprocess_with_arabert(text: str, model_name: str) -> str:"""使用 AraBERT 官方预处理器处理文本。""" preprocessor = ArabertPreprocessor(model_name=model_name) return preprocessor.preprocess(text) if __name__ == "__main__": model_name = "aubmindlab/bert-base-arabertv2" text = "ولن نبالغ إذا قلنا إن اللغة العربية لغة غنية ومعقدة." processed = preprocess_with_arabert(text, model_name) print(processed)
下面代码将会使用 HuggingFace Transformers 加载 AraBERTimport torchfrom transformers import AutoTokenizer, AutoModeldef encode_with_arabert(text: str, model_name: str = "aubmindlab/bert-base-arabertv2"): """ 使用 AraBERT 编码阿语文本。 返回 last_hidden_state。 """ tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModel.from_pretrained(model_name) inputs = tokenizer( text, return_tensors="pt", truncation=True, padding=True, ) model.eval() with torch.no_grad(): outputs = model(**inputs) return outputs.last_hidden_stateif __name__ == "__main__": text = "اللغة العربية لغة ذات نظام صرفي غني." hidden_states = encode_with_arabert(text) print(hidden_states.shape)
torch.Size([1, sequence_length, 768])
sequence_length 表示分词后的序列长度;下面代码可以正确加载模型结构,但分类头是随机初始化的from transformers import AutoTokenizer, AutoModelForSequenceClassificationdef load_arabert_classifier( model_name: str = "aubmindlab/bert-base-arabertv2", num_labels: int = 3,): """ 加载 AraBERT 分类模型结构。 注意:如果使用基础模型,分类头需要训练。 """ tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForSequenceClassification.from_pretrained( model_name, num_labels=num_labels, ) return tokenizer, modelif __name__ == "__main__": tokenizer, model = load_arabert_classifier(num_labels=3) text = "هذا المنتج ممتاز جدا." inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True) outputs = model(**inputs) print(outputs.logits)
六、MARBERT:方言阿语与社交媒体文本理解模型MARBERT 是面向阿拉伯语的 BERT 类预训练模型,重点覆盖方言阿语和社交媒体文本。它适合处理推文、评论、口语化表达、方言混合文本等场景。如果文本是现代标准阿语新闻,AraBERT 通常更直接;如果文本来自社交媒体、短评论或方言材料,MARBERT 更适合。pip install transformers torch
import torchfrom transformers import AutoTokenizer, AutoModeldef encode_with_marbert(text: str, model_name: str = "UBC-NLP/MARBERT"): """ 使用 MARBERT 编码阿语文本。 返回 last_hidden_state。 """ tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModel.from_pretrained(model_name) inputs = tokenizer( text, return_tensors="pt", truncation=True, padding=True, ) model.eval() with torch.no_grad(): outputs = model(**inputs) return outputs.last_hidden_stateif __name__ == "__main__": text = "الخدمة كتير ممتازة والأسعار مناسبة." hidden_states = encode_with_marbert(text) print(hidden_states.shape)
该代码会输出 MARBERT 对输入文本的隐藏层表示MARBERT Masked Language Model 示例MARBERT 是 masked language model,可以进行掩码预测:import torchfrom transformers import AutoTokenizer, AutoModelForMaskedLMdef predict_mask_with_marbert( text: str, model_name: str = "UBC-NLP/MARBERT", top_k: int = 5,): """ 使用 MARBERT 对 [MASK] 位置进行预测。 """ tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForMaskedLM.from_pretrained(model_name) inputs = tokenizer(text, return_tensors="pt") mask_token_index = torch.where(inputs["input_ids"] == tokenizer.mask_token_id)[1] if len(mask_token_index) == 0: raise ValueError("输入文本中必须包含 [MASK]。") model.eval() with torch.no_grad(): outputs = model(**inputs) mask_logits = outputs.logits[0, mask_token_index, :] top_tokens = torch.topk(mask_logits, top_k, dim=1).indices[0].tolist() return [tokenizer.decode([token]).strip() for token in top_tokens]if __name__ == "__main__": text = "الجو اليوم [MASK] جدا." predictions = predict_mask_with_marbert(text) print(predictions)
输出是模型认为最可能填入 [MASK] 的若干 token具体结果会随模型版本、tokenizer 和运行环境略有差异原始阿语文本↓CAMeL Tools 规范化↓Farasa 分词或词干提取↓保存为 JSON / CSV / SQLite↓进入统计分析或检索系统
现代标准阿语文本
↓
必要的文本清洗
↓
AraBERT tokenizer
↓
AraBERT 模型
↓
分类器或向量表示
社交媒体文本↓轻度清洗↓MARBERT tokenizer↓MARBERT 模型↓分类器或向量表示
社交媒体文本不宜过度规范化,因为重复字母、表情、拼写变体、混合语言等信息可能具有情感或语用价值。建议使用 Python 直接调用 Java JAR 的方式Python 输入文本
↓
写入临时 UTF-8 文件
↓
subprocess 调用 java -jar farasaSeg.jar
↓
读取输出文件
↓
返回 Python 字符串
CAMeL Tools 适合作为阿语文本清洗、规范化和基础 NLP 处理工具。Farasa 适合分词、词干提取和词法处理。Python 中可以使用 farasapy,也可以直接通过 subprocess 调用 Java JAR。前者适合快速实验,后者适合工程部署。AraBERT 适合现代标准阿语文本理解任务,如分类、情感分析、NER 微调和语义匹配。MARBERT 则是适合方言阿语、推文、评论和社交媒体文本分析。如果项目以 Python 为主,可以采用以下组合:CAMeL Tools:规范化与基础处理Farasa:分词与词干提取AraBERT:现代标准阿语文本理解MARBERT:方言和社交媒体文本理解
AraBERT 和 MARBERT 本身承担理解任务,不承担生成任务