Lucene([7], [8]) là phần mềm mã nguồn mở, dùng để phân tích, đánh chỉ mục và tìm kiếm thông tin với hiệu suất cao bằng Javạ Lucene đƣợc phát triển đầu tiên bởi DougCutting đƣợc giới thiệu đầu tiên vào tháng 8 năm 2000. Tháng 9 năm 2001 Lucene gia nhập vào tổ chức Apache và hiện tại đƣợc Apache phát triển và quản lý. Cần lƣu ý rằng Lucene không phải là một ứng dụng mà chỉ là một công cụ đặc tả API cần thiết cho việc một search enginẹ Đƣợc xây dựng và thiết kế theo hƣớng hƣớng đối tƣợng nên các API cũng đƣợc cung cấp theo dạng hƣớng đối tƣợng. Mặc dù thiết kế và xây dựng ban đầu từ Java nhƣng hiện nay cũng đã có một số phiên bản cho các ngôn ngữ khác: .NET (Lucenẹnet), C++ (CLucene), Perl (PLucene), PHP (ZendLucene) …. 3.3.2 Kiến trúc Lucene Hình 3.2. Kiến trúc Lucene File Syste FS PDF HTML DOC TXT TXT PDF Parser DOC Docu- -Ments Object Indexer Indexer Searcher
70
Các file đƣợc duyệt qua FS Crawler, những file nào có phần mở rộng (extension) là file văn bản thì nó sẽ đƣợc phân tích và bóc tách nội dung ra thông qua các bộ parser (TXT Parser, Doc Parser, PDF Parser…). Nội dung của các file văn bản này sẽ đƣợc đánh chỉ mục thông qua các Indexer. Khi có yêu cầu từ ngƣời dùng yêu cầu tìm kiếm, Lucene sử dụng các searcher để truy cập vào vùng dữ liệu đã đƣợc đánh chỉ mục để tìm kiếm.
3.3.3 Kiến trúc File Index
Hình 3.3. Kiến trúc file Index
Index Document Document Document Docment Field Field Field Field Field Name Value
71
Trong file index, các văn bản đƣợc lƣu lại thành các khối dữ liệu (Document). Mỗi khối dữ liệu chứa các thông tin của từng văn bản. Các thông tin đƣợc lƣu vào các trƣờng (Field). Mỗi trƣờng đều có hai giá trị là Name và Valuẹ Name lƣu tên của trƣờng, Value chứa nội dung của Field. Ví dụ trong một văn bản (Document) có thể có các Field sau: Path (chứa đƣờng dẫn), Content (chứa nội), CreateDate(chứa ngày tạo file)…
Với mỗi Field, ta có thể chọn giữa đánh chỉ mục hay không đánh chỉ mục. Nếu chọn đánh chỉ mục, ta có thể tìm kiếm trên Field đó. Các Field không đánh chỉ mục thƣờng là các Field không quan trọng trong quá trình tìm kiếm và phục vụ chủ yếu cho nhu cầu trình bày kết quả trả về.
Thao tác đánh chỉ mục khá phức tạp. Trƣớc hết dữ liệu văn bản sẽ đƣợc phân tích thành các từ khóa, đồng thời loại bỏ các từ không dùng đến (stop words, trong tiếng Anh các từ nhƣ a, an, the là các stop words), sau đó các từ khóa sẽ đƣợc dùng để tạo Inverted index (chỉ mục đảo ngƣợc) và lƣu thành mục đảo ngƣợc dùng để chỉ cách lƣu trữ danh sách các tài liệu mà có chứa từ ngƣời ta lƣu trữ danh sách các từ có trong dữ liệu đó. Ví dụ, với từ khóa Index, ta sẽ lƣu trữ danh sách các trang web A, B, C có chứa từ khóa nàỵ Sau này khi ngƣời dùng gõ vào từ khóa Index, danh sách này có thể giúp định vị nhanh chóng các trang web có chứa nó. Nếu dùng chỉ mục thông thƣờng, phải quét qua hết các trang web có trong cơ sở dữ liệu mới tìm rạ Cách này rất tốn thời gian khi số lƣợng dữ liệu lớn.
72
3.3.4 Chỉ mục đảo ngƣợc
Posting Word Doc Offset
1 Football Doc 1 3 Doc 1 67 Doc 2 1 2 Penn Doc 1 1 3 Players Doc 2 2 4 State Doc 1 2 Doc 2 13 Hình 3.4. Chỉ mục đảo ngược
Các từ đƣợc bóc tách ra từ các văn bản sẽ đƣợc lƣu trong Posting Table với quy tắc: Các từ trong bảng là khác nhau, mỗi từ có một ID riêng, các từ đều đƣợc ánh xạ đến văn bản chứa nó thông qua tên ID của văn bản và vị trí (offset) của nó trong văn bản, lƣu lại vị trí của các từ trùng nhau trong một văn bản.
Doc 1: Penn State Football… football Doc 2: Football players … State Posting Table
73
CHƢƠNG 4. TÌM KIẾM XÂU MẪU
4.1 Bài toán đối sánh mẫu trong vấn đề tìm kiếm
4.1.1. Giới thiệu tổng quan về bài toán đối sánh mẫu trong vấn đề tìm kiếm
So mẫu, hay đối sánh mẫu (pattern matching) ([1], [3]) là một bài toán quan trọng trong vấn đề tìm kiếm thông tin đƣợc ứng dụng trong nhiều lĩnh vực khoa học và xử lý thông tin, nhƣ: công cụ tìm kiếm của các hệ điều hành; tìm kiếm mẫu lặp trong nén dữ liệu; tìm kiếm thông tin trong thứ việc điện tử, bách khoa toàn thƣ điện tử; khai phá web trên Internet; tìm kiếm tƣơng tự trong CSDL gen; tìm kiếm tự động các luật trong CSDL; nhận dạng tiếng nói trong các hệ thống điều khiển bằng tiếng nói; nhận dạng ảnh trong viễn thám, khoa học hình sự; … Nói chung, mẫu có thể ở bất kỳ kiểu dữ liệu nào, từ văn bản đến các loại dữ liệu đa phƣơng tiện (ảnh, video, âm thanh, …). Mặc dù dữ liệu đƣợc ghi dƣới nhiều dạng, song văn bản (text) vẫn là dạng phổ biến nhất, vì vậy vấn đề so xâu mẫu (string pattern matching) thực sự là một chủ đề trở nên quan trọng của lĩnh vực xử lý văn bản và đƣợc rất nhiều ngƣời quan tâm.
Vấn đề đặt ra trong bài toán so xâu mẫu là cần phát hiện đƣợc sự xuất hiện của xâu mẫu trong một chuỗi (xâu) các kí hiệu cho trƣớc (gọi là xâu đích, trong thực tế xâu đích có thể là một văn bản). Dạng đơn giản nhất song phổ dụng nhất và cũng đƣợc quan tâm nhiều nhất là bài toán so đơn mẫu, với mẫu là một xâụ Khi mẫu là một tập các từ khóa, ta có bài toán so đa mẫụ Trong bài toán đối sánh mẫu mở rộng, mẫu không đơn giản là một dãy kí tự mà đƣợc mở rộng theo nhiều kiểu khác nhaụ Cuối cùng, dạng tổng quát nhất bao hàm cho tất cả các loại bài toán kể trên là so biểu thức chính quị
Một vấn đề kinh điển khác của khoa học máy tính là tìm kiếm xấp xỉ, đƣợc đặt ra từ các ứng dụng nhận dạng tiếng nói, sinh-tin học, xử lý tín hiệu, so sánh tệp. Ngày nay, việc xây dựng công cụ tìm kiếm hiệu quả, đặc biệt là tính năng tìm kiếm xấp xỉ, trong các hệ thống trích rút văn bản, nhƣ thƣ điện tử, máy tìm kiếm trên
74
mạng, tìm kiếm danh bạ trên điện thoại di động, văn phòng điện tử,… đang đƣợc nhiều ngƣời quan tâm. Đó là do sự tăng trƣởng nhanh chóng và không ngừng của các hệ thống thông tin, trong khi nhu cầu khai thác của ngƣời dùng ngày càng phức tạp. Ngƣời ta mong muốn có kết quả phù hợp trả về ngay cả khi có “lỗi” trong thông tin đƣa vào hay trong cơ sở dữ liệu của hệ thống và có thể thấy ngay nội dung cần tìm trong trang kết quả đầu tiên, với thời gian ngắn nhất. Vậy việc tiếp tục nghiên cứu về các giải pháp tìm kiếm là rất cần thiết.
4.1.2. Bài toán đối sánh mẫu
So mẫu, hay đối sánh mẫu (pattern matching), là bài toán tìm sự xuất hiện của một mẫu (pattern) với một số dặc tính nào đó trong chuỗi các ký hiệu cho trƣớc. Khái niệm “chuỗi” có thể hiểu là chuỗi văn bản gồm một dãy các chữ, số và kí hiệu đặc biệt, có thể là chuỗi nhị phân hay chuỗi gene, … Dạng đơn giản nhất của bài toán so mẫu là tìm sự xuất hiện một xâu cho trƣớc trong một chuỗi (còn gọi là xâu đích).
Thực ra, đây là một trong những bài toán kinh điển nhất và phổ dụng nhất của khoa học máy tính, bởi hầu hết các ứng dụng đều đòi hỏi có sự đối sánh mẫu ở một dạng nào đó. Các phƣơng pháp đối sánh mẫu là cốt lõi trong rất nhiều loại phần mềm khác nhau nhƣ: các tiện ích của hệ điều hành, các hệ thống trích rút dữ liệu, trình soạn thảo văn bản, máy tìm kiếm (search engine) trên Internet, phân tích và tìm kiếm chuỗi gene trong sinh vật học, xử lý ngôn ngữ tự nhiên, tìm kiếm text trong các hệ cơ sở dữ liệu,…
Các kết quả đạt đƣợc hiện nay về đối sánh mẫu chủ yếu tập trung vào trƣờng hợp đơn giản nhất là tìm ra một xâu mẫu trong văn bản, còn với những dạng phức tạp khác, cho đến nay vẫn chƣa có nhiều công trình đƣợc công bố. Tuy nhiên, ta có thể phân loại các thuật toán đối sánh mẫu theo hai hƣớng. Thứ nhất là các thuật toán trực tuyến (on-line), trong đó chỉ mẫu đƣợc tiền xử lý (thƣờng sử dụng otomat hoặc dựa trên các đặc tính kết hợp trên xâu), còn văn bản thì không. Thứ hai là các thuật toán off-line, sử dụng giải pháp tiền xử lý văn bản theo cách xây dựng một cấu trúc dữ liệu trên văn bản (lập chỉ mục). Mặc dù đã có những thuật toán trực tuyến nhanh,
75
song với nhiều ứng dụng phải điều khiển một lƣợng văn bản quá lớn nên không có thuật toán trực tuyến nào có thể thực hiện một cách hiệu quả. Khi đó, giải pháp đƣợc lựa chọn là sử dụng các thuật toán off – linẹ Tìm kiếm trên chỉ mục thực ra cũng dựa trên tìm kiếm on – linẹ
Dựa trên đặc tính của mẫu, bài toán so mẫu đƣợc phân loại nhƣ sau: so đơn mẫu, so đa mẫu, so mẫu mở rộng, so biểu thức chính qui theo hai hƣớng chính xác và xấp xỉ. Nội dung của luận văn trình bày một số thuật toán so đơn mẫụ
4.1.3 So đơn mẫu
Bài toán: Cho xâu mẫu P độ dài m, P= P1P2P3… Pm và xâu S độ dài n, S= S1S2S3… Sn (S thường dài, là một văn bản) trên cùng bảng chữ Ạ Tìm tất cả các xuất hiện của xâu P trong xâu S.
Kí hiệu: S(k) là đoạn S1, S2, …, Sk.
Thuật toán đơn giản nhất là Brute-Force, cho phép tìm đƣợc tất cả các xuất hiện của mẫu trong thời gian cỡ O(m.n). Cho đến nay, rất nhiều thuật toán so đơn mẫu hiệu quả hơn đƣợc đƣa ra, trong đó kinh điển nhất là KMP (do D.ẸKnuth, J.H.Morris và V.R.Pratt đƣa ra năm 1976), BM (do R.S.Boyer và J.S.Moore đƣa ra năm 1976) và Karp-Rabin (do R.M.Karp và M.ỌRabin đƣa ra năm 1980).
4.2 Thuật toán đối sánh mẫu KMP (Knuth Morris Pratt)
Thuật toán KMP có nội dung sau:
Duyệt từ trái sang phải trên S và P, mỗi lần một ký tự. Gọi con trỏ trên P là i, con trỏ trên S là j. Giả sử đã xuất hiện khúc đầu độ dài i – 1 của mẫu P và việc khớp mẫu thất bại tại vị trí j trên S, có nghĩa:
P1P2… Pi-1 Sj-i+1Sj-i+2… Sj-1 và Pi Sj
Khi đó cần phải bắt đầu đối sánh mẫu từ vị trí j – h + 1 trên S (trƣờng hợp xấu nhất h = i – 1 trong thuật toán Brute-Force). Nếu tồn tại h > 0 sao cho h – 1 ký tự đầu của mẫu khớp với h – 1 ký tự cuối của đoạn S(j – 1) hay có nghĩa đã khớp với h – 1 ký tự cuối của P(i – 1) thì ta có thể bỏ qua h – 1 phép so sánh và tiếp tục
76
so sánh ký tự Ph và Sj (Hình 4.1). Do h phụ thuộc vào i nên ký hiệu h = nex[i], i=1,.. , m.
Hình 4.1. Ý nghĩa của mảng next
Nếu Sj ≠ Ph thì phải tiếp tục lùi con trỏ trên mẫụ Để khắc phục nhƣợc điểm do tình huống này gây ra, cần cố gắng tìm h sao cho Ph có nhiều khả năng bằng Sj. Vì Sj ≠ Pi nên cần tìm h thỏa mãn Ph ≠ Pị
Trong KMP, khi i > m ta đƣợc một xuất hiện của mẫu bắt đầu từ vị trí j-m trên S. Để tìm xuất hiện tiếp theo, nếu bắt đầu đối sánh từ Sj và P1 thì có thể bỏ sót mẫu khi có mẫu xuất hiện lồng nhaụ Vì vậy, khi con trỏ trên S dừng ở vị trí j, cần trƣợt mẫu đi một số vị trí sao cho h – 1 kí tự đầu của mẫu khớp với h-1 kí tự cuối của S(j-1) hay chính là khớp với h – 1 kí tự cuối của P(m). Do đó cần mở rộng mảng next với i = m+1 (Hình 4.2). Để có next[m+1], ta tƣởng tƣợng nhƣ đã bổ sung thêm kí tự # vào cuối P, với # là một kí tự nào đó không xuất hiện trong P.
77
Nhƣ vậy, với mỗi vị trí i trên P, i = 1..m + 1, cần xác định next[i] thỏa mãn: + next[i] là số h lớn nhất sao cho h – 1 kí tự đầu của mẫu khớp với h – 1 kí tự
cuối của P(i – 1). + Pi ≠ Pnext[i].
Thuật toán 4.1.Thuật toán xây dựng mảng next
Procedure Initnext(P : char, m : integer ); Var i,j : integer;
Begin i := 1; j := 0; next[1] := 0; while i <= m do begin while j > 0 and Pi ≠ Pj do j := next[j]; i := i+1; j := j+1;
if ( i <= m) and (Pi = Pj) then next[i] := next[j] else next[i] := j;
end; end;
Cài đặt thuật toán
int *Initnext(char *pattern, int psize) {
int i = 1; int j = 0;
78 if (!next) return NULL; next[1] = 0; while ( i <= psize ) {
while ((j > 0) and pattern[i] != pattern[j]) {
j = next[j]; }
i = i + 1; j = j + 1;
if ((i <= psize) and (pattern[i] == pattern[j])) { next[i] = next[j]; } else { next[i] = j; } } printf("Bang Next \n"); printf("i : ");
for (i = 1; i <= psize+1; i++) { printf("%d ", i); }
printf("\n");
79 for (i = 1; i <= psize+1; i++)
{ printf("%d ", next[i]); }
return next; }
Thuật toán 4.2. Thuật toán KMP tìm nhiều lần lặp mẫu
Procedure KMP(S : char, n : integer, P : char, m : integer);
{Tìm mọi vị trí xuất hiện xâu mẫu P độ dài m trong xâu đích S độ dài n, đồng thời thống kê tần suất xuất hiện mẫu}
Var i, j, Counter: integer; Begin Initnext(); i := 1; j := 0; next[1] := 0; repeat while (i <= m) and ( j <= n ) do begin
while (i > 0) and (Sj ≠ Pi) do i := next[i]; i := i+1; j := j+1;
end;
if (i > m) then begin
Ghi nhận vị trí xuất hiện mẫu là j - m; counter := counter + 1;
end; i := next[i]; until j > n;
80 Ghi nhận counter;
end;
Cài đặt thuật toán
int KMP(char *target, int tsize, char *pattern, int psize) { int i; int j; int counter;
int *next = Initnext(pattern, psize); i = 1; j = 1;
counter = 0;
printf("\n Ket qua tim kiem \n"); printf("Vi tri xuat hien :"); while (j < tsize)
{ while ((i < psize) and (j < tsize))
{ while ((i > 0) and (target[j]!= pattern[i])) { i = next[i]; } i = i +1; j = j +1; } if (i >= psize) { printf(" %d,", j-psize + 1); counter = counter + 1; } i = next[i]; } return counter; }
81
Kết quả thử nghiệm
+ Trường hợp tìm thấy
Hình 4.3. Kết quả thực hiện thuật toán KMP_trường hợp tìm thấy chuỗi + Trường hợp không tìm thấy
82
Độ phức tạp của thuật toán KMP
- Pha tiền xử lý mẫu có độ phức tạp thời gian và không gian để xây dựng bảng next là O(m).
- Pha tìm kiếm có độ phức tạp thời gian xấu nhất là O(m + n).
4.3 Thuật toán đối sánh mẫu BM (Boyer-Moore)
Thuật toán BM đƣợc đánh giá là thuật toán nhanh nhất về thực hành, đây là lựa chọn hiệu quả cho những ứng dụng thông thƣờng nhƣ các trình soạn thảo văn bản.
Ý tƣởng cơ bản của thuật toán là sử dụng một – Cửa sổ trƣợt- nhƣ sau: Cửa sổ trƣợt thực ra là một khúc độ dài m trên xâu vào S (m là độ dài của mẫu P) đƣợc đối sánh với mẫu tại một thời điểm nào đó. Mỗi lần đối sánh mẫu P với một cửa sổ trên S bằng cách so sánh từng ký tự từ phải sang tráị Khi gặp ký tự không khớp, cửa sổ trƣợt sang phải qua một đoạn trên S (tƣơng ứng với việc dịch mẫu P sang phải). Trƣờng hợp tốt nhất khi sự không khớp xảy ra tại vị trí Pm và ký tự không khớp là Sk lại không phải là một ký tự trong mẫu P, lúc đó có thể an toàn trƣợt cửa sổ sang phải qua m vị trí trên S và bắt đầu quá trình tìm kiếm mới bởi việc so sánh Pm và Sk+m.
Giả sử tại một thời điểm đang xét cửa sổ Sk-m+1Sk-m+2… Sk và bắt đầu so sánh Pm với Sk.
1. Giả sử Pm ≠ Sk có hai khả năng:
ạ Nếu vị trí xuất hiện phải nhất của ký tự Sk trong P là m – g, ta có thể dịch mẫu P sang phải g vị trí sao cho Pm-g dóng thẳng với Sk rồi bắt đầu lại quá trình đối sánh bởi phép so sánh Pm và Sk+g.
b. Nếu ký tự Sk không có mặt trong P, ta có thể dịch mẫu P sang phải m vị trí. Đây là bƣớc dịch chuyển xa nhất có thể mà vẫn không bỏ sót sự xuất hiện nào của mẫụ
2. Giả sử m – i ký tự cuối của mẫu P đã khớp với m – i ký tự cuối của S(k). Nếu i = 0, ta đã tìm đƣợc một xuất hiện của mẫu P.
83
Ngƣợc lại, nếu i > 0 và Pi ≠ Sk-m+i, xét hai khả năng:
ạ Nếu vị trí xuất hiện trái nhất của ký tự Sk-m+i trong P là i – g, khi đó mẫu P