Использование kmeans для классификации набора данных iris, пример алгоритма кластеризации kmeans

искусственный интеллект алгоритм

 

В классе учитель попросил сделать домашнее задание, классификацию kmeans, кластеризацию и классификацию радужной оболочки, поэтому я сделал это домашнее задание. Очень просто, я установил его в три категории. Дело в том, что когда я выбираю начальный центр, я пробовал два метода: случайный выбор и выбор большого хода. Эффект случайного выбора начальной точки не так хорош, как увеличение. Этот большой трюк заключается в следующем: сначала случайным образом выберите точку как центр1, затем выберите точку, наиболее удаленную от этого центра1, как центр2, а затем выберите точку, наиболее удаленную от центра1 и центра2, как центр3.

При обновлении центроида в процессе обучения, вместо выбора онлайн-режима для обновления центроида за раз, я выбрал режим mini_batch, сначала отправил образцы mini_batch и назначил их соответствующим центрам, а затем обновить. Столько ерунды, лучше выложить код, код такой:

import numpy as np
import csv
import random

features = np.loadtxt('iris.csv',delimiter=',',usecols=(1,2,3,4))  #read features
z_min, z_max = features.min(axis=0), features.max(axis=0)          #features normalized
features = (features - z_min)/(z_max - z_min)

csv_file = open('iris.csv')   #transform string to num label
csv_reader_lines = csv.reader(csv_file)
classes_list = []
for i in csv_reader_lines:
    classes_list.append(i[-1])
labels = []
for i in classes_list:
    if i=='setosa':
        labels.append(0)
    elif i=='versicolor':
        labels.append(1)
    else:
        labels.append(2)

labels = np.array(labels)
labels = labels.reshape((150,1))   # transformm list to numpy type

data_index = np.arange(features.shape[0])
np.random.shuffle(data_index)

train_input = features[ data_index[0:120] ]
train_label = labels[ data_index[0:120] ]

test_input = features[ data_index[120:150] ]
test_label = labels[ data_index[120:150] ]

train_length = 120
K = 3
center_1_pos = random.randint(0,train_length)
center1 = train_input[ center_1_pos ]
# center1 = train_input[0]
# center2 = train_input[1]
# center3 = train_input[2]
# print(center1)
# print(center2)
# print(center3)

biggest_distance = 0.0
center_2_pos = 0

for i in range(train_length):#选择center2
    dist = np.sum(pow( (center1 - train_input[i]),2 ))
    if dist > biggest_distance:
        biggest_distance = dist
        center_2_pos = i

center2 = train_input[center_2_pos]


biggest_distance = 0.0
center_3_pos = 0

for i in range(train_length):#选择center3
    dist = np.sum(pow( (center1 - train_input[i]), 2 )) + np.sum(pow( (center2 - train_input[i]) , 2))
    if dist > biggest_distance:
        biggest_distance = dist
        center_3_pos = i

center3 = train_input[center_3_pos]
mini_batch = 20

for epoch in range(10):#在整个数据集上训练10次
    for i in range(6):
        belong1 = []
        belong2 = []
        belong3 = []
        for j in range(mini_batch):#mini_batch
            temp_index = mini_batch * i + j
            belong = 1
            dist_1 = np.sum(pow( ( center1 - train_input[mini_batch*i+j] ),2 ))
            temp_dist = dist_1

            dist_2 = np.sum(pow((center2 - train_input[mini_batch * i + j]), 2))
            dist_3 = np.sum(pow((center3 - train_input[mini_batch * i + j]), 2))

            if(dist_2 < temp_dist):
                temp_dist = dist_2
                belong = 2
            if(dist_3 < temp_dist):
                belong = 3

            if belong==1:
                belong1.append( temp_index )
            elif belong == 2:
                belong2.append(temp_index)
            else:
                belong3.append(temp_index)


        for k in belong1:
            center1 = center1 + train_input[k]
        center1 = center1 / (1 + len(belong1))

        for k in belong2:
            center2 = center2 + train_input[k]
        center2 = center2 / (1 + len(belong2))

        for k in belong3:
            center3 = center3 + train_input[k]
        center3 = center3 / (1 + len(belong3))

    b_1=[]
    b_2=[]
    b_3=[]
    for l in range(test_input.shape[0]):#在测试机上进行测试
        belong = 1
        dist_1 = np.sum(pow((center1 - test_input[l]), 2))
        temp_dist = dist_1

        dist_2 = np.sum(pow((center2 - test_input[ l ]), 2))
        dist_3 = np.sum(pow((center3 - test_input[ l ]), 2))

        if (dist_2 < temp_dist):
            temp_dist = dist_2
            belong = 2
        if (dist_3 < temp_dist):
            belong = 3



        if belong == 1:
            b_1.append(test_label[l][0])
        elif belong == 2:
            b_2.append(test_label[l][0])
        else:
            b_3.append(test_label[l][0])
    print()
    print('epoch : {} / 10' .format(epoch+1))
    print('center1: ',b_1)
    print('center2',b_2)
    print('center3: ',b_3)

Ниже приведен результат запуска моей программы:

epoch : 1 / 10
center1:  [2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1]
center2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
center3:  [2, 2, 2, 2, 2]

epoch : 2 / 10
center1:  [2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1]
center2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
center3:  [2, 2, 2, 2, 2]

epoch : 3 / 10
center1:  [2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1]
center2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
center3:  [2, 2, 2, 2, 2]

epoch : 4 / 10
center1:  [2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1]
center2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
center3:  [2, 2, 2, 2, 2]

epoch : 5 / 10
center1:  [2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1]
center2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
center3:  [2, 2, 2, 2, 2]

epoch : 6 / 10
center1:  [2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1]
center2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
center3:  [2, 2, 2, 2, 2]

epoch : 7 / 10
center1:  [2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1]
center2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
center3:  [2, 2, 2, 2, 2]

Результаты довольно хорошие на небольших наборах данных.

Примечание. Когда я читал данные радужной оболочки, я удалял имя атрибута первой строки, иначе было бы проблематично иметь дело с ним.

Эй, делать это небольшое домашнее задание тоже довольно интересно Я узнал о нормализации данных Nummpy, чтении CSV-файлов с помощью numpy и о том, как преобразовать типы символов в CSV-файлах в числовые метки.