"Это второй день моего участия в ноябрьском испытании обновлений, ознакомьтесь с подробностями события:Вызов последнего обновления 2021 г."
Алгоритм кластеризации KMeans
Кластеризация — это тип обучения без учителя, при котором похожие объекты группируются в один и тот же кластер. Методы кластеризации можно применять практически ко всем объектам, чем более похожи объекты внутри кластера. Чем лучше эффект кластеризации. Кластеризация KMeans также известна как кластеризация k-средних. Он называется K-средним, потому что он находит k различных кластеров, и центр каждого кластера вычисляется с использованием среднего значения, содержащегося в кластере. (Для получения более подробной информации см. другие статьи. В этой статье используется код только для реализации примера, который подходит для пользователей, понимающих принцип просмотра)
настоящий бой
Имея некоторые 2D-данные, классифицируйте данные и визуализируйте их с помощью matplotlib. Данные, которые я использую, следующие:
1.78 4.58
-3.25 3.12
4.34 -1.15
-5.77 -3.36
0.97 2.32
-3.67 1.53
0.45 -3.10
-3.49 -1.72
2.67 1.79
-3.16 3.59
Хранится в файле test.txt. Библиотеку sklearn для решения не используем, я буду использовать код из книги "Машинное обучение в действии"
Шаг 1. Извлеките данные
from numpy import *
import matplotlib.pyplot as plt
import numpy as np
# 加载数据
def loadDataSet(fileName):
data = np.loadtxt(fileName, delimiter='\t')
return data
Шаг 2: Функция расстояния и случайный выбор центроида
# 欧氏距离计算
def distEclud(x, y):
return np.sqrt(np.sum((x - y) ** 2)) # 计算欧氏距离
# 为给定数据集构建一个包含K个随机质心的集合
def randCent(dataSet, k):
m, n = dataSet.shape
centroids = np.zeros((k, n))
for i in range(k):
index = int(np.random.uniform(0, m)) #
centroids[i, :] = dataSet[index, :]
return centroids
Шаг 3: Реализуйте кластеризацию K-средних
# k均值聚类
def KMeans(dataSet, k):
m = np.shape(dataSet)[0] # 行的数目
# 第一列存样本属于哪一簇
# 第二列存样本的到簇的中心点的误差
clusterAssment = np.mat(np.zeros((m, 2)))
clusterChange = True
# 第1步 初始化centroids
centroids = randCent(dataSet, k)
while clusterChange:
clusterChange = False
# 遍历所有的样本(行数)
for i in range(m):
minDist = 100000.0
minIndex = -1
# 遍历所有的质心
# 第2步 找出最近的质心
for j in range(k):
# 计算该样本到质心的欧式距离
distance = distEclud(centroids[j, :], dataSet[i, :])
if distance < minDist:
minDist = distance
minIndex = j
# 第 3 步:更新每一行样本所属的簇
if clusterAssment[i, 0] != minIndex:
clusterChange = True
clusterAssment[i, :] = minIndex, minDist ** 2
# 第 4 步:更新质心
for j in range(k):
pointsInCluster = dataSet[np.nonzero(clusterAssment[:, 0].A == j)[0]] # 获取簇类所有的点
centroids[j, :] = np.mean(pointsInCluster, axis=0) # 对矩阵的行求均值
return centroids, clusterAssment
Шаг 4: Используйте matplotlib для рисования.
def showCluster(dataSet, k, centroids, clusterAssment):
m, n = dataSet.shape
if n != 2:
print("数据不是二维的")
return 1
mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
if k > len(mark):
print("k值太大了")
return 1
# 绘制所有的样本
for i in range(m):
markIndex = int(clusterAssment[i, 0])
plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])
mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
# 绘制质心
for i in range(k):
plt.plot(centroids[i, 0], centroids[i, 1], mark[i])
plt.show()
dataSet = loadDataSet("test.txt")
k = 4
centroids, clusterAssment = KMeans(dataSet, k)
showCluster(dataSet, k, centroids, clusterAssment)
результат
Я выбрал четыре кластера, но расчет может быть неточным, и в итоге я могу нарисовать три кластера. Количество кластеров k в кластеризации k-средних является определяемым пользователем параметром, но выбор пользователем значения k часто неверен. Если алгоритм k-средних сходится, но эффект кластеризации плохой, причина в том, что алгоритм k-средних сходится к локальному минимуму, а не к глобальному минимуму. Индексом для измерения эффекта кластеризации является SSE (сумма квадратов ошибок).Чем меньше значение SSE, тем ближе точки данных к их центроидам, тем лучше эффект кластеризации. Как уменьшить значение SSE, не уменьшая количество кластеров, требует использования алгоритма K-средних деления пополам. Заинтересованные пользователи могут узнать об этом самостоятельно.