Dịch máy thống kê dựa trên cụm

Một phần của tài liệu Tìm hiểu mô hình ngôn ngữ sử dụng phương pháp bloom filter (Trang 51)

Hình 9: Minh họa dịch máy thống kê dựa vào cụm

Trong dịch dựa trên cụm, một chuỗi các từ liên tiếp (cụm) được dịch sang ngôn ngữ đích, với độ dài cụm ngôn ngữ nguồn và đích có thể khác nhau. Hình 9 minh họa phương pháp dịch cụm: câu vào được chia thành một số cụm; từng cụm một được dịch sang ngôn

Tiền xử lý Ngôn ngữ nguồn ( f ) Bộ giải mã B Hậu xử lý Mô hình ngôn ngữ Pr(e) Mô hình dịch Pr(f | e) Ngôn ngữ đích ( e )

That songwriter wrote many romantic songs

ngữ đích; và sau đó các cụm được đảo trật tự theo một cách nào đó rồi ghép với nhau. Cuối cùng ta thu được câu dịch trong ngôn ngữ đích.

Giả sử ta gọi ngôn ngữ nguồn là f và ngôn ngữ đích là e, chúng ta sẽ cố gắng tối đa hóa xác suất Pr( | )f e với mong muốn có được bản dịch tốt nhất. Thực tế là tồn tại rất nhiều bản dịch đúng cho cùng một câu, mục đích của ta là tìm ra câu ngôn ngữ e phù hợp nhất khi cho trước câu ngôn ngữ nguồn f. Dịch dựa vào cụm sử dụng mô hình kênh nhiễu, áp dụng công thức Bayes ta có: arg max Pr( | ) Pr( ) arg max Pr( | ) Pr( ) e e f e e e f f =

Do Pr(f) là không đổi đối với e, vấn đề trở thành việc tìm câu e nhằm tối đa hóa

Pr( | ) Pr( )f e e . Việc xây dựng mô hình ngôn ngữ cần sử dụng một ngữ liệu đơn ngữ lớn, trong khi đó mô hình dịch lại cần đến ngữ liệu song ngữ tốt. Bộ giải mã được sử dụng để chia câu nguồn thành các cụm và sinh ra các khả năng dịch có thể cho mỗi cụm nhờ sự trợ giúp của bảng cụm (phrase table).

Để sinh ra được câu dịch, câu nguồn được chia thành I cụm liên tiếp f1I. Chúng ta giả sử rằng phân phối xác suất là như nhau đối với các cụm này. Mỗi cụm fi trong f1I

được dịch thành cụm tương ứng trong ngôn ngữ đích ei. Các cụm trong ngôn ngữ đích có thể đảo ví trí cho nhau. Quá trình dịch cụm được mô hình hóa bởi phân phối xác suất

) | (fi ei

φ .

Việc đảo ví trí (reodering) của các cụm đầu ra được mô hình bởi phân phối xác suất

) (aibi−1

d , trong đó ai đại diện cho vị trí bắt đầu của cụm trong câu nguồn được dịch thành cụm thứ i trong câu đích, và bi-1là ký hiệu chỉ vị trí kết thúc của cụm trong câu nguồn được dịch thành cụm (i-1) trong câu đích. Ở đây chúng ta sử dụng mô hình đảo cụm rất đơn giản như sau:

| 1 | 1) 1 ( − − = aibi− − i i b a d α

Để xác định độ dài thích hợp của câu dịch, chúng ta đưa thêm vào thừa số ω khi sinh ra câu trong ngôn ngữ đích. Thừa số này sẽ được tối ưu qua quá trình tìm kiếm câu dịch tối ưu. Thừa số này càng lớn hơn 1 thì độ dài của câu trong ngôn ngữ đích càng dài.

Nói tóm lại, câu dịch tốt nhất ebest được sinh ra từ câu nguồn theo mô hình trong [22] là:

( ) es arg max Pr( | ) arg max Pr( | ) Pr ( ) length e

b t e e LM

e = e f = f e e ω ở đây Pr( | )f e được phân tích thành:

1 1 1 1 Pr( I | I) I ( | ) ( ) i i i i i f e ϕ f e d a b− = =∏ − 4.1.3 Điểm BLEU

Đánh giá chất lượng các hệ thống dịch có thể được thực hiện thủ công bởi con người hoặc tự động. Quá trình đánh giá thủ công cho điểm cho các câu dịch dựa trên sự trôi chảy và chính xác của chúng. Phần lớn mọi người cho rằng đây là phương pháp đánh giá chính xác nhất. Thế nhưng công việc đánh giá thủ công này lại tiêu tốn quá nhiều thời gian, đặc biệt khi cần so sánh nhiều mô hình ngôn ngữ, nhiều hệ thống khác nhau. Công bằng mà nói, mỗi phương pháp đều có ưu nhược điểm riêng. Tuy đánh giá tự động không thể phản ánh được hết mọi khía cạnh của chất lượng dịch, nhưng nó có thể nhanh chóng cho ta biêt: chất lượng của hệ dịch ở tầm nào, có tăng lên hay không sau khi cải tiến hoặc thay đổi một tham số nào đó. Trong thực tế, hai phương pháp này vẫn được sử dụng đồng thời, và điểm BLEU là độ đo chất lượng hệ dịch phổ biến nhất hiện nay, được đề xuất bởi Papineni năm 2002 [32].

BLEU tính điểm bằng cách đối chiếu kết quả dịch với tài liệu dịch tham khảo và tài liệu nguồn. Mặc dù [9] chỉ ra rằng điểm BLEU thường không thực sự tương quan với đánh giá thủ công của con người với các loại hệ thống khác nhau, thế nhưng vẫn có thể khá chính xác để đánh giá trên cùng một hệ thống, hoặc những hệ thống tương tự nhau. Chính vì vậy, trong khóa luận này, điểm BLEU được sử dụng làm thước đo chất lượng dịch, từ đó so sánh các loại mô hình ngôn ngữ khác nhau.

4.2 Baseline system

Chúng tôi xây dựng hệ thống dịch sử dụng GIZA++ 2.0 8 [29], SRILM [34] và bộ huấn luyện cực tiểu hóa tỉ lệ lỗi (Minimum Error Rate Training – MERT) [27] để gióng hàng các từ, xây dựng mô hình ngôn ngữ, tối ưu hóa các trọng số sử dụng trong quá trình dịch. Mô hình ngôn ngữ sử dụng trong huấn luyện là một mô hình 3-gram với thuật toán làm mịn Kneser-Ney cải tiến. MERT được thực hiện trên tập ngữ liệu phát triển được sử dụng tại WMT năm 2008, gồm 2000 cặp câu song ngữ Đức – Anh (thống kê ở bảng 7). Bảng cụm được tạo ra sau quá trình huấn luyện có dung lượng 800.8 MB; một bảng hỗ trợ đảo vị trí từ (lexical reordering table) [15][38] cũng được tạo ra có dung lượng 186.5 MB.

Trong quá trình xây dựng và thử nghiệm trên hệ thống dịch này, chúng tôi có sử dụng một số script hỗ trợ 9 bao gồm:

- Bộ tách từ tokenizer.perl

- Script chuyển toàn bộ văn bản sang chữ thường lowercase.perl

- SGML-Wrapper có nhiệm vụ đóng gói dữ liệu theo định dạng XML của hệ thống tính điểm NIST BLEU : wrap-xml.perl

- Script NIST MTeval version 11b mteval-v11b.pl dùng để tính điểm BLEU

4.3 Ngữ liệu

Hệ thống dịch được huấn luyện sử dụng ngữ liệu Europarl [18] song ngữ Đức – Anh version 3 gồm 1.2 triệu câu trong mỗi ngôn ngữ. Thế nhưng sau khi loại bỏ bớt các câu có độ dài lớn hơn 40 từ tương ứng ở cả hai ngôn ngữ, chỉ còn khoảng gần 1 triệu cặp câu (mất 268,000 cặp câu). Nguyên nhân ta cần phải làm như vậy là vì quá trình huấn luyện bằng GIZA++ tốn rất nhiều thời gian nếu có nhiều câu dài. Thống kê đầy đủ về ngữ liệu này sau khi lọc có thể được tham khảo ở bảng 7.

Mô hình ngôn ngữ tiếng Anh dùng trong huấn luyện hệ thống dịch được xây dựng từ ngữ liệu Europarl đơn ngữ tiếng Anh (xem thống kê chi tiết ở bảng 6).

8http://code.google.com/p/giza-pp/

9 Download từ http://www.statmt.org/wmt08/scripts.tgz

Bảng 6: Thống kê chi tiết ngữ liệu Europarl đơn ngữ tiếng Anh dùng để xây dựng LM huấn luyện hệ thống dịch

Dung lượng 200.6 MB

Gzip 62.7 MB

Số lượng câu 1,412,546

Số lượng từ 38,280,717

Độ dài trung bình câu 27

Cỡ từ điển (từ) 100,795

Bảng 7: Thống kê ngữ liệu song ngữ Đức – Anh dùng để huấn luyện, phát triển và đánh giá 10 hệ thống dịch

Tiếng Đức Tiếng Anh

Huấn luyện Số lượng câu 997,575

Số lượng từ 20,341,901 21,432,529

Độ dài câu trung bình (từ) 20.4 21.5

Cỡ từ điển (từ) 226,387 74,581

Phát triển Số lượng câu 2000

Số lượng từ 55,118 58,761

Độ dài câu trung bình (từ) 27.6 29.4

Cỡ từ điển (từ) 8,796 6,118

Đánh giá Số lượng câu 2000

Số lượng từ 54,232 58,055

Độ dài câu trung bình (từ) 27.1 29.0

Cỡ từ điển (từ) 8,669 6058

4.4 Kết quả thử nghiệm

Hệ thống dịch được thử nghiệm với các mô hình ngôn ngữ SRILM và RandLM, với việc dịch 2000 câu tiếng Đức. Thời gian để dịch hết 2000 câu này khi sử dụng mô hình ngôn ngữ SRILM là 98 phút, đối với BloomMap-LM là 124 phút và với LF-BF-LM là 117 phút. Như vậy là khi sử dụng các loại BF-LM, thời gian dịch lâu hơn khi sử dụng mô hình ngôn ngữ chuẩn khoảng 1.3 lần. Khoảng thời gian dịch lâu hơn này không phải là tồi khi ta xem xét đến phần bộ nhớ đã tiết kiệm được nhờ sử dụng các LM dựa trên Bloom Filter.

Bảng 8: Thời gian dịch 2000 câu tiếng khi sử dụng các loại LM khác nhau

Loại LM Thời gian dịch (phút)

SRI-LM 98

BloomMap-LM 124

LF-BF-LM 117

Hình 9: Định dạng XML của NIST MT

Để đánh giá kết quả dịch, chúng tôi sử dụng điểm BLEU. Do đó, sau khi dịch, kết quả được đóng gói lại theo định dạng XML của hệ thống tính điểm NIST MT. Hình 9 là một ví dụ của định dạng XML này. Script MTeval sử dụng ba đầu vào để đánh giá kết quả dịch: file chứa văn bản ở ngôn ngữ nguồn, file chứa kết quả dịch ở ngôn ngữ đích và một file dịch chuẩn dùng để tham chiếu.

Điểm BLEU cho kết quả dịch với các LM khác nhau được thể hiện trong bảng 9. Các mô hình ngôn ngữ này đều được xây dựng từ tập ngữ liệu Set 4 gồm 1 GB ngữ liệu tiếng Anh. Nhìn vào kết quả này ta có thể thấy rằng nếu cùng sử dụng mô hình 3-gram thì hệ thống dịch sử dụng mô hình ngôn ngữ SRI-LM có điểm cao hơn khi sử dụng mô hình các mô hình BF-LM. Nhưng sự chênh lệch này không phải là lớn, trong trường hợp này là

<tstset setid="wmt08-de-en-nc-test" srclang="German" trglang="English"> <DOC docid="Speigel-doc1" sysid="UMD_de_en_primary">

<seg id="1"> TRANSLATED ENGLISH TEXT </seg> <seg id="2"> TRANSLATED ENGLISH TEXT </seg> ...

</DOC>

<DOC docid="Speigel-doc2" sysid="UMD_de_en_primary"> <seg id="13"> TRANSLATED ENGLISH TEXT </seg>

<seg id="14"> TRANSLATED ENGLISH TEXT </seg> ...

</DOC> </tstset>

SRILM cho điểm cao hơn BloomMap-LM 3.5%, cao hơn LF-BF-LM 4%, nên ta có thể coi các điểm số này là tương đương nhau với cùng bậc n-gram. Thế nhưng, như đã nói ở phần trên, với cấu hình máy tính dùng cho thử nghiệm, ta chỉ có thể xây dựng mô hình ngôn ngữ 4-gram nếu sử dụng BF-LM. Sử dụng mô hình ngôn ngữ 4-gram BF-LM này (sử dụng cấu trúc dữ liệu Bloom Map) trong hệ thống dịch cho điểm số là 19.93, cao hơn rõ rệt khi sử dụng mô hình ngôn ngữ SRI-LM với 18.25 điểm.

Bảng 9: Điểm BLEU cho kết quả dịch với các LM khác nhau

Cỡ LM Điểm BLEU

SRI-LM 3-gram 893.4 MB 18.25

BloomMap-LM 3-gram 138.8 MB 17.63

LF-BF-LM 3-gram 181.5 MB 17.55

BloomMap-LM 4-gram 302.2 MB 19.93

Ta đã biết rằng dung lượng các LF-BF-LM rõ ràng là cao hơn BloomMap-LM. Nhưng qua thử nghiệm trong thực tế dịch, điểm BLEU của hệ thống sử dụng LF-BF-LM không hề cao hơn so với khi sử dụng BloomMap-LM (với cùng bậc n-gram). Thậm chí sử dụng BloomMap-LM điểm số còn nhỉnh hơn một chút. Hơn thế nữa, thời gian dịch khi sử dụng 2 loại mô hình này có sự chênh lệch không lớn. Nhìn vào kết quả này, ta có thể thấy rõ ưu thế của cấu trúc dữ liệu Bloom Map so với cấu trúc dữ liệu Log-Frequency Bloom Filter, vừa sử dụng ít bộ nhớ hơn, vừa hiệu quả hơn.

Kết luận

Qua các chương của khóa luận, chúng tôi đã trình bày lý thuyết và thử nghiệm các mô hình ngôn ngữ xây dựng dựa trên hai cấu trúc dữ liệu Bloom Filter là Log-Frequency Bloom Filter và Bloom Map. Đây là các cấu trúc dữ liệu có ưu điểm nổi bật là khả năng tiết kiệm đáng kể bộ nhớ nhờ có sự chia sẻ bit dùng trong lưu trữ. Tuy phải đánh đổi điều này với một xác suất lỗi khác 0, nhưng xác suất lỗi này lại là yếu tố có thể điều khiển được. Từ kết quả các thử nghiệm, ta có thể nhận thấy các mô hình ngôn ngữ Bloom Filter có hiệu quả xấp xỉ các lossless LM chuẩn nhưng tốc độ truy vấn chậm hơn. Thế nhưng điều quan trọng là nó cho phép ta xây dựng các LM có bậc cao hơn, sử dụng ngữ liệu lớn hơn; giải quyết được yêu cầu vừa tiết kiệm tài nguyên mà vẫn tận dụng được tri thức của các ngữ liệu lớn.

Trong tương lai, tôi mong muốn tiếp tục nghiên cứu các mô hình ngôn ngữ có nền tảng là các PDS và áp dụng vào xây dựng một hệ thống dịch máy thống kê Anh – Việt, Việt - Anh với ngữ liệu lớn. Hơn thế nữa, việc nghiên cứu ứng dụng của chúng trong các bài toán khác cũng vẫn còn rộng mở.

PHỤ LỤC

Chương trình truy vấn RandLM

1. GenStats.h #ifndef GENSTATS_H #define GENSTATS_H #include "RandLMParams.h" #include "RandLMTool.h" #include "RandLM.h" namespace randlm { class GenStats { public: // Constructor

GenStats(int argc, char ** argv) { inParam = argv; randlm_ = NULL; test_data_ = NULL; vocab = NULL; order_ = 0; corpus_data_ = false; getcounts_ = false; outputFile = ""; assert(load()); } // Destructor ~GenStats() { delete randlm_; delete test_data_; }

// Token a string into a vector

static void Tokenize(const string& str, vector<string>& tokens,

// Skip delimiters at beginning.

string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first "non-delimiter".

string::size_type pos = str.find_first_of(delimiters, lastPos); while (string::npos != pos || string::npos != lastPos) {

// Found a token, add it to the vector.

tokens.push_back(str.substr(lastPos, pos - lastPos)); // Skip delimiters. Note the "not_of"

lastPos = str.find_first_not_of(delimiters, pos); // Find next "non-delimiter"

pos = str.find_first_of(delimiters, lastPos); }

}

// reads ngrams from file and writes scores them to stdout, output file bool query();

// check and format user's input

vector<string> formatTestInfo(string info); // set test info

bool setTestInfo(vector<string> testInfo); private:

// load RandLM file into memory bool load();

RandLM* randlm_; // RandLM file

CountRandLM* count_randlm_; // use this if return only counts

TestCorpus* test_data_; // Test data

Vocab* vocab; // Vocabulary info

int order_; // order of LM

bool corpus_data_; // input file is corpus or ngrams ?

bool getcounts_; // if != NULL, return only counts

char ** inParam; // argv

string outputFile; // output file

}; }

2. GenStats.cpp #include <iostream> #include <fstream> using namespace std; #include "genstats.h" #include <ctime> namespace randlm { // Query bool GenStats::query() { assert(test_data_ != NULL); WordID sentence[Corpus::kMaxSentenceWords]; double start = clock();

int len = 0; int found = 0;

uint64_t counter = 0; long sentenceNo = 0; bool out = false; ofstream output;

// open output file for writing if(outputFile != "") { out = true; output.open (outputFile.c_str()); } // query as sentences if (corpus_data_) {

while (test_data_->nextSentence(&sentence[0], &len)) { cout << "SENTENCE No." << sentenceNo + 1 << ": "; if(out)

output << "SENTENCE No." << sentenceNo + 1 << ": "; for (int i = 0; i < len; i++) {

cout << vocab->getWord(sentence[i]) << " ";

if(out) output << vocab->getWord(sentence[i]) << " "; }

cout << endl;

if(out) output << endl;

continue;

for (int i = 1; i < len; ++i) {

int start = std::max(0, i - order_ + 1); if (getcounts_) { // return counts

if((i-start+1) < order_) continue; for(int j = 0; j < i-start+1; j++) { cout << vocab->getWord(sentence[start+j]) << " "; if(out) output << vocab->getWord(sentence[start+j]) << " "; } cout << ": " << count_randlm_->getCount(&sentence[start], i - start + 1) << std::endl; if(out) output << ": " << count_randlm_->getCount(&sentence[start], i - start + 1) << std::endl; }

else { // return probs

if((i-start+1) < order_) continue; for(int j = 0; j < i-start+1; j++) {

cout<< vocab->getWord(sentence[start+j]) << " ";

if(out) output << vocab->getWord(sentence[start+j]) << " "; }

cout << ": "

<< randlm_->getProb(&sentence[start], i - start + 1, &found) << std::endl;

if(out)

output << ": "

<< randlm_->getProb(&sentence[start], i - start + 1, &found) << std::endl;

}

++counter; }

cout << endl;

if(out) output << endl; sentenceNo++;

}

// query as ngrams } else {

while (test_data_->nextSentence(&sentence[0], &len)) { assert(len <= order_); for(int j = 0; j < len; j++) { cout << vocab->getWord(sentence[j]) << " "; output << vocab->getWord(sentence[j]) << " "; } cout << ": "; if(out) output << ": ";

if (getcounts_) { // return counts

cout << count_randlm_->getCount(&sentence[0], len) << std::endl; if(out) output << count_randlm_->getCount(&sentence[0], len)

<< std::endl; } else { // return probs

cout << randlm_->getProb(&sentence[0], len, &found) << std::endl; if(out) output << randlm_->getProb(&sentence[0], len, &found)

<< std::endl; } ++counter; } } output.close();

std::cerr << "Time elapsed: "

<< (clock() - start)/CLOCKS_PER_SEC << std::endl; return true;

Một phần của tài liệu Tìm hiểu mô hình ngôn ngữ sử dụng phương pháp bloom filter (Trang 51)

Tải bản đầy đủ (DOC)

(71 trang)
w