Bài 58: K-Means gom cụm Khách hàng theo độ tuổi, thu nhập và ngân sách chi tiêu

Bài học này Tui hướng dẫn các bạn cách lập trình K-Means để gom cụm khách hàng theo thu nhập, độ tuổi và ngân sách chi tiêu. Chúng ta dùng phương pháp Elbow để tìm ra K Cụm tối ưu nhất để gom, bài học này chúng ta trực quan hóa các cụm bằng 2D và 3D. Đồng thời phân loại chi tiết Khách hàng theo từng cụm để dễ dàng đưa ra các chính sách chăm sóc và tiếp thị phù hợp. Lý thuyết K-Means các bạn đọc trong bài 57

Bạn tải cơ sở dữ liệu MySQL Server “SalesDatabase “trong link:

https://tranduythanh.com/datasets/salesdatabase.rar

Giải nén ra ta có thư mục salesdatabase

Trong MySQL Workbench bạn nhớ tạo một Schema tên là “salesdatabase” sau đó dùng chức năng import đã được học để import dữ liệu vào.

Đồng thời trong quá trình lập trình liên quan tới kết nối cơ sở dữ liệu thì nhớ đổi các thông số kết nối theo máy tính của bạn đã cài đặt.

Cấu trúc bảng dữ liệu như hình dưới đây:

Chúng ta sẽ gom cụm khách hàng bằng K-Means theo nhiều chiều khác nhau, và cho nhận xét. Yêu cầu các thuộc tính liên quan tới Customer dùng để gom cụm sẽ được trích suất từ 2 bảng dữ liệu “customer” và “customer_spend_score” theo SQL script như sau:

select distinct customer.CustomerID, Age, Annual_Income, Spending_Score
from customer, customer_spend_score
where customer.CustomerID=customer_spend_score.CustomerID

Kết quả tiền xử lý dữ liệu:

Trong Pycharm, ta tạo một dự án tên “KMeansCustomer“:

(1) File “Connector.py” là mã lệnh để kết nối, truy vấn dữ liệu:

#python -m pip install mysql-connector-python
import mysql.connector
import traceback
import pandas as pd

class Connector:
    def __init__(self,server=None, port=None, database=None, username=None, password=None):
        self.server=server
        self.port=port
        self.database=database
        self.username=username
        self.password=password
    def connect(self):
        try:
            self.conn = mysql.connector.connect(
                host=self.server,
                port=self.port,
                database=self.database,
                user=self.username,
                password=self.password
            )
            return self.conn
        except:
            self.conn=None
            traceback.print_exc()
        return None

    def disConnect(self):
        if self.conn != None:
            self.conn.close()

    def queryDataset(self, sql):
        try:
            cursor = self.conn.cursor()
            cursor.execute(sql)
            df = pd.DataFrame(cursor.fetchall())
            df.columns=cursor.column_names
            return df
        except:
            traceback.print_exc()
        return None

Tiếp theo ta viết mã lệnh cho “CustomerCluster.py” và thử nghiệm các chức năng:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
from sklearn.cluster import KMeans
import numpy as np

from Connector import Connector

conn=Connector('localhost',3306,'salesdatabase','root','@Obama123')
conn.connect()

sql1="select * from customer"
df1=conn.queryDataset(sql1)
print(df1)

Thực thi mã lệnh trên ta có kết quả:

Tiếp tục bổ sung nối đuôi các mã lệnh tiền xử lý dữ liệu để rút trích thông tin khách hàng, tuổi, thu nhập, điểm tiêu dùng và cuối tập tin “CustomerCluster.py”:

sql2="select distinct customer.CustomerId, Age, Annual_Income, Spending_Score " \
     "from customer, customer_spend_score " \
     "where customer.CustomerId=customer_spend_score.CustomerID"

df2=conn.queryDataset(sql2)
df2.columns = ['CustomerId', 'Age', 'Annual Income', 'Spending Score']

print(df2)

print(df2.head())

print(df2.describe())

Thực hiện mã lệnh trên ta có kết quả:

Tiếp tục bổ sung nối đuôi mã lệnh dưới đây vào “CustomerCluster.py” để thực hiển Histogram:

def showHistogram(df,columns):
    plt.figure(1, figsize=(7,8))
    n = 0
    for column in columns:
        n += 1
        plt.subplot(3, 1, n)
        plt.subplots_adjust(hspace=0.5, wspace=0.5)
        sns.distplot(df[column], bins=32)
        plt.title(f'Histogram of {column}')
    plt.show()

showHistogram(df2,df2.columns[1:])

Thực thi mã lệnh trên ta có kết quả:

Nhìn vào biểu đồ Histogram, ta thấy được sự phân phối có tần suất của các tập dữ liệu liên quan tới Age, Annual Income và Spending Score.

Trong thuật toán K-Means thì chúng ta cần phải xác định trước số cụm. Và ta thường phân vân đâu là số lượng cụm cần phân chia tốt nhất đối với một bộ dữ liệu cụ thể, thì phương pháp Elbow là một cách giúp ta lựa chọn được số lượng các cụm phù hợp dựa vào đồ thị trực quan hoá bằng cách nhìn vào sự suy giảm của hàm biến dạng và lựa chọn ra điểm khuỷ tay (elbow point)

Tiếp tục bổ sung nối đuôi mã lệnh vào “CustomerCluster.py” để tính phương pháp Elbow nhằm tìm ra K cụm tối ưu cho K-Means:

def elbowMethod(df,columnsForElbow):
    X = df.loc[:, columnsForElbow].values
    inertia = []
    for n in range(1 , 11):
        model = KMeans(n_clusters = n,
                   init='k-means++',
                   max_iter=500,
                   random_state=42)
        model.fit(X)
        inertia.append(model.inertia_)

    plt.figure(1 , figsize = (15 ,6))
    plt.plot(np.arange(1 , 11) , inertia , 'o')
    plt.plot(np.arange(1 , 11) , inertia , '-' , alpha = 0.5)
    plt.xlabel('Number of Clusters') , plt.ylabel('Cluster sum of squared distances')
    plt.show()

-init: dùng k-means++

-max_iter: 500 lần

-random_state=42 để dùng cùng 1 phân bố dữ liệu chỗ mỗi lần chạy đảm bảo nhất quán

Ta thử nghiệm tìm K cụm theo phương pháp Elbow với 2 đặc trưng: Age và Spending Score. Ta bổ sung nối đuôi mã lệnh dưới đây vào “CustomerCluster.py”

columns=['Age','Spending Score']
elbowMethod(df2,columns)

Chạy phương thức elbow và có kết quả k=4:

Viết hàm runKMeans() với một đối số truyền vào là 1 ma trận X bất kỳ và số cluster muốn gom, cluster được lấy theo phương thức elbow

Tiếp tục bổ sung nối đuôi mã lệnh runKMeans() vào cuối “CustomerCluster.py”:

def runKMeans(X,cluster):
    model = KMeans(n_clusters=cluster,
                   init='k-means++',
                   max_iter=500,
                   random_state=42)
    model.fit(X)
    labels = model.labels_
    centroids = model.cluster_centers_
    y_kmeans = model.fit_predict(X)
    return y_kmeans,centroids,labels

Thử nghiệm triệu gọi hàm runKMeans(), với columns[Age, Spending Score], cluster=4. Tiếp tục bổ sung mã lệnh nối đuôi vào “CustomerCluster.py” để xem kết quả:

X = df2.loc[:, columns].values
cluster=4
colors=["red","green","blue","purple","black","pink","orange"]

y_kmeans,centroids,labels=runKMeans(X,cluster)
print("y_kmeans:")
print(y_kmeans)
print("centroids:")
print(centroids)
print("labels:")
print(labels)
df2["cluster"]=labels
print("df2:")
print(df2)

Mảng X được lấy theo các columns (các thuộc tính mà customer ta muốn clustering). Đồng thời tạo cột cluster cho df2, nhằm phục vụ cho truy vấn danh sách Customer chi tiết theo từng cụm

Thực thi mã lệnh ở trên ta có kết quả:

Tiếp tục Viết hàm visualizeKMeans nhận vào 6 đối số, hàm này trực quan hóa kết quả gom cụm. Hàm này viết nối đuôi vào “CustomerCluster.py“:

•X: ma trận đã gom cụm

•y_kmeans: nhãn các phần tử được gom cụm

•cluster: số cụm

•title: tiêu đề

•xlabel: nhãn trục x

•ylabel: nhãn trục y

•colors: mảng màu

def visualizeKMeans(X,y_kmeans,cluster,title,xlabel,ylabel,colors):
    plt.figure(figsize=(10, 10))
    for i in range(cluster):
        plt.scatter(X[y_kmeans == i, 0],
                    X[y_kmeans == i, 1],
                    s=100,
                    c=colors[i],
                    label='Cluster %i'%(i+1))
    plt.title(title)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.legend()
    plt.show()

Triệu gọi hàm visualizeKMeans, bằng cách tiếp tục viết nối đuôi mã lệnh vào “CustomerCluster.py“:

visualizeKMeans(X,
                y_kmeans,
                cluster,
                "Clusters of Customers - Age X Spending Score",
                "Age",
                "Spending Score",
                colors)

Kết quả sau khi triệu gọi hàm visualizeKMeans.

Gom cụm customer theo cột Age Spending Score

Thực nghiệm gom cụm theo 2 cột khác: Cột Annual Income Spending Score

Tiếp tục bổ sung nối đuôi mã lệnh sau vào “CustomerCluster.py”:

columns=['Annual Income','Spending Score']
elbowMethod(df2,columns)

Thực thi lệnh trên ta có kết quả:

Như vậy, theo phương thức elbow và có kết quả k=5

Tiến hành thực nghiệm gom cụm với cluster=5 và Cột Annual Income Spending Score

Tiếp tục bổ sung nối đuôi mã lệnh sau vào “CustomerCluster.py”:

X = df2.loc[:, columns].values
cluster=5

y_kmeans,centroids,labels=runKMeans(X,cluster)
print("y_kmeans:")
print(y_kmeans)
print("centroids:")
print(centroids)
print("labels:")
print(labels)
df2["cluster"]=labels
print("df2:")
print(df2)

Mảng X được lấy theo các columns (các thuộc tính mà customer ta muốn clustering). Đồng thời tạo cột cluster cho df2, nhằm phục vụ cho truy vấn danh sách Customer chi tiết theo từng cụm

Thực thi mã lệnh trên ta có kết quả:

Triệu gọi hàm visualizeKMeans để trực quan hóa gom cụm với K=5. Tiếp tục bổ sung nối đuôi mã lệnh vào “CustomerCluster.py”:

visualizeKMeans(X,
                y_kmeans,
                cluster,
                "Clusters of Customers - Annual Income X Spending Score",
                "Annual Income",
                "Spending Score",
                colors)

Kết quả sau khi triệu gọi hàm visualizeKMeans. Gom cụm customer theo cột Annual IncomeSpending Score với K=5

Tiếp tục thực nghiệm gom cụm theo 3 cột khác: Cột Age, Annual IncomeSpending Score

Ta tiếp tục viết nối đuôi mã lệnh vào “CustomerCluster.py”:

columns=['Age','Annual Income','Spending Score']
elbowMethod(df2,columns)

Chạy phương thức elbow và có kết quả k=6

Tiến hành thực nghiệm gom cụm với cluster=6 và Cột Age, Annual IncomeSpending Score

Ta viết nối đuôi mã lệnh vào “CustomerCluster.py”:

X = df2.loc[:, columns].values
cluster=6

y_kmeans,centroids,labels=runKMeans(X,cluster)
print("y_kmeans:")
print(y_kmeans)
print("centroids:")
print(centroids)
print("labels:")
print(labels)
df2["cluster"]=labels
print("df2:")
print(df2)

Mảng X được lấy theo các columns (các thuộc tính mà customer ta muốn clustering). Đồng thời tạo cột cluster cho df2, nhằm phục vụ cho truy vấn danh sách Customer chi tiết theo từng cụm

Thực thi mã lệnh ta có kết quả:

Vì trường hợp này dạng 3 thuộc tính (cột) nên ta bổ sung thêm 1 hàm trực quan hóa 3D kết quả gom cụm:

df: tập dữ liệu đã gom cụm.

columns: dữ liệu các trục. Là dữ liệu có các cột mà ta gom cụm

hover_data: Khi di chuyển chuột vào node sẽ hiển thị chi tiết.

cluser: số cụm

Ta tiếp tục bổ sung mã lệnh vào cuối “CustomerCluster.py”:

def visualize3DKmeans(df,columns,hover_data,cluster):
    fig = px.scatter_3d(df,
                        x=columns[0],
                        y=columns[1],
                        z=columns[2],
                        color='cluster',
                        hover_data=hover_data,
                        category_orders={"cluster": range(0, cluster)},
                        )
    fig.update_layout(margin=dict(l=0, r=0, b=0, t=0))
    fig.show()

Triệu gọi hàm trực quan hóa gom cụm 3D. Ở đây hover_data lấy theo cột dữ liệu để chương trình tự động mapping chính xác dữ liệu hiển thị

Tiêp tục bổ sung mã lệnh vào cuối “CustomerCluster.py”:

hover_data=df2.columns
visualize3DKmeans(df2,columns,hover_data,cluster)

Thực thi mã lệnh ta có kết quả:

Kết quả trực quan hóa gom cụm 3D.

Ta có thể tương tác trên chart 3D này, di chuyển tới từng cụm, vào từng node để xem dữ liệu.

Có  thể tương tác trên các node góc phải màn hình, xuất chart ra tập tin ảnh

(Máy tính cần có cấu hình mạnh để render 3D)

minh họa thêm tương các node và cụm:

Dưới đây là coding đầy đủ của “CustomerCluster.py”:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
from sklearn.cluster import KMeans
import numpy as np

from Connector import Connector

conn=Connector('localhost',3306,'salesdatabase','root','@Obama123')
conn.connect()

sql1="select * from customer"
df1=conn.queryDataset(sql1)
print(df1)

sql2="select distinct customer.CustomerId, Age, Annual_Income, Spending_Score " \
     "from customer, customer_spend_score " \
     "where customer.CustomerId=customer_spend_score.CustomerID"

df2=conn.queryDataset(sql2)
df2.columns = ['CustomerId', 'Age', 'Annual Income', 'Spending Score']

print(df2)

print(df2.head())

print(df2.describe())

def showHistogram(df,columns):
    plt.figure(1, figsize=(7,8))
    n = 0
    for column in columns:
        n += 1
        plt.subplot(3, 1, n)
        plt.subplots_adjust(hspace=0.5, wspace=0.5)
        sns.distplot(df[column], bins=32)
        plt.title(f'Histogram of {column}')
    plt.show()

showHistogram(df2,df2.columns[1:])

def elbowMethod(df,columnsForElbow):
    X = df.loc[:, columnsForElbow].values
    inertia = []
    for n in range(1 , 11):
        model = KMeans(n_clusters = n,
                   init='k-means++',
                   max_iter=500,
                   random_state=42)
        model.fit(X)
        inertia.append(model.inertia_)

    plt.figure(1 , figsize = (15 ,6))
    plt.plot(np.arange(1 , 11) , inertia , 'o')
    plt.plot(np.arange(1 , 11) , inertia , '-' , alpha = 0.5)
    plt.xlabel('Number of Clusters') , plt.ylabel('Cluster sum of squared distances')
    plt.show()

columns=['Age','Spending Score']
elbowMethod(df2,columns)

def runKMeans(X,cluster):
    model = KMeans(n_clusters=cluster,
                   init='k-means++',
                   max_iter=500,
                   random_state=42)
    model.fit(X)
    labels = model.labels_
    centroids = model.cluster_centers_
    y_kmeans = model.fit_predict(X)
    return y_kmeans,centroids,labels

X = df2.loc[:, columns].values
cluster=4
colors=["red","green","blue","purple","black","pink","orange"]

y_kmeans,centroids,labels=runKMeans(X,cluster)
print("y_kmeans:")
print(y_kmeans)
print("centroids:")
print(centroids)
print("labels:")
print(labels)
df2["cluster"]=labels
print("df2:")
print(df2)

def visualizeKMeans(X,y_kmeans,cluster,title,xlabel,ylabel,colors):
    plt.figure(figsize=(10, 10))
    for i in range(cluster):
        plt.scatter(X[y_kmeans == i, 0],
                    X[y_kmeans == i, 1],
                    s=100,
                    c=colors[i],
                    label='Cluster %i'%(i+1))
    plt.title(title)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.legend()
    plt.show()

visualizeKMeans(X,
                y_kmeans,
                cluster,
                "Clusters of Customers - Age X Spending Score",
                "Age",
                "Spending Score",
                colors)

columns=['Annual Income','Spending Score']
elbowMethod(df2,columns)

X = df2.loc[:, columns].values
cluster=5

y_kmeans,centroids,labels=runKMeans(X,cluster)
print("y_kmeans:")
print(y_kmeans)
print("centroids:")
print(centroids)
print("labels:")
print(labels)
df2["cluster"]=labels
print("df2:")
print(df2)

visualizeKMeans(X,
                y_kmeans,
                cluster,
                "Clusters of Customers - Annual Income X Spending Score",
                "Annual Income",
                "Spending Score",
                colors)

columns=['Age','Annual Income','Spending Score']
elbowMethod(df2,columns)

X = df2.loc[:, columns].values
cluster=6

y_kmeans,centroids,labels=runKMeans(X,cluster)
print("y_kmeans:")
print(y_kmeans)
print("centroids:")
print(centroids)
print("labels:")
print(labels)
df2["cluster"]=labels
print("df2:")
print(df2)

def visualize3DKmeans(df,columns,hover_data,cluster):
    fig = px.scatter_3d(df,
                        x=columns[0],
                        y=columns[1],
                        z=columns[2],
                        color='cluster',
                        hover_data=hover_data,
                        category_orders={"cluster": range(0, cluster)},
                        )
    fig.update_layout(margin=dict(l=0, r=0, b=0, t=0))
    fig.show()

hover_data=df2.columns
visualize3DKmeans(df2,columns,hover_data,cluster)

Như vậy tới đây Tui đã hoàn tất hướng dẫn các bạn cách lập trình K-Means để gom cụm khách hàng theo thu nhập, độ tuổi và ngân sách chi tiêu. Chúng ta dùng phương pháp Elbow để tìm ra K Cụm tối ưu nhất để gom, bài học này chúng ta trực quan hóa các cụm bằng 2D và 3D. Đồng thời phân loại chi tiết Khách hàng theo từng cụm để dễ dàng đưa ra các chính sách chăm sóc và tiếp thị phù hợp.

Bài học này rất thiết thực, ứng dụng vào thực tiễn rất lớn, các bạn cố gắng thực hành nhiều lần để hiểu rõ về nó, cũng như có thể áp dụng vào dự án thực tế của doanh nghiệp

Source code đầy đủ của dự án các bạn tải ở đây:

https://www.mediafire.com/file/hgvx5xusot3enhs/KMeansCustomer.rar/file

Bắt đầu từ bài học sau Tui sẽ viết các bài Blog liên quan tới Hợp đồng thông minh và Công nghệ Blockchain, một trong những kiến thức và công nghệ nổi đình nổi đám hiện nay, các bạn chú ý theo dõi.

Chúc các bạn thành công

Bài 57: Minh họa giải thuật gom cụm K-Means bằng toán học

K-Means là một trong những thuật toán phổ biến và được sử dụng rất nhiều trong kỹ thuật gom cụm. Ý tưởng chính của thuật toán này là tìm cách phân nhóm các đối tượng đã cho vào K cụm sao cho tổng khoảng cách giữa các đối tượng đến tâm nhóm là nhỏ nhất. Thường K là số cụm được xác định trước và thường lấy ý kiến của chuyên gia, K phải nguyên dương. Khoảng cách giữa các đối tượng thường được sử dụng là khoảng cách Euclid.

Trong toán học, khoảng cách Euclid (tiếng Anh: Euclidean distance) giữa hai điểm trong không gian Euclid là độ dài của đoạn thẳng nối hai điểm đó. Có thể tính nó từ tọa độ Descartes của hai điểm bằng cách sử dụng định lý Pythagoras, do đó còn có tên gọi khác là khoảng cách Pythagoras (tiếng Anh: Pythagorean distance).

Src: Wikipedia

Đầu vào:

•Tập các  đối tượng X = {xi| i = 1, 2, …, N},

•Số cụm: K

Đầu ra:

•Các cụm Ci ( i = 1 ÷ K) tách rời và hàm tiêu chuẩn E đạt giá trị tối thiểu.

Trong đó cj là trọng tâm của cụm Cj

Chu trình hoạt động thuật toán:

  • Thuật toán hoạt động trên 1 tập vectơ d chiều, tập dữ liệu X gồm N phần tử:

  X = {xi | i = 1, 2, …, N}

  • K-Mean lặp lại nhiều lần quá trình:
    • Gán dữ liệu.
    • Cập nhật lại vị trí trọng tâm.
  • Quá trình lặp dừng lại khi trọng tâm hội tụ và mỗi đối tượng là 1 bộ phận của 1 cụm.

Các bước thực hiện thuật toán:

Dựa vào chu trình và lưu đồ thuật toán, ta có thể diễn giải các bước thực hiện như sau:

Bước 1 – Khởi tạo

  Chọn K trọng tâm {ci} ngẫu nhiên hoặc theo tiêu chuẩn (i = 1÷K).

Bước 2 – Tính toán khoảng cách

Bước 3 – Cập nhật lại trọng tâm, ta thường tính giá trị trung bình

Bước 4 – Điều kiện dừng

Ví dụ gom cụm bằng K-Means với bảng dữ liệu sau (k=2) và giả sử r3, r5 là center mặc định:

Value 1Value 2Value 3Value 4Value 5Value 6Value 7Value 8Value 9Value 10Value 11
r1110.50.50000.50.2500
r2110.50.50000.50.2500
r30.50.5110000.330.3300
r40.50.5110000.330.3300
r500001110000
r600001110000
r700001110000
r80.50.50.330.3300010.250.170.17
r90.250.250.330.330000.2510.750.75
r1000000000.170.7511
r1100000000.170.7511

Sau đây là chi tiết các bước thực hiện giải thuật K-Means để gom cụm. Dùng Euclid để tính các khoảng cách:

Bước 1: Khởi tạo
Giả sử chọn ngẫu nhiên 2 Trọng tâm ban đầu: r3; r5

* Gọi V1 là véc tơ trọng tâm của C1: Ta tính được V1(0.5,0.5,1,1,0,0,0,0.33,0.33,0,0)
* Gọi V2 là véc tơ trọng tâm của C2: Ta tính được V2(0,0,0,0,1,1,1,0,0,0,0)

Bước 2: Tính khoảng cách từ các đỉnh tới các Vector trọng tâm:

– d([r1],V1)=1.02 < d([r1],V2)=2.41. Vậy ta gom [r1] vào cụm C1.

Lý giải:

Ta tính được d([r1],V1)=1.02 từ công thức sau:

Tương tự ta cũng tính được d([r1],V2)=2.41 từ công thức sau:

Tương tự ta tính được khoảng cách tới trọng tâm cho các đỉnh còn lại (Các bạn cần viết lại công thức chi tiết như minh họa ở trên):

– d([r2],V1)=1.02 < d([r2],V2)=2.41. Vậy ta gom [r2] vào cụm C1.
– d([r4],V1)=0 < d([r4],V2)=2.39.Vậy ta gom [r4] vào cụm C1.
– d([r6],V1)=2.39 > d([r6],V2)=0. Vậy ta gom [r6] vào cụm C2.
– d([r7],V1)=2.39 > d([r7],V2)=0. Vậy ta gom [r7] vào cụm C2.
– d([r8],V1)=1.18 < d([r8],V2)=2.2. Vậy ta gom [r8] vào cụm C1.
– d([r9],V1)=1.61 < d([r9],V2)=2.35. Vậy ta gom [r9] vào cụm C1
– d([r10],V1)=2.17 < d([r10],V2)=2.36. Vậy ta gom [r10] vào cụm C1
– d([r11],V1)=2.17 < d([r11],V2)=2.36. Vậy ta gom [r11] gom vào cụm C1

*Vậy ta có phân bố cụm lần 1:

U=1r1r2r3r4r5r6r7r8r9r10r11
C111110001111
C200001110000

Bước 3: Cập nhật lại vector trọng tâm
* Gọi V1 là véc tơ trọng tâm mới của C1:
Ta tính được V1(0.47,0.47,0.46,0.46,0,0,0,0.41,0.49,0.36,0.36)

Lý giải trọng tâm mới được tính như sau:

Tương tự cho các thuộc tính và Vector còn lại.
* Gọi V2 là véc tơ trọng tâm mới của C2: Ta tính được V2(0,0,0,0,1,1,1,0,0,0,0)

Bước 4: Kiểm tra điều kiện dừng
Ta so sánh Vector trọng tâm mới được tạo ở bước 3 so với Vector trọng tâm cũ:
Tập Vector Trọng tâm cũ:
V1(0.5,0.5,1,1,0,0,0,0.33,0.33,0,0)

V2(0,0,0,0,1,1,1,0,0,0,0)
Tập Vector Trọng tâm Mới:
V1(0.47,0.47,0.46,0.46,0,0,0,0.41,0.49,0.36,0.36)

V2(0,0,0,0,1,1,1,0,0,0,0)
Ta kiểm tra thấy trọng tâm bị thay đổi nên lặp lại bước 2.

Bước 2: Tính khoảng cách từ các đỉnh tới các Vector trọng tâm:
– d([r1],V1)=0.95 < d([r1],V2)=2.41. Vậy ta gom [r1] vào cụm C1.
– d([r2],V1)=0.95 < d([r2],V2)=2.41. Vậy ta gom [r2] vào cụm C1.
– d([r3],V1)=0.94 < d([r3],V2)=2.39. Vậy ta gom [r3] vào cụm C1.
– d([r4],V1)=0.94 < d([r4],V2)=2.39. Vậy ta gom [r4] vào cụm C1.
– d([r5],V1)=2.13 > d([r5],V2)=0 . Vậy ta gom [r5] vào cụm C2.
– d([r6],V1)=2.13 > d([r6],V2)=0. Vậy ta gom [r6] vào cụm C2.
– d([r7],V1)=2.13 > d([r7],V2)=0. Vậy ta gom [r7] vào cụm C2.
– d([r8],V1)=0.72 < d([r8],V2)=2.2. Vậy ta gom [r8] vào cụm C1.
– d([r9],V1)=0.84 < d([r9],V2)=2.35.  Vậy ta gom [r9] vào cụm C1.
– d([r10],V1)=1.34 < d([r10],V2)=2.36. Vậy ta gom [r10] vào cụm C1.
– d([r11],V1)=1.34 < d([r11],V2)=2.36. Vậy ta gom [r11] vào cụm C1.
*Vậy ta có phân bố cụm lần 2:

U=2r1r2r3r4r5r6r7r8r9r10r11
C111110001111
C200001110000

Bước 3: Cập nhật lại vector trọng tâm

* Gọi V1 là véc tơ trọng tâm mới của C1:

Ta tính được V1(0.47,0.47,0.46,0.46,0,0,0,0.41,0.49,0.36,0.36)

* Gọi V2 là véc tơ trọng tâm mới của C2:

Ta tính được V2(0,0,0,0,1,1,1,0,0,0,0)

Bước 4: Kiểm tra điều kiện dừng
Ta so sánh Vector trọng tâm mới được tạo ở bước 3 so với Vector trọng tâm cũ:

Tập Vector Trọng tâm cũ:

V1(0.47,0.47,0.46,0.46,0,0,0,0.41,0.49,0.36,0.36) ;V2(0,0,0,0,1,1,1,0,0,0,0)

Tập Vector Trọng tâm Mới:

V1(0.47,0.47,0.46,0.46,0,0,0,0.41,0.49,0.36,0.36);V2(0,0,0,0,1,1,1,0,0,0,0)

Vậy ta thấy U2 và U1 Không có sự thay đổi. Giải thuật K-Means kết thúc.

Cuối cùng ta được 2 cụm như sau:

Cụm 1 {r1;r2;r3;r4;r8;r9;r10;r11}

Cụm 2 {r5;r6;r7}

Bài tập tương tự: Cho bảng ma trận dữ liệu dưới đây, hãy giải thích từng bước quá trình K-Means hoạt động, với số cụm là 3, center vector khởi tạo ban đầu là Daisy, Vitor, Real

CustomerAttribute 1Attribute 2
John11
Peter1112
Daisy23
Case12
Ronie26
Vitor98
Rehm01
Tom1110
Bob02
Lie1011
Tide1012
Real74
Jassor56

Bài học sau Tui hướng dẫn cách sử dụng K-Means để gom cụm khách hàng theo thu nhập, độ tuổi và ngân sách chi tiêu. Chúng ta dùng phương pháp Elbow để tìm ra K Cụm tối ưu nhất để gom, trực quan hóa các cụm bằng 2D và 3D. Đồng thời phân loại chi tiết Khách hàng theo từng cụm để dễ dàng đưa ra các chính sách chăm sóc và tiếp thị phù hợp.

Các bạn chú ý theo dõi

Chúc các bạn thành công