翻译模型(TM):基于短语的统计翻译模型(PBSMT)的构建
文章目录
- 一、PBSMT概述
- 1.1 PBSMT介绍
- 1.2 为什么是“短语”?
- 1.3 PBSMT的优缺点
- 1.4 训练流程总结
- 1.5 与其他翻译模型的对比
- 1.6 PBSMT核心要点总结
- 1.7 典型工具
- 二、 构建流程:四大核心步骤
- 2.1 步骤一:语料库准备与预处理
- 2.2 步骤二:模型训练:短语对齐与翻译知识获取
- 2.3 步骤三:语言模型训练
- 2.4 步骤四:解码器:搜索与生成译文
- 三、python实现PBSMT系统(代码可直接运行)
一、PBSMT概述
1.1 PBSMT介绍
基于短语的统计机器翻译(Phrase-Based Statistical Machine Translation, PBSMT) 是统计机器翻译(SMT)的一种主流方法,它在21世纪前十年占据主导地位。PBSMT的核心思想是将句子分割成连续的词序列(短语),然后对这些短语进行翻译和重组。与基于词的翻译相比,它能够更好地处理局部上下文和多词表达。
随着2014年基于注意力机制的Seq2Seq模型和2017年Transformer模型的兴起,神经机器翻译凭借其强大的端到端学习能力、更流畅的译文和更高的效率,迅速取代了SMT成为主流。然而,SMT的许多核心思想(如对齐、解码搜索、特征组合)至今仍在NLP的其他领域和现代神经模型的架构设计中有着非常重要的作用。
简单来说:PBSMT将翻译单位从单词扩展到短语,能更好地处理词汇重组和局部上下文依赖。
1.2 为什么是“短语”?
在深入构建之前,我们必须理解SMT的革命性思想。
- 传统方法的局限:早期的统计模型(如IBM模型)是“词对词”的翻译。它们只计算一个源语言词翻译成一个目标语言词的概率。这无法处理语言的词序差异,例如,英文的“red car”在法文中是“voiture rouge”(名词在前,形容词在后),逐词翻译会得到错误的“rouge voiture”。
- SMT的突破:SMT认为,翻译的基本单元是短语,而不是单词。一个源语言短语可以被一个等价的目标语言短语替换,同时保持短语内部的词序。例如,短语“red car”整体被替换为“voiture rouge”。这极大地提升了翻译的流畅度和准确性。
因此,构建一个PBSMT模型,本质上就是教会计算机如何“学习”和“应用”这些短语翻译规则。整个过程可以概括为:从海量平行语料中自动学习翻译规则,然后在翻译新句子时,利用这些规则进行搜索和组合,生成最可能的译文。
1.3 PBSMT的优缺点
优点:
- 可解释性强:翻译结果可以追溯到具体的短语翻译,便于调试和修正。
- 灵活性高:可以轻松整合多种知识源,如词典、命名实体识别器等。
- 对数据要求相对较低:在较小规模的平行语料上也能取得不错的效果。
- 处理OOV(Out-of-Vocabulary)能力较好:通过词根、词缀和翻译词典,能处理训练集中未出现的词。
缺点:
- 对齐错误传播:短语对齐是基石,一旦出错,后续所有步骤都会受影响。
- 短语拼接问题:即使每个短语都翻译得好,拼接起来也可能不流畅,缺乏全局的句法一致性。
- 特征工程复杂:需要手动设计和调优多种特征和权重。
- 计算开销大:解码搜索过程非常耗时,难以实现实时翻译。
1.4 训练流程总结
基于短语的统计翻译模型构建可分为以下步骤:
- 数据准备:收集并预处理平行语料(分词、去重、清洗)和单语语料;
- 词对齐:使用GIZA++等工具对平行语料进行词对齐;
- 短语抽取:基于词对齐结果抽取源-目标短语对;
- 翻译模型训练:计算短语概率、重排序概率等特征;
- 语言模型训练:使用目标语言单语语料训练 ( n )-gram语言模型;
- 特征权重优化:通过MERT训练对数线性模型的特征权重;
- 解码配置:设置解码器参数(如短语候选数量、 beam search 大小),生成译文。
1.5 与其他翻译模型的对比
模型类型 | 核心单元 | 优势领域 | 典型工具 |
---|---|---|---|
基于词的统计翻译 | 词 | 低资源语言、简单句式 | GIZA++ |
基于短语的统计翻译 | 短语 | 中等资源语言、通用领域 | Moses、Pharaoh |
神经机器翻译 | 神经网络编码解码 | 高资源语言、流畅度要求高 | TensorFlow、PyTorch |
1.6 PBSMT核心要点总结
1、主要组成部分
- 短语翻译表: 存储源语言短语到目标语言短语的翻译概率
- 语言模型: 确保生成的目标语言句子符合语言规律
- 重排模型: 处理源语言和目标语言的词序差异
- 解码算法: 搜索最优翻译结果
2、关键技术点
- 短语抽取: 从平行语料中提取一致的短语对
- 概率计算: 使用最大似然估计计算各种概率
- 特征函数: 定义影响翻译质量的各种特征
- 搜索算法: 使用束搜索等算法寻找最优翻译
3、与现代神经翻译的区别
- 显式建模: PBSMT显式建模翻译、语言、重排等过程
- 可解释性: 每个组件的作用清晰明确
- 特征工程: 需要手工设计特征函数
- 组合性: 各组件可独立优化和替换
1.7 典型工具
- Moses Toolkit:开源PBSMT系统,支持短语提取、调优和解码全流程。
- Google Translate早期版本:结合PBSMT与规则系统,显著提升翻译质量。
- WMT竞赛:2006-2016年间,PBSMT长期占据基准系统地位,直至神经网络模型崛起。
二、 构建流程:四大核心步骤
构建一个完整的PBSMT系统,通常需要经过以下四个主要阶段:
- 语料库准备与预处理
- 模型训练:对齐与知识获取
- 语言模型训练
- 解码器:搜索与生成译文
下面我们逐一详解每个步骤。
2.1 步骤一:语料库准备与预处理
这是所有工作的基础,数据的质量直接决定了模型的上限。
1. 平行语料库
- 定义:由大量“源语言句子”和“目标语言句子”一一对应组成的文本集合。例如,
{ (S₁, T₁), (S₂, T₂), ..., (Sₙ, Tₙ) }
。 - 要求:规模越大越好(通常需要百万级句子对);质量越高越好(人工翻译的、专业的文本)。
- 示例:
- 源语言 (Source):
The cat sat on the mat.
- 目标语言 (Target):
Le chat s'est assis sur le tapis.
- 源语言 (Source):
2. 语料库预处理
原始语料库不能直接使用,需要经过一系列清洗和标准化处理:
- 文本标准化:统一字符编码(如UTF-8)、处理大小写、统一标点符号。
- 分词:将句子切分成单词或子词单元。这是至关重要的一步。
- 英文:按空格分词即可,
"The cat sat on the mat."
->["The", "cat", "sat", "on", "the", "mat", "."]
- 中文/日文:没有空格,需要使用专门的分词工具,如Jieba (中文)、MeCab (日文)。
"猫坐在垫子上。"
->["猫", "坐", "在", "垫子", "上", "。"]
- 英文:按空格分词即可,
- 标准化处理:将数字、日期、货币等特殊符号进行规范化,便于模型统一处理。例如,将
"$1,000"
转换为<NUM>
标记。
2.2 步骤二:模型训练:短语对齐与翻译知识获取
这是PBSMT的核心,目标是从平行语料中学习到两大知识:短语翻译概率和词对齐信息。
1. 词对齐
- 定义:在源语言句子和目标语言句子之间,建立单词与单词之间的对应关系。一个源词可以对应一个或多个目标词,反之亦然。
- 工具:通常使用GIZA++(或其改进版MGIZA++)工具。它基于IBM的统计翻译模型(特别是Model 4),通过迭代训练来估算对齐概率。
- 输出:对齐文件。它通常以多种格式存在,其中最常用的是
grow-diag-final-and
。这种格式结合了多种启发式规则,能生成更鲁棒的对齐结果。 - 示例:
- 源:
0-0 1-1 2-2 3-3 4-4 5-5 6-6
(完全对齐) - 源:
0-0 1-2 1-3 2-4 3-5 4-6 5-6
(表示源词1
对应目标词2
和3
)
- 源:
2. 短语抽取
- 定义:基于词对齐结果,从句子对中抽取所有可能的短语对。
- 规则:一个短语对
(f, e)
是有效的,当且仅当:f
是源语言句子中的一个连续词序列。e
是目标语言句子中的一个连续词序列。f
中的所有词的对齐点都落在e
的词的覆盖范围内,反之亦然。这个规则保证了短语的“一致性”。
- 示例:
- 句子对:
The cat sat on the mat.
/Le chat s'est assis sur le tapis.
- 词对齐:
The-0, cat-1, sat-2, on-3, the-4, mat-5
/Le-0, chat-1, s'est-2, assis-3, sur-4, le-5, tapis-6
- 有效短语对:
- (
The
,Le
) - (
The cat
,Le chat
) - (
cat sat
,chat s'est
) - (
sat on the mat
,s'est assis sur le tapis
)
- (
- 无效短语对:
- (
The cat
,Le chat s'est
) -> 因为cat
的对齐点是1,而s'est
的对齐点是2,超出了Le
的范围。
- (
- 句子对:
3. 翻译模型
- 定义:计算一个源语言短语
f
被翻译成目标语言短语e
的概率,记为p(e|f)
。 - 计算公式:
p(e|f) = Count(f, e) / Sum_{e'} Count(f, e')
Count(f, e)
:在所有平行句子的抽取结果中,短语对(f, e)
出现的总次数。Sum_{e'} Count(f, e')
:对于固定的源短语f
,所有可能的目标短语e'
出现的次数总和。
- 平滑处理:直接计算会导致很多短语对从未出现过(概率为0)。因此需要使用平滑技术(如Kneser-Ney平滑、Add-k平滑)来给这些未出现的短语对分配一个很小的非零概率,避免模型在解码时“崩溃”。
至此,我们得到了第一个核心模型:翻译模型,它是一个巨大的短语翻译概率表。
2.3 步骤三:语言模型训练
语言模型用于评估一个目标语言句子是否通顺、自然。它独立于翻译过程,只在解码阶段使用。
- 定义:计算一个目标语言词序列
T = t₁, t₂, ..., tₙ
出现的概率,记为p(T)
。 - 计算公式(基于N-gram模型):
p(T) = p(t₁) * p(t₂|t₁) * p(t₃|t₁, t₂) * ... * p(tₙ|tₙ₋₂, tₙ₋₁)
这通常用马尔可夫假设简化为N-gram概率:
p(T) ≈ Π p(tᵢ | tᵢ₋ₙ₊₁ ... tᵢ₋₁)
- 训练:使用大规模的单语目标语料库(例如,维基百科的全部法语文本)来训练。
- 工具:常用工具是SRILM (SRI Language Modeling) 或 KenLM。
- 平滑处理:同样,N-gram模型会遇到数据稀疏问题,也需要进行平滑。
至此,我们得到了第二个核心模型:语言模型,它是一个N-gram概率表。
2.4 步骤四:解码器:搜索与生成译文
这是SMT系统应用所学知识、进行“翻译”的最终环节。给定一个新的源句子 S
,解码器的任务是找到目标句子 T
,使得 T
的概率最大。
1. 评分函数
解码器通过一个线性组合的评分函数来评估每一个候选译文 T
:
Score(T|S) = λ₁ * Log p(T|S) + λ₂ * Log p_lm(T) + λ₃ * Lex(F(T), S)
p(T|S)
:翻译模型概率。它不是直接计算的,而是通过短语翻译模型和** distortion model(扭曲模型)** 来估算。扭曲模型用于惩罚源语言短语和目标语言短语之间过大的位置偏移,模拟语言的词序倾向。p_lm(T)
:语言模型概率。衡量译文T
的流畅度。Lex(F(T), S)
:词典模型。这是一个简单的特征,用于鼓励使用“已知”的短语翻译。如果译文中的某个短语f
在训练时见过,就给予一个奖励。λ₁, λ₂, λ₃
:权重系数。这些权重需要在一个开发集(一个未参与训练的平行语料子集)上进行调优,通常是使用Minimum Error Rate Training (MERT) 算法,目标是让模型在这个开发集上翻译效果最好。
2. 搜索算法
解码的本质是在一个巨大的假设空间中寻找得分最高的译文。这个空间是指数级爆炸的,不可能穷举。因此必须使用高效的搜索算法。
- 核心思想:动态规划 + 启发式搜索。
- 经典算法:A Search (A*算法)* 或 Cube Pruning (立方体剪枝)。
- 搜索过程:
- 将源句子
S
划分成多个不重叠的片段。 - 从左到右,逐步构建译文。在每一步,考虑所有可能的短语翻译。
- 维护一个堆,存放当前部分译文及其得分。
- 在每一步,从堆中取出得分最高的部分译文,然后对其进行扩展(在其后添加一个新的短语翻译),并将新的部分译文放回堆中。
- 通过剪枝策略(如保留得分最高的1000个假设)来控制搜索空间,防止内存溢出。
- 当源句子被完全覆盖时,搜索结束,堆中得分最高的假设就是最终的译文。
- 将源句子
三、python实现PBSMT系统(代码可直接运行)
# -*- encoding: utf-8 -*-
import numpy as np
from collections import defaultdict, Counter
import math
from typing import List, Tuple, Dict
import reclass PBSMTModel:def __init__(self):"""初始化PBSMT模型"""# 翻译模型参数self.phrase_table = {} # 短语翻译表self.translation_probs = defaultdict(lambda: defaultdict(float)) # 翻译概率self.distortion_probs = defaultdict(float) # 重排概率self.language_model = None # 语言模型self.max_phrase_length = 5 # 最大短语长度# 对齐模型self.alignment_counts = defaultdict(Counter)self.alignment_totals = Counter()def preprocess_text(self, text: str) -> List[str]:"""文本预处理Args:text (str): 输入文本Returns:List[str]: 分词后的词列表"""# 简单的分词和预处理text = text.lower()text = re.sub(r'[^\w\s]', ' ', text)tokens = text.split()return tokensdef extract_phrase_pairs(self, source_sent: List[str], target_sent: List[str],alignment: List[Tuple[int, int]]) -> List[Tuple[Tuple, Tuple]]:"""从句子对和对齐信息中提取短语对Args:source_sent (List[str]): 源语言句子target_sent (List[str]): 目标语言句子alignment (List[Tuple[int, int]]): 对齐信息Returns:List[Tuple[Tuple, Tuple]]: 短语对列表"""phrase_pairs = []# 构建对齐矩阵alignment_matrix = np.zeros((len(source_sent), len(target_sent)))for i, j in alignment:if i < len(source_sent) and j < len(target_sent):alignment_matrix[i][j] = 1# 提取短语对for i1 in range(len(source_sent)):for i2 in range(i1, min(i1 + self.max_phrase_length, len(source_sent))):# 找到目标端对应的范围aligned_target_positions = set()for i in range(i1, i2 + 1):for j in range(len(target_sent)):if alignment_matrix[i][j] == 1:aligned_target_positions.add(j)if aligned_target_positions:j1 = min(aligned_target_positions)j2 = max(aligned_target_positions)# 检查一致性约束if self.is_consistent(i1, i2, j1, j2, alignment_matrix):source_phrase = tuple(source_sent[i1:i2 + 1])target_phrase = tuple(target_sent[j1:j2 + 1])phrase_pairs.append((source_phrase, target_phrase))return phrase_pairsdef is_consistent(self, i1: int, i2: int, j1: int, j2: int,alignment_matrix: np.ndarray) -> bool:"""检查短语对是否满足一致性约束Args:i1, i2 (int): 源语言短语范围j1, j2 (int): 目标语言短语范围alignment_matrix (np.ndarray): 对齐矩阵Returns:bool: 是否一致"""# 检查源语言短语内部的对齐点是否都在目标语言短语范围内for i in range(i1, i2 + 1):for j in range(alignment_matrix.shape[1]):if alignment_matrix[i][j] == 1 and not (j1 <= j <= j2):return False# 检查目标语言短语内部的对齐点是否都在源语言短语范围内for j in range(j1, j2 + 1):for i in range(alignment_matrix.shape[0]):if alignment_matrix[i][j] == 1 and not (i1 <= i <= i2):return Falsereturn Trueclass PhraseExtractor:def __init__(self, max_phrase_length: int = 5):self.max_phrase_length = max_phrase_lengthdef extract_phrases(self, source_tokens: List[str], target_tokens: List[str],alignment: List[Tuple[int, int]]) -> Dict[Tuple, Dict[Tuple, int]]:"""从平行语料中提取短语对Args:source_tokens: 源语言分词结果target_tokens: 目标语言分词结果alignment: 对齐信息 [(source_index, target_index), ...]Returns:短语对计数字典"""# 构建对齐矩阵align_matrix = np.zeros((len(source_tokens), len(target_tokens)))for s_idx, t_idx in alignment:if 0 <= s_idx < len(source_tokens) and 0 <= t_idx < len(target_tokens):align_matrix[s_idx][t_idx] = 1phrase_counts = defaultdict(lambda: defaultdict(int))# 提取所有可能的短语对for i1 in range(len(source_tokens)):for i2 in range(i1, min(i1 + self.max_phrase_length, len(source_tokens))):# 找到对应的target范围target_positions = set()for i in range(i1, i2 + 1):for j in range(len(target_tokens)):if align_matrix[i][j] == 1:target_positions.add(j)if target_positions:j1, j2 = min(target_positions), max(target_positions)# 检查一致性if self._is_consistent(i1, i2, j1, j2, align_matrix):source_phrase = tuple(source_tokens[i1:i2 + 1])target_phrase = tuple(target_tokens[j1:j2 + 1])phrase_counts[source_phrase][target_phrase] += 1return phrase_countsdef _is_consistent(self, i1: int, i2: int, j1: int, j2: int,align_matrix: np.ndarray) -> bool:"""检查短语对的一致性"""# 源语言短语内的对齐点必须在目标短语内for i in range(i1, i2 + 1):for j in range(align_matrix.shape[1]):if align_matrix[i][j] == 1 and not (j1 <= j <= j2):return False# 目标语言短语内的对齐点必须在源语言短语内for j in range(j1, j2 + 1):for i in range(align_matrix.shape[0]):if align_matrix[i][j] == 1 and not (i1 <= i <= i2):return Falsereturn Trueclass TranslationModel:def __init__(self):self.phrase_translation_probs = defaultdict(lambda: defaultdict(float))self.reverse_phrase_translation_probs = defaultdict(lambda: defaultdict(float))def train(self, phrase_counts: Dict[Tuple, Dict[Tuple, int]]):"""训练翻译模型Args:phrase_counts: 短语对计数"""# 计算前向翻译概率 P(f|e)for source_phrase, target_phrases in phrase_counts.items():total_count = sum(target_phrases.values())for target_phrase, count in target_phrases.items():self.phrase_translation_probs[source_phrase][target_phrase] = count / total_count# 计算反向翻译概率 P(e|f)reverse_counts = defaultdict(lambda: defaultdict(int))for source_phrase, target_phrases in phrase_counts.items():for target_phrase, count in target_phrases.items():reverse_counts[target_phrase][source_phrase] += countfor target_phrase, source_phrases in reverse_counts.items():total_count = sum(source_phrases.values())for source_phrase, count in source_phrases.items():self.reverse_phrase_translation_probs[target_phrase][source_phrase] = count / total_countdef get_translation_prob(self, source_phrase: Tuple, target_phrase: Tuple) -> float:"""获取翻译概率"""return self.phrase_translation_probs[source_phrase][target_phrase]class DistortionModel:def __init__(self):self.distortion_probs = defaultdict(lambda: defaultdict(float))self.distortion_counts = defaultdict(Counter)self.distortion_totals = Counter()def train(self, source_tokens: List[str], target_tokens: List[str],alignment: List[Tuple[int, int]]):"""训练重排模型Args:source_tokens: 源语言分词target_tokens: 目标语言分词alignment: 对齐信息"""# 简化的重排模型训练# 这里使用距离作为重排特征for s_idx, t_idx in alignment:if s_idx > 0 and t_idx > 0:# 计算相对位置变化distortion = abs(s_idx - t_idx)self.distortion_counts[distortion][1] += 1self.distortion_totals[distortion] += 1def get_distortion_prob(self, distortion: int) -> float:"""获取重排概率"""if self.distortion_totals[distortion] > 0:return self.distortion_counts[distortion][1] / self.distortion_totals[distortion]return 1e-6class LanguageModel:def __init__(self, n: int = 3):self.n = nself.ngram_counts = defaultdict(Counter)self.context_counts = Counter()self.vocab = set()def train(self, sentences: List[List[str]]):"""训练语言模型"""for sentence in sentences:tokens = ['<s>'] * (self.n - 1) + sentence + ['</s>']for i in range(len(tokens) - self.n + 1):ngram = tuple(tokens[i:i + self.n])context = ngram[:-1]word = ngram[-1]self.ngram_counts[context][word] += 1self.context_counts[context] += 1self.vocab.add(word)def probability(self, context: Tuple, word: str) -> float:"""计算语言模型概率"""count_context_word = self.ngram_counts[context][word]count_context = self.context_counts[context]if count_context == 0:return 1e-10return count_context_word / count_contextclass Decoder:def __init__(self, translation_model: TranslationModel,language_model: LanguageModel,distortion_model: DistortionModel):self.translation_model = translation_modelself.language_model = language_modelself.distortion_model = distortion_modelself.beam_size = 10def translate(self, source_sentence: List[str]) -> List[str]:"""翻译源语言句子Args:source_sentence: 源语言句子分词结果Returns:目标语言句子分词结果"""# 简化的贪婪解码# 实际实现中会使用更复杂的搜索算法如栈解码或束搜索target_words = []for source_word in source_sentence:source_tuple = (source_word,)best_translation = Nonebest_prob = 0.0# 寻找最佳翻译translations = self.translation_model.phrase_translation_probs[source_tuple]for target_phrase, prob in translations.items():if prob > best_prob:best_prob = probbest_translation = target_phraseif best_translation:target_words.extend(best_translation)return target_words# 完整的PBSMT系统示例
class PBSMTSystem:def __init__(self):self.phrase_extractor = PhraseExtractor()self.translation_model = TranslationModel()self.distortion_model = DistortionModel()self.language_model = LanguageModel()self.decoder = Nonedef train(self, parallel_corpus: List[Tuple[List[str], List[str], List[Tuple[int, int]]]]):"""训练PBSMT系统Args:parallel_corpus: 平行语料 [(source_tokens, target_tokens, alignment), ...]"""print("开始训练PBSMT系统...")# 1. 提取短语对print("1. 提取短语对...")all_phrase_counts = defaultdict(lambda: defaultdict(int))target_sentences = []for source_tokens, target_tokens, alignment in parallel_corpus:phrase_counts = self.phrase_extractor.extract_phrases(source_tokens, target_tokens, alignment)# 合并短语计数for source_phrase, target_phrases in phrase_counts.items():for target_phrase, count in target_phrases.items():all_phrase_counts[source_phrase][target_phrase] += counttarget_sentences.append(target_tokens)# 2. 训练翻译模型print("2. 训练翻译模型...")self.translation_model.train(all_phrase_counts)# 3. 训练语言模型print("3. 训练语言模型...")self.language_model.train(target_sentences)# 4. 训练重排模型print("4. 训练重排模型...")for source_tokens, target_tokens, alignment in parallel_corpus:self.distortion_model.train(source_tokens, target_tokens, alignment)# 5. 初始化解码器self.decoder = Decoder(self.translation_model, self.language_model, self.distortion_model)print("PBSMT系统训练完成!")def translate(self, source_sentence: str) -> str:"""翻译句子Args:source_sentence: 源语言句子Returns:目标语言句子"""if not self.decoder:raise ValueError("系统未训练,请先调用train方法")# 预处理source_tokens = source_sentence.lower().split()# 解码target_tokens = self.decoder.translate(source_tokens)# 后处理return ' '.join(target_tokens)# 使用示例
def demo_pbsmt():# 构造小型训练数据parallel_corpus = [# (源语言分词, 目标语言分词, 对齐信息[(源索引, 目标索引)])(['the', 'cat', 'sat'], ['猫', '坐在'], [(0, 0), (1, 0), (2, 1)]),(['the', 'dog', 'ran'], ['狗', '跑了'], [(0, 0), (1, 0), (2, 1)]),(['a', 'cat', 'ran'], ['一只', '猫', '跑了'], [(0, 0), (1, 1), (2, 2)]),(['the', 'dog', 'sat'], ['狗', '坐'], [(0, 0), (1, 0), (2, 1)]),]print("=== PBSMT系统演示 ===\n")# 创建并训练PBSMT系统pbsmt = PBSMTSystem()pbsmt.train(parallel_corpus)# 测试翻译test_sentences = ["the cat sat","a dog ran","the dog sat"]print("\n翻译结果:")for sentence in test_sentences:translation = pbsmt.translate(sentence)print(f"源语言: {sentence}")print(f"目标语言: {translation}")print()if __name__ == "__main__":demo_pbsmt()
总结:基于短语的统计机器翻译代表了统计方法在机器翻译领域的成熟阶段,虽然已被神经机器翻译超越,但其核心思想(如注意力机制与短语对齐的关联)仍在现代NMT中有所体现。理解PBSMT对于全面掌握机器翻译技术的发展脉络具有重要意义。