Hình ở góc trên bên trái là kết quả của thuật toán MBSAS: cụm màu xanh da trời - blue (bên trái) có quy mô không đúng so với hình ở góc trên bên phải của TTSAS. Kết quả của TTSAS hầu như chính xác vì nó không phụ thuộc vào số cụm phải tạo ra.
Hình ở góc dưới bên trái là kết quả thuật toán GAS, nó tương tự với MBSAS trong khi đó GDS (góc dưới bên phải) tạo ra cụm màu đỏ lớn hơn, chứa cả các vector của cụm màu xanh lá cây (green). Thực tế GDS khác với GAS bởi vì cụm màu đỏ của GDS chặt chẽ hơn cụm màu xanh da trời (blue) của GAS.
MBSAS TTSAS
KẾT LUẬN Những kết quả đã đạt đƣợc
Ngày nay, quá trình khai thác thông tin trong các hệ thống CSDL ngày càng đa dạng, và tăng trưởng nhanh cả về chất lẫn về lượng; hơn nữa, nhu cầu khai thác các tri thức từ các CSDL này (dưới dạng phân hoạch CSDL thành các cụm dữ liệu cần quan tâm) ngày càng lớn. Vì vậy, nghiên cứu các thuật toán phân cụm là việc làm rất cần thiết và có nhiều ý nghĩa trong khoa học cũng như trong thực tiễn.
Luận văn đã tập hợp và trình bày lại một cách có hệ thống ba họ thuật toán phân cụm tiêu biểu: tuần tự, phân cấp và tối ưu hoá. Với mỗi họ thuật toán đều trình bày sơ đồ thuật toán, phân tích ưu và nhược điểm, phạm vi áp dụng; đồng thời đưa ra một cài đặt thử nghiệm mang tính chất mô phỏng để so sánh giữa các thuật toán. Cụ thể từng chương như sau:
Chương 1: Trình bày tổng quan về khai phá dữ liệu, phân cụm, các thuật toán phân cụm và phân loại trong khai phá dữ liệu đồng thời trình bày các khái niệm cơ bản về một số độ đo tương tự, không tương tự nhằm cung cấp cơ sở toán học cho các thuật toán...
Chương 2: Trình bày về các thuật toán phân cụm tuần tự. Trong chương này, trước hết xét sơ đồ phân cụm tổng quát BSAS, sơ đồ BSAS sửa đổi (MBSAS) và phân cụm tuần tự hai ngưỡng TTSAS. Hai thuật toán BSAS, MBSAS đều có kết quả phụ thuộc chặt chẽ vào thứ tự các vector đưa vào phân cụm cũng như giá trị ngưỡng. TTSAS ít phụ thuộc vào thứ tự các vector đưa vào phân cụm mà số cụm sinh ra phụ thuộc vào chọn giá trị cho hai ngưỡng. Trong 3 thuật toán trên, TTSAS có hiệu quả hơn (độ phức tạp O(n2)). Để kết quả phân cụm hợp lý hơn, người ta sử dụng kết hợp thủ tục sắp xếp lại và thủ tục trộn trong quá trình thực hiện các thuật toán.
Chương 3: Trình bày chi tiết về họ thuật toán phân cụm phân cấp. Các thuật toán này được chia thành 2 loại tích tụ và phân rã và có thể sử dụng lý thuyết ma trận hoặc lý thuyết đồ thị. Trong thuật toán tích tụ dựa trên lý thuyết ma trận có cả 7 thuật toán được thảo luận: liên kết đơn, liên kết đầy đủ, WPGMA, UPGMA, WPGMC, UPGMC và Ward. Trong các thuật toán này thì thuật toán liên kết đơn có khuynh hướng hình thành các cụm dài còn liên kết đầy đủ có khuynh hướng hình thành nên các cụm chặt. Các thuật toán khác nằm giữa hai thuật toán này. Thuật toán tích tụ dựa trên lý thuyết đồ thị gồm: liên kết đơn, liên kết đầy đủ và thuật toán dựa
trên cây khung nhỏ nhất. Các thuật toán loại này, nếu các cụm hình thành hợp lệ đều phải thoả một tính chất nào đó của đồ thị. Các thuật toán phân cụm phân rã thực hiện ngược với phân cụm tích tụ và cần tính toán chặt chẽ hơn. Người ta biểu diễn quá trình phân cụm bằng sơ đồ ngưỡng. Đây là sơ đồ biểu diễn quá trình hình thành các cụm ở mỗi mức ngưỡng. Bằng cách cắt sơ đồ ngưỡng ở một mức nào đó ta được các cụm sinh ra ở mức đó. Phần cuối của chương là thảo luận về phương pháp cắt sơ đồ ngưỡng để được các cụm sinh ra phù hợp với dữ liệu. Nhìn chung, các cụm thuộc loại này có độ phức tạp theo lý thuyết là O(n3
).
Chương 4: Giới thiệu phương pháp phân cụm qua tối ưu hoá để giải quyết bài toán phân cụm theo tâm. Cụ thể là phương pháp quy hoạch toán học và tối ưu hoá d.c. Đây là phương pháp tỏ ra có hiệu quả hơn các phương pháp khác. Để kiểm tra tính hiệu quả của phương pháp này, luận văn trình bày lại các thí nghiệm của các tác giả Mangasarian, H. Tuỵ trong CSDL chuẩn đoán ung thư vú của đại học Wisconsin.
Chương 5: Đưa ra một số phân tích, cài đặt thử nghiện 4 thuật toán cơ bản MBSAS, TTSAS, GAS (Liên kết đơn) và GDS (cải tiến) đồng thời so sánh thời gian thực hiện cũng như thảo luận về sự hình thành các cụm qua mỗi thuật toán. Phần phụ lục của luận văn giới thiệu mã nguồn của một số thuật toán.
Hạn chế của đề tài:
- Chưa có điều kiện nghiên cứu kỹ lớp các bài toán phân cụm nhờ tối ưu hoá. - Chưa cài đặt được thuật toán phân cụm nhờ tối ưu hoá cho một ứng dụng cụ
thể mà sử dụng những kết quả thử nghiệm đã có của các tác giả khác như đã giới thiệu trong chương 4.
- Cài đặt các thuật toán trong chương 5 chỉ mang tính chất mô phỏng, chưa ứng dụng được vào thực tế.
Hƣớng phát triển của đề tài
Nghiên cứu về các thuật toán phân cụm qua tối ưu hoá. Cụ thể: - Bài toán phân cụm theo siêu phẳng;
- Bài toán phân cụm trên mặt phẳng, trên mặt cầu;
- Nghiên cứu tối ưu hoá đơn điệu và áp dụng vào bài toán phân cụm;
- Cài đặt thử nghiệm một số thuật toán dựa trên tối ưu hoá và ứng dụng vào các bài toán thực tế.
TÀI LIỆU DẪN Tài liệu tiếng Việt
[1] Hoàng Tuỵ (2006), "Lý thuyết tối ưu" (Bài giảng lớp cao học), Viện Toán học Hà Nội, 2006.
[2] Hoàng Tuỵ (2005), Hàm thực và giải tích hàm, Nhà xuất bản Đại học Quốc gia Hà Nội.
Tài liệu tiếng Anh
[3] Alan Rea (1995), Data Mining – An Introduction. The Parallel Computer Centre, Nor of The Queen’s University of Belfast.
http://www.pcc.qub.ac.uk/tec/courses/datamining/stu_notes/dm_book_1.html
[4] A.M. Gagirov, A.M. Rubinov, A. Stranieri and J. Yearwood (1999). The global
optimization approach to the clustering analysis. Woking paper 45/99, University of
Ballarat, Australia.
[5] Boberg J., Salakoski T. “General formulation and evaluation of agglomerative clustering methods with metric and non-metric distances,” Pattern Recognition, Vol. 26(9), pp. 1395-1406, 1993.
[6] H. Tuy (1997), "A general d.c. approach to location problems", in State of the Art in Global optimization: Computational Methods and Application, eds. C. Floudas and P.Pardalos, eds., Kluwer, 413-432.
[7] H. Tuy (1998), "Convex Analysis and Global Optimization", Kluwer.
[8] H. Tuy (1999), Monotonic Optimization: Problems and Solution Approaches, Preprint, Institute of Mathematics, Hanoi.
[9] H.Tuy , A.M. Gagirov, A.M. Rubinov: Clustering via D.C. Optimization. Research Report 00/13 (2000), School of Information Technology and Mathematical Sciences, Univerity of Ballarat. Submitted.
[10] Jiawei Han and Micheline Kamber (2001), Data Mining : Concepts and Techniques, Hacours Science and Technology Company, USA.
[11] Lance G.N., Williams W.T. “A general theory of classificatory sorting strategies: II. Clustering System.” Computer Journal, Vol. 10, pp. 271-277, 1967.
[12] MacQuenn J.B. “Some methods for classification and analysis of multivariate observations,” Proceedings of the Symposium on Mathematical Statistics and Probability, 5th Berkeley, Vol. 1, pp. 218-297, AD 669871, University of California Press, 1967.
[13] Maria Halkidi (2001), On Clustering Validation Techniques, Kluwer Academic Publishers, Holland.
[14] O.L Mangasarian (1987) Mathematical Programming in Data Mining, in Data Mining and Knowledge Discovery 1, 183-201.
[15] O.L Mangasarian, W.N. Street and W.H Wolberg: Breast cancer diagnosis and prognosis via linear Programming. Operations research 4(1995), 570-577.
[16] P.S. Bradley, O.L. Magasarian and W.N Street (1997), Clustering via cancave Minimization, Techincal Report 96-03, Computer Sciences Department, University of Wisconsin, Madison, Wisconsin, May 1996. Advances In Neural Information processing Systems 9. MIT Press, Cambridge, MA, 368-374, M.C. Mozer, M.I.Jordan and T. Petsche, editors. Available by ftp://ftp.cs.winsc.edu/math-prog/tech-trports/96-03.ps.Z
[17] R. Horst and H. Tuy (1996), "Global Optimization" (Deterministic Approaches), Springer, third edition.
[18] W.H. Wolberg, W.N Street and O.L. Magasarian (1994), Machine learning techniques to diagnose breast cancer from fine-needle aspirates. Cancer Letters, 77, 163-171.
[19] Yu. G. Evtushenko (1982), Solution Methods of Extremal Problems and Their Application to optimization System, Moscow, Nauka. (In Russian)
PHỤ LỤC: MÃ NGUỒN CỦA MỘT SỐ THUẬT TOÁN
/**
* Cluster.h
*
* La mot lop co so chua cac vector mau. *
*/ /**
* Dinh nghia mot cum don. Mot cum co mot danh sach cac vector * thuoc cum do. Cac vector co the duoc them vao hoac loai bo * khoi cum.
* Cac lop khac co the kế thừa lop nay. Chang han nhu cac * lop co cac vector dai dien khac nhau. Lop nay su dung dai * dien la vec tor trung binh.
* */
class CCluster
{
protected:
/** Danh sach Cac vector dang thuoc ve cum nay */ VList Vectors;
/** Dai dien trung binh */ fVector3 Medium;
/** Cac vector Outlier hien tai */ fVector3 Outlier;
/** Khoang cach tu cac vector Outlier toi vector dai dien */ float fOutlierDist;
/** La cac outlier hop le */ bool bOutlierValid;
/** Cap nhat gia tri dai dien */ virtual void UpdateMedium();
/** Cap nhat vector outlier (vector nam xa vetor dai dien nhat */ virtual void UpdateOutlier();
public:
CCluster(void);
/** Kiem tra xem cum co rong khong? */ bool IsEmpty() const;
/** Them mot vector vao cum nay */
virtual void AddVector(const fVector3& vec); /** Loai bo mot vector khoi cum nay */
virtual void RemoveVector(const fVector3& vec); /** Chua tat ca vector cua mot cum da cho. */ virtual void Include(CCluster& cluster);
/** Tra ve mot tham chieu toi danh sach cac vector */ virtual const VList& GetVectors() const;
/** Tra ve vector dai dien */
virtual fVector3 GetRepresentative() const { return Medium; }
virtual fVector3 GetOutlier(); /** Tra ve khoang cach outlier */ virtual float GetOutlierDist(); /** Tra ve mot doi tuong cum moi. */ virtual CCluster* GetNewCluster() { return new CCluster(); }
/** Tra ve binh phuong khoang cach toi vector da cho. */ virtual float Distance(const fVector3& vec);
/** Tra ve binh phuong khoang cach toi mot cum khac */ virtual float Distance(const CCluster* clust);
/** Lam sach va xoa cum nay */ virtual ~CCluster(void);
};
/** Mot danh sach cac con tro cum */ typedef list<CCluster*> ClList;
// Cluster.cpp…
void CCluster::Include(CCluster& cluster) {
VList::iterator i;
for (i = cluster.Vectors.begin(); i != cluster.Vectors.end(); ++i) { Vectors.push_back(*i);
}
UpdateMedium();
bOutlierValid = false; }
const VList& CCluster::GetVectors() const {
return Vectors; }
float CCluster::Distance(const fVector3& vec) {
return Medium.SquaredDistance(vec); }
float CCluster::Distance(const CCluster* clust) { return Medium.SquaredDistance(clust->GetRepresentative()); } /** * ClustAlgorithm.h **/ #pragma once #include "Cluster.h" /**
* Cung cap lop co so cho tat ca cac thuat toan phan cum. */
class CClustAlgorithm {
public:
CClustAlgorithm() {};
virtual void SetParameters(float theta, int q = 0) = 0; /**
* Tao ra phep phan cum toi uu cac vector su dung cac lop empty da cho. * Co the cho cac loai lop cum con khac nhau nhu tham so.
* */
virtual ClList* Clusterize(const VList* vectors, CCluster* empty) const = 0;
/** Tra ve so cum tim duoc, 0 neu khong co*/ virtual int GetClusters()
{ return 0; }
/** Tra ve tham so theta duoc su dung, 0 neu khong su dung */ virtual float GetTheta()
{ return 0.f; }
virtual float GetTheta2() { return 0.f; }
/** Tra ve ten cua thuat toan */
virtual const char* GetName() const = 0; virtual ~CClustAlgorithm(void) {};
};
// MBSAS.cpp…
ClList* CMBSAS::Clusterize(const VList* vectors, CCluster* empty) const {
int numVectors = 0; int clusters = 0; fVector3 tmp;
if ((vectors == NULL) || (empty == NULL)) return NULL;
if ((int)vectors->size() < 1) return NULL;
// Day khong la cach toi uu.... VList tmplist = *vectors;
ClList* ClusterList = new ClList(); VList::iterator iter;
ClList::iterator iter2;
// Khoi tao tat ca cac vector iter = tmplist.begin();
empty->AddVector(*iter); iter++;
ClusterList->push_back(empty); // 'Tạo ra cac cum'
for (; iter != tmplist.end(); iter++) { tmp = *iter;
float mindist = FLT_MAX; // Tim khoang cach nho nhat
for (iter2 = ClusterList->begin(); iter2 != ClusterList->end(); iter2++) {
float dist = (*iter2)->Distance(tmp); if (dist < mindist)
mindist = dist; }
// Co tao ra cum moi khong?
if ((mindist > fTheta) && ((int)ClusterList->size() < iq)) { CCluster* newclust = empty->GetNewCluster();
newclust->AddVector(tmp);
ClusterList->push_back(newclust); }
}
// Phai loai bo mau vua tao ra...
for (iter2 = ClusterList->begin(); iter2 != ClusterList->end(); iter2++) {
tmp = (*iter2)->GetRepresentative(); // Dai dien la duy nhat tmplist.remove(tmp);
}
// Phan loai cac vector con lai...
for (iter = tmplist.begin(); iter != tmplist.end(); iter++) { tmp = *iter;
float mindist = FLT_MAX; CCluster* minclust = NULL;
// Tim khoang cach cum nho nhat...
for (iter2 = ClusterList->begin(); iter2 != ClusterList->end(); iter2++) {
float dist = (*iter2)->Distance(tmp); if (dist < mindist) {
mindist = dist; minclust = *iter2; }
}
minclust->AddVector(tmp); // ...them vector vao cum }
return ClusterList; }
// TTSAS.cpp...
ClList* CTTSAS::Clusterize(const VList* vectors, CCluster* empty) const {
if ((vectors == NULL) || (empty == NULL)) return NULL;
if ((int)vectors->size() < 1) return NULL;
bool* clas = new bool[vectors->size()];
fVector3* tmplist = new fVector3[vectors->size()]; VList::const_iterator iter;
int i = 0;
for (iter = vectors->begin(); iter != vectors->end(); iter++, i++) { tmplist[i] = *iter;
}
ClList* ClusterList = new ClList(); int numVectors = (int)vectors->size(); int numDone = 0; // So mau da duoc phan lop
int existsChange = 0; // So vector duoc phan lop trong lan duyet nay
int curChange = 0; // So vector da duoc phan lop tinh den lan duyet hien tai
int prevChange = 0; // So vector da duoc phan lop trong cac lan duyet truoc
float mindist = FLT_MAX; CCluster* minclust = NULL; ClList::iterator iter2;
while (numDone < numVectors) { bool gotOne = false;
for (i = 0; i < numVectors; i++) {
if (!clas[i] && existsChange == 0 && !gotOne) { // Dam bao rang vong while se phai ket thuc :) CCluster* clust = empty->GetNewCluster(); clust->AddVector(tmplist[i]);
ClusterList->push_back(clust); clas[i] = true;
curChange++; numDone++; gotOne = true; }
else if (clas[i] == 0) { mindist = FLT_MAX;
minclust = NULL;
// Tim cum khoang cach nho nhat...
for (iter2 = ClusterList->begin(); iter2 != ClusterList->end(); iter2++) {
float dist = (*iter2)->Distance(tmplist[i]); if (dist < mindist) {
mindist = dist; minclust = *iter2; }
}
if (mindist < fTheta1) { // them vector vao cum da co minclust->AddVector(tmplist[i]);
clas[i] = true;
curChange++; numDone++; }
else if (mindist > fTheta2) { // can tao ra cum moi CCluster* clust = empty->GetNewCluster();
clust->AddVector(tmplist[i]); ClusterList->push_back(clust); clas[i] = true; curChange++; numDone++; } } else // clas == 1 curChange++;
}
existsChange = abs(curChange - prevChange); prevChange = curChange; curChange = 0; } delete empty; delete[] clas; delete[] tmplist; return ClusterList; } // GDS.cpp...
ClList* CGDS::Clusterize(const VList* vectors, CCluster* empty) const {
if ((vectors == NULL) || (empty == NULL)) return NULL;
if ((int)vectors->size() < 1) return NULL;
// Tạo ra phep phan cum khoi tao... ClList* ClusterList = new ClList(); VList::const_iterator iter;
CCluster* tmp = empty->GetNewCluster();
for (iter = vectors->begin(); iter != vectors->end(); iter++) tmp->AddVector(*iter);
ClusterList->push_back(tmp); float maxdist, maxdist2; CCluster* maxclust; ClList::iterator iter2;
while ((int)ClusterList->size() < iq) { maxdist = 0;
maxclust = NULL;
// Tim cum co phan tu outlier lon nhat...
for (iter2 = ClusterList->begin(); iter2 != ClusterList->end(); iter2++) if ((*iter2)->GetOutlierDist() > maxdist) {
maxdist = (*iter2)->GetOutlierDist(); maxclust = *iter2;
}
// Chuyen outlier vao mot cum moi
CCluster* newclust = empty->GetNewCluster(); newclust->AddVector(maxclust->GetOutlier()); maxclust->RemoveVector(maxclust->GetOutlier()); ClusterList->push_back(newclust);
bool foundOne = true;
// Khi tim thay mot vector tuong tu hon mot cum moi... while (foundOne) {
foundOne = false; // Chua tim thay vector nao fVector3 vect(0, 0, 0);
maxdist = FLT_MAX;
// Duyet qua tat ca cac vector trong cum cu
for (iter = maxclust -> GetVectors().begin();iter != maxclust-> GetVectors().end(); iter++) {
maxdist2 = newclust->Distance(*iter); // Khoang cach toi cum moi. if (maxclust->Distance(*iter) > maxdist2 && maxdist2 < maxdist) { foundOne = true;
maxdist = maxdist2; // Khoang cach gan nhat toi cum moi vect = *iter;
} }
if (foundOne) { // Tim thay mot vector? newclust->AddVector(vect); maxclust->RemoveVector(vect); } } } delete empty; return ClusterList; } // GAS.cpp...
ClList* CGAS::Clusterize(const VList* vectors, CCluster* empty) const {
if ((vectors == NULL) || (empty == NULL)) return NULL;
if ((int)vectors->size() < 1) return NULL;
// Tao ra mot phan cum khoi tao... ClList* ClusterList = new ClList(); VList::const_iterator iter;
for (iter = vectors->begin(); iter != vectors->end(); iter++) { CCluster* tmp = empty->GetNewCluster(); tmp->AddVector(*iter); ClusterList->push_back(tmp); } ClList::iterator iter2; ClList::iterator iter3; float mindist; CCluster* minclust1; CCluster* minclust2;
while ((int)ClusterList->size() > iq) { mindist = FLT_MAX;
minclust1 = NULL; minclust2 = NULL;
// Duyet hai cum ma no co khoang cach nho nhat (slow)...
for (iter2 = ClusterList->begin(); iter2 != ClusterList->end(); iter2++) {
iter2++; // Tang gia
for (iter3 = iter2--; iter3 != ClusterList->end(); iter3++) { float dist = (*iter2)->Distance(*iter3);
if (dist < mindist) {
mindist = dist; minclust1 = *iter2; minclust2 = *iter3; }
} }
// ...va ket hop hai cum voi nhau if (minclust2 != NULL) { minclust1->Include(*minclust2); ClusterList->remove(minclust2); delete minclust2; } } delete empty; return ClusterList; } // GLRenderer.cpp…
void CGLRenderer::DrawVolumes(const ClList* list) {
int c = 0;
glColor4f(0.5f, 0.5f, 0.5f, 0.4f); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (ClList::const_iterator iter=list->begin();iter!= list->end();
iter++, c+=3){ glPushMatrix();
float dist = (*iter)->GetOutlierDist(); fVector3 out = (*iter)->GetRepresentative(); glTranslatef(out.x, out.y, out.z);
glutWireSphere(sqrt(dist), 8, 8); glutSolidSphere(sqrt(dist), 8, 8); glPopMatrix(); } glDisable(GL_BLEND); }
void CGLRenderer::RotateCamera(float xrot, float yrot) {
// Quay len tren...
vdir = vdir.Rotate(vup, 3.1415f * yrot / 180.f); vleft = vleft.Rotate(vup, 3.1415f * yrot / 180.f); vup = vdir.Cross(vleft);
// Quay sang trai...
vup = vup.Rotate(vleft, 3.1415f * xrot / 180.f); vdir = vdir.Rotate(vleft, 3.1415f * xrot / 180.f); vleft = vup.Cross(vdir);
vdir.Normalize(); vleft.Normalize(); vup.Normalize(); }
A watermark is added at the end of each output PDF file.
To remove the watermark, you need to purchase the software from