python實現K-means算法(步驟詳細

文章目錄
K-means 聚類算法
代碼實現
實驗目的
實驗步驟算法

  1. 數據準備
  2. KMeans算法實現
  3. 設置參數,調用函數,獲得結果
    實驗結果
    K-means 聚類算法
    特色
    對初始化敏感。初始點選擇的不一樣,可能會產生不一樣的聚類結果
    最終會收斂。無論初始點如何選擇,最終都會收斂
    算法思想
    選擇K個點做爲初始質心
    repeat
    將每一個點指派到最近的質心,造成K個簇
    從新計算每一個簇的質心
    until 簇不發生變化或達到最大迭代次數
    1
    2
    3
    4
    5
    代碼實現
    實驗目的
    根據下列成績單,將5名同窗成績歸爲A類、B類、C類。

限制:使用Kmeans算法實現,但不直接調用sklearn第三方庫的KMeans函數。app

學生姓名 小測1 小測2 小測3 期末成績 項目答辯 成績
張三 12 15 13 28 24 ?
李四 7 11 10 19 21 ?
王五 12 14 11 27 23 ?
趙六 6 7 4 13 20 ?
劉七 13 14 13 27 25 ?
實驗步驟ide

  1. 數據準備
    將數據儲存爲csv文件,格式以下

學生姓名,小測1,小測2,小測3,期末成績,項目答辯
張三,12,15,13,28,24
李四,7,11,10,19,21
王五,12,14,11,27,23
趙六,6,7,4,13,20
劉七,13,14,13,27,25
1
2
3
4
5
6
在從csv文件中讀取數據,並選取可用的數據(排除姓名列)函數

data = pd.read_csv('grade.csv')
new_data = data.iloc[:, 1:].values
1
2code

  1. KMeans算法實現
    KMeans算法涉及兩點之間距離的計算,咱們提早寫好一個函數:輸入兩個點的座標,返回兩點之間的歐氏距離

def eucliDist(A, B):
return math.sqrt(sum([(a - b) ** 2 for (a, b) in zip(A, B)]))
1
2
函數k_means(c,data,max,label)實現KMeans算法:ip

a. 輸入:質心列表c,待聚類數據data,最大迭代次數max,標籤列表labelit

b. 計算data中的每一個點分別到3個質心的歐式距離,獲得一個矩陣metrixclass

metrix = [[eucliDist(a, b) for a in data] for b in c]
1
c. 比較矩陣metrix同一列的數值大小,將對應的學生劃歸距離較短的質心所屬的類,將標籤存儲爲列表.cli

classifier = []
for (d, e, f) in zip(metrix[0], metrix[1], metrix[2]):
m = min(d, e, f)
if d == m:
classifier.append(label[0])
elif e == m:
classifier.append(label[1])
else:
classifier.append(label[2])
1
2
3
4
5
6
7
8
9
d. 從新計算質心的座標,新質心的座標=被劃歸同一類點的座標的平均值csv

n1, n2 = 0, 0
c1 = [0, 0, 0, 0, 0]
c2 = c1
c3 = c1
for i in range(0, num):

if classifier[i] == label[0]:
        c1 = [a + b for (a, b) in zip(c1, data[i])]
        n1 = n1 + 1
    elif classifier[i] == label[1]:
        c2 = [a + b for (a, b) in zip(c2, data[i])]
        n2 = n2 + 1
    else:
        c3 = [a + b for (a, b) in zip(c3, data[i])]

c1 = [a / n1 for a in c1]
c2 = [a / n2 for a in c2]
c3 = [a / (num - n1 - n2) for a in c3]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
e. 重複b~d,直到質心座標再也不變化或達到最大迭代次數

f. 返回標籤列表

完整函數以下
def k_means(c, data, max,label):

a. 輸入質心列表c,待聚類數據data,最大迭代次數max

max = max - 1
num = len(data)
# b. 計算data中的每一個點分到k個質心的距離,獲得一個矩陣,如
metrix = [[eucliDist(a, b) for a in data] for b in c]
print(metrix)
# c. 比較矩陣同一列的數值大小,將對應的學生劃歸距離較短的質心所屬的類,將標籤存儲爲列表
classifier = []
for (d, e, f) in zip(metrix[0], metrix[1], metrix[2]):
    m = min(d, e, f)
    if d == m:
        classifier.append(label[0])
    elif e == m:
        classifier.append(label[1])
    else:
        classifier.append(label[2])

print(classifier)

# d. 從新計算質心的座標,新質心的座標=被劃歸同一類點的座標的平均值
n1, n2 = 0, 0
c1 = [0, 0, 0, 0, 0]
c2 = c1
c3 = c1
for i in range(0, num):

    if classifier[i] == label[0]:
        c1 = [a + b for (a, b) in zip(c1, data[i])]
        n1 = n1 + 1
    elif classifier[i] == label[1]:
        c2 = [a + b for (a, b) in zip(c2, data[i])]
        n2 = n2 + 1
    else:
        c3 = [a + b for (a, b) in zip(c3, data[i])]

c1 = [a / n1 for a in c1]
c2 = [a / n2 for a in c2]
c3 = [a / (num - n1 - n2) for a in c3]

print(max)
print([c1,c2,c3])
# e. 重複b~d,直到質心座標再也不變化,或達到最大迭代次數
if c != [c1, c2, c3] and max > 0:

    c = [c1, c2, c3]
    print(c)
    k_means(c, data, max, label)
return classifier

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

  1. 設置參數,調用函數,獲得結果
    設置初始質心、標籤列表、最大迭代次數

選擇K個點做爲初始質心

c = [[12, 15, 13, 28, 24], [ 7, 11, 10, 19, 21],[12, 14, 11, 27, 23]]
label = ['A', 'B', 'C']
max = 20
1
2
3
4
調用函數,整理結果

grade = k_means(c, new_data, max, label)grade = pd.Series(grade, index=data['學生姓名'])print(grade)123實驗結果初始質心爲[12, 15, 13, 28, 24], [ 7, 11, 10, 19, 21],[12, 14, 11, 27, 23]時,迭代2次即收斂,結果以下學生姓名 小測1 小測2 小測3 期末成績 項目答辯 成績張三 12 15 13 28 24 A李四 7 11 10 19 21 B王五 12 14 11 27 23 C趙六 6 7 4 13 20 B劉七 13 14 13 27 25 A————————————————

相關文章
相關標籤/搜索