Showing posts with label Khai phá dữ liệu (datamining). Show all posts
Showing posts with label Khai phá dữ liệu (datamining). Show all posts

Sunday, June 30, 2013

Thuật toán Cây quyết định ID3 và chương trình mô phỏng

1. Giải thuật ID3:

ID3_algorithm(Training_Set, Class_Labels, Attributes)

Tạo nút Root của cây quyết định

   If tất cả các ví dụ của Training_Set thuộc cùng lớp c

   Return Cây quyết định có nút Root được gắn với (có nhãn) lớp c

   If Tập thuộc tính Attributes là rỗng

   Return Cây quyết định có nút Root được gắn với nhãn lớp ≡ Majority_Class_Label(TrainingSet)

   A ← Thuộc tính trong tập Attributes có khả năng phân loại “tốt nhất” đối với Training_Set

   Thuộc tính kiểm tra cho nút Root ← A

   For each Giá trị có thể v của thuộc tính A

 Bổ sung một nhánh cây mới dưới nút Root, tương ứng với trường hợp: “Giá trị của A là v”

   Xác định Training_Setv = {ví dụ x | x ⊆ Training_Set, xA=v}

  If (Training_Setv là rỗng) Then

  Tạo một nút lá với nhãn lớp ≡ Majority_Class_Label(Training_Set)

Gắn nút lá này vào nhánh cây mới vừa tạo

Else Gắn vào nhánh cây mới vừa tạo một cây con sinh ra bởi ID3_algorithm(Training_Setv, Class_Labels, {Attributes A})

Return Root


2. Giao diện chính của chương trình Demo gồm 4 phần:

o Phần 1: Bảng lưu dữ liệu training (Data Training).

o Phần 2: Ghi ra các bước giải của thuật toán (Solutions).

o Phần 3: Vẽ cây minh họa cho thuật toán (Decision Tree).

o Phần 4: Các chức năng của chương trình (Control).


Có 4 button với các chức năng như sau:

- Load Data: Đưa dữ liệu training vào chương trình.

- ID3 – Alg: Chạy giải thuật ID3.

- Reset: Khởi động, chạy lại chương trình.

- About: Thông tin về chương trình.


3.  Các bước chạy chương trình:

- Đầu tiên, nạp dữ liệu vào chương trình bằng button Load Data.

Dữ liệu được đưa lên bảng Data Training (Phần 1).

- Sau đó, nhấn button ID3 – Alg để chạy giải thuật.

Các bước giải sẽ được hiện ra ở phần 2 (Solutions).

Cây được vẽ ra ở phần 3 (Decision Tree).


4. Giao diện chương trình:

Chương trình gồm những hàm chính sau:

 Hàm tính Entropy:

· Công thức:    Entropy (S) = – p+ log2 p+ – p- log2 p-

· Code [C#]:

private double GetEntropy(int Positives , int Negatives)
{
if (Positives == 0)
return 0;
if (Negatives == 0)
return 0;
double Entropy;
int total = Negatives + Positives;
double RatePositves = (double)Positives / total;
double RateNegatives = (double)Negatives / total;
Entropy = -RatePositves * Math.Log(RatePositves, 2) – RateNegatives * Math.Log(RateNegatives, 2);
return Entropy;
}


 Hàm tính Gain:

· Công thức: 


· Code [C#]:

private double Gain(List<List<string>> Examples, Attribute A, string bestat)
{
double result;
int CountPositives = 0;
int[] CountPositivesA = new int[A.Value.Count];
int[] CountNegativeA = new int[A.Value.Count];
int Col = Attributes.IndexOf(A);
for (int i = 0; i < A.Value.Count; i++)
{
CountPositivesA[i] = 0;
CountNegativeA[i] = 0;
}
for (int i = 0; i < Examples.Count; i++)
{
int j = A.Value.IndexOf(Examples[i][Col].ToString());
if (Examples[i][Examples[0].Count – 1]==”yes”)
{
CountPositives++;
CountPositivesA[j]++;
}
else
{
CountNegativeA[j]++;
}
}
result = GetEntropy(CountPositives, Examples.Count – CountPositives);
for (int i = 0; i < A.Value.Count; i++)
{
double RateValue = (double)(CountPositivesA[i] + CountNegativeA[i]) / Examples.Count;
result = result – RateValue * GetEntropy(CountPositivesA[i], CountNegativeA[i]);
}
Solution = Solution + “n * Gain(” + bestat + “,” + A.Name + “) = ” + result.ToString();
return result;
}



 Hàm chọn đặc tính tốt nhất:

· Phương pháp:
    - Dựa vào giá trị gain của các đặc tính, đặc tính nào có Gain lớn nhất.

    - Chọn đặc tính đó – đặc tính tốt nhất.

· Code [C#]:

private Attribute GetBestAttribute(List<List<string>> Examples, List<Attribute> Attributes, string bestat)
{
double MaxGain = Gain(Examples, Attributes[0], bestat);
int Max = 0;
for (int i = 1; i < Attributes.Count; i++)
{
double GainCurrent = Gain(Examples, Attributes[i], bestat);
if (MaxGain < GainCurrent)
{
MaxGain = GainCurrent;
Max = i;
}
}
return Attributes[Max];
}
 Hàm thực hiện giải thuật ID3:
Code:
private TreeNode ID3(List<List<string>> Examples, List<Attribute> Attribute,string bestat)
{
if (CheckAllPositive(Examples))
{
return new TreeNode(new Attribute(“Yes”));
}
if (CheckAllNegative(Examples))
{
return new TreeNode(new Attribute(“No”));
}
if (Attribute.Count == 0)
{
return new TreeNode(new Attribute(GetMostCommonValue(Examples)));
}
Attribute BestAttribute = GetBestAttribute(Examples, Attribute, bestat);
int LocationBA = Attributes.IndexOf(BestAttribute);
TreeNode Root = new TreeNode(BestAttribute);
for (int i = 0; i < BestAttribute.Value.Count; i++)
{
List<List<string>> Examplesvi = new List<List<string>>();
for (int j = 0; j < Examples.Count; j++)
{
if (Examples[j][LocationBA].ToString() == BestAttribute.Value[i].ToString())
Examplesvi.Add(Examples[j]);
}
if (Examplesvi.Count==0)
{
return new TreeNode(new Attribute(GetMostCommonValue(Examplesvi)));
}
else
{
Attribute.Remove(BestAttribute);
Root.AddNode(ID3(Examplesvi, Attribute,BestAttribute.Value[i]));
}
}
return Root;
}


Toàn bộ chương trình demo ở đây: http://adf.ly/RJwUY [sau 5s, click Bỏ qua quảng cáo]

(theo csshare)

Wednesday, June 26, 2013

Thuật toán K-Mean trong bài toán Phân cụm dữ liệu

I.  GIỚI THIỆU
    Thuật toán K-means clustering do MacQueen giới thiệu trong tài liệu “J. Some Methods for Classification and Analysis of Multivariate Observations” năm 1967.
K-means Clustering là một thuật toán dùng trong các bài toán phân loại/nhóm n đối tượng thành k nhóm dựa trên đặc tính/thuộc tính của đối tượng (k £n nguyên, dương).
Về nguyên lý, có n đối tượng, mỗi đối tượng có m thuộc tính, ta phân chia được các đối tượng thành k nhóm dựa trên các thuộc tính của đối tượng bằng việc áp dụng thuật toán này.
Coi mỗi thuộc tính của đối tượng (đối tượng có m thuộc tính) như một toạ độ của không gian m chiều và biểu diễn đối tượng như một điểm của không gian m chiều.
ai =( xi1, xi2, ... xim)                   ( 1)
ai (i=1..n) - đối tượng thứ i
xij (i=1..n, j=1..m) - thuộc tính thứ j của đối tượng i
Phương thức phân loại/nhóm dữ liệu thực hiện dựa trên khoảng cách Euclidean nhỏ nhất giữa đối tượng đến phần tử  trung tâm của các nhóm.
Phần tử trung tâm của nhóm được xác định bằng giá trị trung bình các phần tử trong nhóm.
2. Khoảng cách Euclidean.
   ai=(xi1, xi2,... xim) i=1..n - đối tượng thứ i cần phân phân loại
cj=(xj1, xj2,... xjm) j=1..k - phần tử trung tâm nhóm j
Khoảng cách Euclidean từ đối tượng ai đến phần tử trung tâm nhóm j cj được tính toán dựa trên công thức:
    


( 2)

dji - khoảng cách Euclidean từ ai đến cj
xis - thuộc tính thứ s của đối tượng ai
xjs - thuộc tính thứ s của phần tử trung tâm cj

3. Phần tử trung tâm.
k phần tử trung tâm (k nhóm) ban đầu được chọn ngẫu nhiên, sau mỗi lần nhóm các đối tượng vào các nhóm, phần tử trung tâm được tính toán lại.
Clusteri = {a1, a2 .... at} – Nhóm thứ i
i=1..k,  k số cluster
j= 1..m,  m số thuộc tính
t - số phần tử hiện có của nhóm thứ i
xsj - thuộc tính thứ j của phần tử s   s=1..t
cij - toạ độ thứ j của phần tử trung tâm nhóm i;
                     


( 3)


II. GIỚI THIỆU VỀ THUẬT TOÁN K-MEANS.
Sơ đồ thuật toán:


Hình 3:  Sơ đồ thuật toán K-means clustering

Thuật toán k-means bao gồm các bước cơ bản sau :
Input: Số cụm k và các trọng tâm cụm {mj}kj=1.
Output: Các cụm C[i] (1  ≤  i  ≤  k) và hàm tiêu chuẩn E đạt giá trị tối thiểu.
Begin
Bước 1: Khởi tạo
Chọn k trọng tâm {mj}kj=1 ban đầu trong không gian Rd (d là số chiều của dữ liệu). Việc lựa chọn này có thể là ngẫu nhiên hoặc theo kinh nghiệm.
Bước 2: Tính toán khoảng cách
Đối với mỗi điểm Xi  (1 ≤ i ≤ n), tính toán khoảng cách của nó tới mỗi trọng tâm mj (1 ≤ j ≤  k). Sau đó tìm trọng tâm gần nhất đối với mỗi điểm.
Bước 3: Cập nhật lại trọng tâm
Đối với mỗi 1 ≤ j ≤ k, cập nhật trọng tâm cụm mj  bằng cách xác định trung bình cộng các vectơ đối tượng dữ liệu.
Điều kiện dừng:
Lặp lại các bước 2 và 3 cho đến khi các trọng tâm của cụm không thay đổi.
End.

Thuật toán k-means trên được chứng minh là hội tụ và có độ phức tạp tính toán là: 

 Trong đó, n là số đối tượng dữ liệu, k là số cụm dữ liệu, d là số chiều, τ là số vòng lặp, Tflop là thời gian để thực hiện một phép tính cơ sở như phép tính nhân, chia,... Như vậy, do k-means phân tích phân cụm đơn giản nên có thể áp dụng đối với tập dữ liệu lớn.Tuy nhiên, nhược điểm của k-means là chỉ áp dụng với dữ liệu có thuộc tính số và khám phá ra các cụm có dạng hình cầu, k-means còn rất nhạy cảm với nhiễu và các phần tử ngoại lai trong dữ liệu. Hơn nữa, chất lượng phân cụm dữ liêuk của thuật toán k-means phụ thuộc nhiều vào các tham số đầu vào như: số cụm k và k trọng tâm khởi tạo ban đầu. Trong trường hợp các trọng tâm khởi tạo ban đầu mà quá lệch so với các trọng tâm cụm tự nhiên thì kết quả phân cụm của k-means là rất thấp, nghĩa là các cụm dữ liệu được khám phá rất lệch so với các cụm trong thực tế. Trên thực tế chưa có một giải pháp tối ưu nào để chọn các tham số đầu vào, giải pháp thường được sử dụng nhất là thử nghiệm với các giá trị đầu vào k khác nhau rồi sau đó chọn giải pháp tốt nhất.



III. CHƯƠNG TRÌNH DEMO.
Chương trình gồm các Hàm chính:
·        kMeanCluster– Thể hiện một đối tượng
·        dist – Đối tượng trung tâm

Sub kMeanCluster(Data() As Variant, numCluster As Integer)
Dim i As Integer
Dim j As Integer
Dim X As Single
Dim Y As Single
Dim min As Single
Dim cluster As Integer
Dim d As Single
Dim sumXY()
Dim isStillMoving As Boolean
isStillMoving = True
If totalData <= numCluster Then
    Data(0, totalData) = totalData               ' cluster No = total data
    Centroid(1, totalData) = Data(1, totalData)  ' X
    Centroid(2, totalData) = Data(2, totalData)  ' Y
Else                    'calculate minimum distance to assign the new data
    min = 10 ^ 10                                'big number
    X = Data(1, totalData)
    Y = Data(2, totalData)
    For i = 1 To numCluster
        d = dist(X, Y, Centroid(1, i), Centroid(2, i))
        If d < min Then
            min = d
            cluster = i
        End If
    Next i
    Data(0, totalData) = cluster
   
    Do While isStillMoving
    ' this loop will surely convergent        calculate new centroids
   ReDim sumXY(1 To 3, 1 To numCluster) '1=X,2=Y,3=count number of data
        For i = 1 To totalData
            sumXY(1, Data(0, i)) = Data(1, i) + sumXY(1, Data(0, i))
            sumXY(2, Data(0, i)) = Data(2, i) + sumXY(2, Data(0, i))
            sumXY(3, Data(0, i)) = 1 + sumXY(3, Data(0, i))
        Next i
        For i = 1 To numCluster
            Centroid(1, i) = sumXY(1, i) / sumXY(3, i)
            Centroid(2, i) = sumXY(2, i) / sumXY(3, i)
        Next i
        'assign all data to the new centroids
        isStillMoving = False
        For i = 1 To totalData
            min = 10 ^ 10                                'big number
            X = Data(1, i)
            Y = Data(2, i)
            For j = 1 To numCluster
                d = dist(X, Y, Centroid(1, j), Centroid(2, j))
                If d < min Then
                    min = d
                    cluster = j
                End If
            Next j
            If Data(0, i) <> cluster Then
                Data(0, i) = cluster
                isStillMoving = True
            End If
        Next i
    Loop
End If

End Sub


Function dist(X1 As Single, Y1 As Single, X2 As Single, Y2 As Single) As Single
' calculate Euclidean distance
    dist = Sqr((Y2 - Y1) ^ 2 + (X2 - X1) ^ 2)

End Function


Private Function min2(num1, num2)
' return minimum value between two numbers
    If num1 < num2 Then
        min2 = num1
    Else
        min2 = num2
    End If

End Function




>> DOWNLOAD CODE TẠI ĐÂY

KẾ QUẢ CHƯƠNG TRÌNH
Dữ liệu vào
    Data(1, 1) = 1
    Data(2, 1) = 1
   
    Data(1, 2) = 5
    Data(2, 2) = 2
   
    Data(1, 3) = 8
    Data(2, 3) = 5
   
    Data(1, 4) = 7
    Data(2, 4) = 3
       
    Data(1, 5) = 5
    Data(2, 5) = 1

Kết quả chạy với k= 3





Kết quả chạy với k= 2


Giống như các thuật toán khác, k- mean cũng có một số hạn chế nhất định:
-         Việc khởi tạo phần tử trung tâm của nhóm ban đầu ảnh hưởng đến sự phân chia đối tượng vào nhóm trong trường hợp dữ liệu không lớn.
-         Số nhóm k luôn phải được xác định trước.
-         Không xác định được rõ ràng vùng của nhóm, cùng 1 đối tượng, nó có thể được đưa vào nhóm này hoặc nhóm khác khi dung lượng dữ liệu thay đổi.
-         Điều kiện khởi tạo có ảnh hưởng lớn đến kết quả. Điều kiện khởi tạo khác nhau có thể cho ra kết quả phân vùng nhóm khác nhau.
-         Không xác định được mức độ ảnh hưởng của thuộc tính đến quá trình tạo nhóm.
Như vậy, với dữ liệu nhỏ, thuật toán có thể có những hạn chế. Để khắc phục những hạn chế này, nên sử dụng thuật toán kmean trong trường hợp dữ liệu lớn.
Về vấn đề hạn chế phân nhóm, có thể dùng phương pháp xác định trung tuyến thay vì xác định mean.

Một quan niệm cho rằng k-means không thể dùng cho dữ liệu có kiểu là định lượng. Điều này không đúng, k-means có thể được dùng giải quyết các bài toán dữ liệu đa biến, thậm chí cho các bài toán có nhiều dạng dữ liệu. Chìa khoá cho việc giải bài toán này của k-means là sử dụng ma trận khoảng cách.

TÀI LIỆU THAM KHẢO

1.      Bài giảng của thầy Nguyễn Bá Tường
2.      k-means clustering http://en.wikipedia.org/wiki/K-means_clustering
3.      How the K-Mean Clustering algorithm works? http://people.revoledu.com/kardi/tutorial/kMean/Algorithm.htm
4.      Kiri Wagstaff, Claire Cardie; Constrained k-means clustering with Background Knowledge http://www.cse.msu.edu/~cse802/notes/ConstrainedKmeans.pdf

[TxT]

Ví dụ mảng 2 chiều [C/C++]

BAI TAP MANG 2 CHIEU - 29.11.19 /* Viết các hàm thực hiện 1.Nhập vào từ bàn phím ma trận vuông chứa các số nguyên có kích thước n (3...