Машинное обучение — кластеризация KMeans (практика машинного обучения)

искусственный интеллект

"Это второй день моего участия в ноябрьском испытании обновлений, ознакомьтесь с подробностями события:Вызов последнего обновления 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)

результат

QQ浏览器截图20211110222217.png

Я выбрал четыре кластера, но расчет может быть неточным, и в итоге я могу нарисовать три кластера. Количество кластеров k в кластеризации k-средних является определяемым пользователем параметром, но выбор пользователем значения k часто неверен. Если алгоритм k-средних сходится, но эффект кластеризации плохой, причина в том, что алгоритм k-средних сходится к локальному минимуму, а не к глобальному минимуму. Индексом для измерения эффекта кластеризации является SSE (сумма квадратов ошибок).Чем меньше значение SSE, тем ближе точки данных к их центроидам, тем лучше эффект кластеризации. Как уменьшить значение SSE, не уменьшая количество кластеров, требует использования алгоритма K-средних деления пополам. Заинтересованные пользователи могут узнать об этом самостоятельно.