Phân đoạn tiếng Trung bằng Python

Việc phân đoạn tiếng Trung là một lĩnh vực quan trọng trong xử lý ngôn ngữ tự nhiên. Bài viết này sẽ tập trung vào việc triển khai các phương pháp phân đoạn dựa trên từ điển, bao gồm khớp chính hướng tối đa (Forward Maximum Matching - FMM), khớp ngược hướng tối đa (Reverse Maximum Matching - RMM) và khớp hai chiều tối đa (Bidirectional Maximum Matching - BDMM).

1. Khớp chính hướng tối đa (FMM)

FMM hoạt động bằng cách:

  • Tìm từ dài nhất trong từ điển.
  • Cắt chuỗi từ trái sang phải với độ dài bằng từ dài nhất, kiểm tra xem có tồn tại trong từ điển không. Nếu có, từ đó được tách ra; nếu không, giảm độ dài chuỗi đi 1 ký tự và lặp lại quá trình.

2. Khớp ngược hướng tối đa (RMM)

RMM tương tự như FMM nhưng thực hiện cắt từ phải sang trái:

  • Tìm từ dài nhất trong từ điển.
  • Cắt chuỗi từ phải sang trái với độ dài bằng từ dài nhất, kiểm tra xem có tồn tại trong từ điển không. Nếu có, từ đó được tách ra; nếu không, tăng độ dài chuỗi lên 1 ký tự và lặp lại quá trình.

3. Khớp hai chiều tối đa (BDMM)

BDMM so sánh kết quả của FMM và RMM:

  • Nếu số lượng từ cắt ra khác nhau, chọn phương án có ít từ hơn.
  • Nếu số lượng từ bằng nhau, ưu tiên phương án có ít từ đơn âm hơn.

Mã nguồn

1. Tải từ điển


# -*- coding:utf-8 -*-
def load_dictionary(path):
    dictionary = {}
    max_length = 0
    with open(path, 'r', encoding='utf8') as file:
        for line in file:
            word = line.strip()
            if word:
                dictionary[word] = "property"  # Thay thế bằng thuộc tính thực tế nếu cần
                max_length = max(max_length, len(word))
    return dictionary, max_length

2. Phương pháp FMM


def forward_maximum_matching(text, dictionary, max_length):
    result = []
    start = 0
    while start < len(text):
        matched = False
        for length in range(max_length, 0, -1):
            end = start + length
            if end > len(text):
                continue
            segment = text[start:end]
            if segment in dictionary:
                result.append(segment)
                start = end
                matched = True
                break
        if not matched:
            start += 1
    return result

3. Phương pháp RMM


def reverse_maximum_matching(text, dictionary, max_length):
    result = []
    end = len(text)
    while end > 0:
        matched = False
        for length in range(max_length, 0, -1):
            start = end - length
            if start < 0:
                continue
            segment = text[start:end]
            if segment in dictionary:
                result.insert(0, segment)
                end = start
                matched = True
                break
        if not matched:
            end -= 1
    return result

4. Phương pháp BDMM


def bidirectional_maximum_matching(text, dictionary, max_length):
    fmm_result = forward_maximum_matching(text, dictionary, max_length)
    rmm_result = reverse_maximum_matching(text, dictionary, max_length)
    
    if len(fmm_result) < len(rmm_result):
        return fmm_result
    elif len(fmm_result) > len(rmm_result):
        return rmm_result
    else:
        fmm_single_words = sum(1 for word in fmm_result if len(word) == 1)
        rmm_single_words = sum(1 for word in rmm_result if len(word) == 1)
        return fmm_result if fmm_single_words <= rmm_single_words else rmm_result

5. Ví dụ sử dụng


if __name__ == "__main__":
    dict_path = "../resource/dict.txt"
    dictionary, max_length = load_dictionary(dict_path)
    sample_text = "各国有各国的困难…"
    
    print("Kết quả FMM:", forward_maximum_matching(sample_text, dictionary, max_length))
    print("Kết quả RMM:", reverse_maximum_matching(sample_text, dictionary, max_length))
    print("Kết quả BDMM:", bidirectional_maximum_matching(sample_text, dictionary, max_length))

Thẻ: python NLP TextProcessing

Đăng vào ngày 30 tháng 7 lúc 21:19