3. Chương 3: Một số phương pháp KPDL sinh luật kết hợp
3.4. Thuật toán Closet
3.4.1. Giới thiệu
Cũng vào năm 2000, nhóm tác giả J. Pei, J. Han, Y. Yin và R. Mao ngoài việc đề xuất thuật toán FP-Growth trong khai phá luật kết hợp thông thường, còn đề xuất một thuật toán không sinh ứng cử khác trong khai phá luật kết hợp đóng là Closet [107]. Giống như FP-Growth, đây là một thuật toán khai phá rất hiệu quả dựa trên ý tưởng chia để trị, xuất phát từ CSDL ban đầu, chia nhỏ chúng thành các CSDL phụ thuộc mẫu để khai phá và cứ như vậy cho tới khi CSDL phụ thuộc mẫu đủ nhỏ (suy biến) để có thể khai phá trực tiếp. Các khái niệm và ký hiệu trong giải thuật Closet cũng được sử dụng khá nhất quán với giải thuật FP-Growth như CSDL phụ thuộc mẫu, FP-tree, ..., do đó đọc giả nên tham khảo giải thuật FP-Growth tại phần 3.2 trước.
TID Items 1 a, c, d, e, f 2 a, b, e 3 c, e, f 4 a, c, d, f 5 c, e, f
Bảng 3.25: Cơ sở dữ liệu minh hoạ thuật toán Closet.
Ký hiệu:
+ TDB là CSDL tổng thể D cần khai phá.
+ TDB|d là CSDL phụ thuộc mẫu chứa tập mục (mẫu) d. + f_list là tập các mục đơn ứng với CSDL tổng thể D.
+ f_list|d là tập các mục đơn ứng với CSDL phụ thuộc mẫu chứa d. + FCI là tập các tập mục đóng phổ biến (Frequent Closed Itemsets).
Hình 3.9: Minh hoạ thuật toán Closet.
Các bước của thuật toán Closet cụ thể như sau (giả định minsup = 2): + Tìm các mục đơn phổ biến:
Duyệt TDB ta thu được f_list = {c:4, e:4, f:4, a:3, d:2} trong đó các mục được sắp theo thứ tự giảm dần của độ hỗ trợ và các mục không đủ độ hỗ trợ như b sẽ bị loại.
+ Chia nhỏ không gian tìm kiếm:
Rõ ràng tất cả các tập mục đóng phổ biến chỉ có thể phái sinh từ 5 tập con độc lập (không giao nhau) dựa trên f_list:
(1) Tập con chứa d.
(2) Tập con chứa a nhưng không chứa d. (3) Tập con chứa f nhưng không chứa a, d. (4) Tập con chứa e nhưng không chứa a, d, f. (5) Tập con chứa c nhưng không chứa a, d, f, e.
+ Tìm các tập con của FCI:
TDB cefad ea cef cfad cef TDB|d (d:2) cefa cfa Output to FCI: {cfad:2} TDB|a (a:3) cef e cf Output to FCI: {a:3} TDB|f (f:4) ce:3 c Output to FCI: {cf:4, cef:3} TDB|e (e:4) c:3 Output to FCI: {e:4} f_list: {c:4, e:4, f:4, a:3, d:2}
TDB|ea (ea:2) c Output to FCI:
Các tập con của FCI có thể được khai phá bằng việc tạo ra các CSDL phụ thuộc mẫu (Conditional pattern database) tương ứng và ta sẽ khai phá đệ quy đối với chúng.
+ (1) Tìm các tập mục đóng phổ biến chứa d:
Ta có TDB = {cefad, ca, cef, cfad, cef} =>TDB|d = {cefa, cfa} và f_list|a = {c:2, f:2, a:2}. Nhận xét: sup(d) = 2, các mục c, f, a xuất hiện 2 lần trong TDB|d (thoả minsup = 2), còn e
chỉ xuất hiện 1 lần (không thoả minsup) do đó sau khi loại e, chúng ta có cfad:2 là tập mục đóng phổ biến. Chú ý là các mục đơn không phổ biến cục bộ sẽ bị bỏ qua kể cả nó nằm trong f_list tổng thể. Hơn nữa cfad:2 cũng bao phủ mọi mục đơn phổ biến trong
TDB|d nên việc khai phá TDB|d kết thúc.
+ (2) Tìm các tập mục đóng phổ biến chứa a nhưng không chứa d:
Tương tự, ta có TDB|a = {cef, e, cf} và f_list|a = {c:2, e:2, f:2}. Trong đó d sẽ bị bỏ qua trong các giao dịch này bởi vì mọi tập mục đóng phổ biến chứa d đã được tìm thấy trong
TDB|d. Ta thấy sup(a) = 3 và không có bất kỳ mục nào xuất hiện trong TDB|a với cùng độ hỗ trợ là 3, nên a:3 là tập mục đóng phổ biến.
Để tìm các tập mục đóng phổ biến còn lại chứa a nhưng không chứa d, chúng ta sẽ tiếp tục khai phá TDB|a. Tương ứng với f_list|a, các tập mục đóng phổ biến chứa a nhưng không chứa d có thể được phân hoạch thành 3 tập con:
+ Tập con chứa af nhưng không chứa d. + Tập con chứa ae nhưng không chứa d, f. + Tập con chứa ac nhưng không chứa d, e, f.
Rõ ràng chúng ta có thể áp dụng đệ quy để khai phá bằng cách lặp lại các bước trên. Xét TDB|fa = {c:2} và f_list|fa = {c:2}, ta thấy sup(fa) = sup(cfa) = 2 = sup(cfad) mà cfad
là tập mục đóng phổ biến đã được tìm thấy (trong bước trước) và nó bao hàm cả fa và cfa, điều đó có nghĩa là mọi giao dịch chứa fa cũng phải chứa cfad. Do đó, ta khẳng định không tồn tại tập mục đóng phổ biến chứa fa mà không chứa c, d.
Xét TDB|ea = {c} và f_list|fa = , ta thấy không sinh ra bất kỳ mục đơn phổ biến nào nữa nên ea:2 là tập mục đóng phổ biến.
Xét TDB|ca = và f_list|ca = , không sinh ra bất kỳ tập mục đóng phổ biến nào nữa. + (3) Tìm các tập mục đóng phổ biến chứa f nhưng không chứa a, d:
Tương tự, ta có TDB|f = {ce:3, c} và f_list|f = {c:4, e:3}, ta thấy c xuất hiện trong mọi giao dịch của TDB|f và cf không phải là tập con của bất kỳ tập mục đóng phổ biến nào với cùng độ hỗ trợ nên cf:4 là tập mục đóng phổ biến. Đồng thời sup(fc) = sup(f) = sup(c) = 4
do đó f và c sẽ luôn xuất hiện cùng nhau nên sẽ không tồn tại tập mục đóng phổ biến chứa
c mà không chứa f. Tương tự, cef:3 không là tập con của bất kỳ tập mục đóng phổ biến nào đã tìm thấy (từ trước tới nay) nên cef là tập mục đóng phổ biến.
Tương tự, ta có TDB|e = {c:3} và f_list|e = {c:3}, ta thấy ce không phải là tập mục đóng phổ biến vì ce là tập con của cef mà sup(ce) = sup(cef) = 3. Tuy nhiên e:4 là tập mục đóng phổ biến.
+ (5) Tìm các tập mục đóng phổ biến chỉ chứa c:
Trong bước (3) chúng ta đã có kết luận là không tồn tại tập mục đóng phổ biến chứa c mà không chứa f nên sẽ không có tập mục đóng phổ biến nào chỉ chứa c.
+ Tổng hợp ta thu được tập các tập mục đóng phổ biến:
FCI = {acdf:2, a:3, ae:2, cf:4, cef:3, e:4}.
Thuật toán Closet được xây dựng dựa trên các tính chất sau (tính đúng đắn của các tính chất này được chứng minh cụ thể trong [107]):
Tính chất 1: Cho CSDL TDB, ngưỡng độ hỗ trợ cực tiểu minsup và f_list = {i1, ..., in}. Thì bài toán khai phá tập các tập mục đóng phổ biến trong TDB, có thể được phân rã thành n bài toán con. Trong đó bài toán thứ j là tìm tất cả các tập mục đóng phổ biến chứa mục đơn in+1-j nhưng không chứa bất kỳ mục đơn ik nào với n+1-j<kn.
Với tính chất này ta có thể áp dụng đệ quy để giải bài toán.
Tính chất 2: Nếu X là tập mục đóng phổ biến thì không thể tồn tại mục đơn i thoả mãn:
it, tTDB|X.
Với tính chất này ta có thể khẳng định X không phải tập mục đóng phổ biến nếu tồn tại mục đơn i nào đó thoả mãn: it, tTDB|X. Và nếu Y = {i: it, tTDB|X} thì ta có thể thay thế X bởi YX. Và nếu YX không bị phủ bởi FCI thì ta bổ sung nó vào FCI.
Tính chất 3: Nếu Y là tập mục cực đại: Y = i, if_list|X thoả mãn Yt, tTDB|X. Thì YX sẽ là tập mục đóng phổ biến khi không tồn tại Z là một tập mục đóng phổ biến nào đó đã được khai phá và YXZ.
Với tính chất này ta có thể kết thúc quá trình khai phá với TDB|X khi tìm được Y như trên và bổ sung YX vào tập các tập mục đóng phổ biến.
Tính chất 4: Nếu Y là tập mục ứng với đoạn đơn i (i-single segment). Thì Y sẽ là tập mục đóng phổ biến nếu nó thoả minsup và không tồn tại Z là một tập mục đóng phổ biến nào đó đã được khai phá và YZ.
Trong đó đoạn đơn i là đường đi từ gốc của cây FP-tree (xem 3.2) tới nút N với: + Nhãn của N là i, và trong cây chỉ có duy nhất N có nhãn là i.
+ N hoặc không có nút con, hoặc phải có nhiều nút con, hoặc chỉ có 1 nút con N’
nhưng độ hỗ trợ của N’ nhỏ hơn N.
Với tính chất này ta có thể khai phá tập mục đóng phổ biến từ cây FP-tree.
Tính chất 5: Nếu X là tập mục phổ biến không đóng và Y là tập mục đóng phổ biến thoả mãn XY và sup(X) = sup(Y). Thì không tồn tại tập mục đóng phổ biến Z thoả mãn
XZ nhưng lại không chứa bất kỳ mục i nào thuộc Y\X.
Với tính chất này ta có thêm 1 trường hợp tỉa nhánh (X) khi khai phá, và khẳng định X
luôn đi cùng với Y\X với sup(X) = sup(Y).
3.4.2. Thuật toán
Bảng 3.26: Thủ tục ClosetMining.
Input: CSDL TDB, ngưỡng độ hỗ trợ cực tiểu minsup.
Output: Tập các tập mục đóng phổ biến.
Thực hiện: ClosetMining(TDB, minsup).
(1) FCI = null; // Khởi tạo tập các tập mục đóng phổ biến. (2) Closet(null, TDB, minsup, FCI);
(3) Return FCI;
Bảng 3.27: Thủ tục Closet.
Input: Mẫu đang xét X, CSDL phụ thuộc mẫu tương ứng TDB|X, ngưỡng độ hỗ trợ cực tiểu
minsup, tập các tập mục đóng phổ biến hiện tại FCI.
Output: Tập các tập mục đóng phổ biến FCI.
Thực hiện: Closet(X, TDB|X, minsup, FCI).
(1) // Tìm tập các mục đơn phổ biến trong TDB|X và sắp giảm dần theo độ hỗ trợ: (2) f_list|X = GetFrequentItems(TDB|X, minsup);
(3) // Áp dụng tính chất 2 và 3:
(4) // Nếu Y = {if_list|X: it, tTDB|X} thì ta có thể thay thế X bởi YX. (5) // Và nếu YX không bị phủ bởi FCI thì ta bổ sung nó vào FCI.
(6) // Đồng thời loại Y khỏi TDB|X và f_list|X. (7) Y = {if_list|X: it, tTDB|X}; (8) If (!Subsumption_Check(FCI, YX)) (9) FCI = FCI {YX}; (10) X = YX; // Thay thế X bởi YX. (11) Remove(Y, TDB|X, f_list|X); (12) // Dựng cây FP-tree từ TDB|X:
(13) TNew = CreateFPTree(TDB|X, minsup);
(14) // Áp dụng tính chất 4 để khai phá các tập mục đóng phổ biến trên FP-tree:
(16) FCI = FCI {YX};
(17) // Áp dụng tính chất 1 để khai phá đệ quy và tính chất 5 để tỉa nhánh: (18) Foreach from last entry (i in f_list|X & !Subsumption_Check(FCI, iX)) { (19) TDB|iX = CreateDB(TNew, i); // Xác định CSDL phụ thuộc mẫu. (20) Closet(iX, TDB|iX, minsup, FCI); // Khai phá đệ quy.
(21) }
(22) Return FCI;
Trong đó:
+ Thủ tục CreateFPTree và CreateDB có thể tham khảo tại 3.2.2. + Thủ tục Subsumption_Check có thể tham khảo tại 3.3.2.
3.4.3. Tổng kết
Hình 3.10: So sánh Closet với A-Close và Charm.
Qua minh hoạ trên phần nào cho ta thấy thuật toán Closet rất tốt, không những vậy trong môi trường thực nghiệm với một số CSDL cụ thể nó cũng tốt hơn những thuật toán khác như Close (A-Close) [108], và Charm [110], [111], đó là do những ưu điểm sau đây:
(1) Thuật toán Closet chỉ tìm các tập mục đóng phổ biến và trong quá trình tìm không cần phải sinh ra mọi tập mục phổ biến có thể có.
(2) Giống thuật toán FP-Growth, Closet sử dụng chiến lược chia để chế ngự (divide and conquer) và áp dụng ý tưởng khai phá phát triển (growth), hoàn toàn không sinh ứng cử. Đồng thời áp dụng chiến lược tỉa các mẫu nếu không phổ biến hoặc không thoả tính chất đóng. Sử dụng cấu trúc dữ liệu đặc biệt FP-tree để nén dữ liệu và tăng tốc khai phá
trong khi vẫn duy trì đầy đủ thông tin cho khai thác các mẫu phổ biến. Cây FP-tree không bao giờ lớn hơn CSDL gốc và nếu áp dụng kỹ thuật sắp xếp giảm dần theo tần suất thì các mục phổ biến sẽ được chia sẻ nhiều hơn, độ nén sẽ cao hơn và tốc độ khai phá nhanh hơn. Độ cao của cây tổng thể chỉ bằng kích thước của tác vụ lớn nhất (sau khi đã lọc bỏ các mục không thoả minsup).
(3) Áp dụng tốt cho cả mẫu phổ biến ngắn hay dài, CSDL thưa hay dày. Chỉ quét CSDL đúng 2 lần.
(4) Tính đúng đắn của thuật toán Closet đã được chứng minh [107]. Thời gian xây dựng cây FP-tree là O(n) với n là số lượng giao dịch. Tuy nhiên tổng thời gian khai phá trên các cây FP-tree phụ thuộc là tương đối khó đánh giá nhưng nó tỉ lệ với số mẫu phổ biến được sinh ra. Ngoài ra giải thuật là tương đối phức tạp, không hề đơn giản như Charm.