机器学习-KMeans聚类算法

K-Means和KNN区别:

KNN是监督学习的分类算法,有对应的类别输出。
KNN基本不需要训练,对测试集里面的点,只需要找到在训练集中最近的k个点,用这最近的k个点的类别来决定测试点的类别。

K-Means是无监督学习的聚类算法,没有样本输出;
K-Means则有明显的训练过程,找到k个类别的最佳质心,从而决定样本的簇类别。

两个算法都包含一个过程,即找出和某一个点最近的点。两者都利用了最近邻(nearest neighbors)的思想。

K-Means的优点与缺点

优点:
1,简单、易于理解和实现;
2,收敛快,一般仅需5-10次迭代
3,高效
缺点:
1,对K值得选取把握不同对结果有很大的不同
2,对于初始点的选取敏感,不同的随机初始点得到的聚类结果可能完全不同
3,对于不是凸的数据集比较难收敛
4,对噪点过于敏感,因为算法是根据基于均值的
5,结果不一定是全局最优,只能保证局部最优
6,对球形簇的分组效果较好,对非球型簇分组效果不好

Python代码

# -*- encoding: utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
dataset = pd.read_csv('watermelon.csv', delimiter=",")
data = dataset.values
print(dataset)
import random
#计算范数的平方
def distance(x1, x2):
    return sum((x1-x2)**2)
def Kmeans(D,K,maxIter):
    m, n = np.shape(D)
    if K >= m:
        return D
    initSet = set()
    curK = K
    while(curK>0):  # 随机选取k个样本
        randomInt = random.randint(0, m-1)
        if randomInt not in initSet:
            curK -= 1
            initSet.add(randomInt)
    U = D[list(initSet), :]  # 均值向量
    C = np.zeros(m)
    curIter = maxIter
    while curIter > 0:
        curIter -= 1
        for i in range(m):
            p = 0
            minDistance = distance(D[i], U[0])
            for j in range(1, K):
                if distance(D[i], U[j]) < minDistance:
                    p = j
                    minDistance = distance(D[i], U[j])
            C[i] = p
        newU = np.zeros((K, n))
        cnt = np.zeros(K)
        for i in range(m):
            newU[int(C[i])] += D[i]
            cnt[int(C[i])] += 1
        changed = 0
        for i in range(K):
            newU[i] /= cnt[i]
            for j in range(n):
                if U[i, j] != newU[i, j]:
                    changed = 1
                    U[i, j] = newU[i, j]
        if changed == 0:
            return U, C, maxIter-curIter
    return U, C, maxIter-curIter

U, C, iter = Kmeans(data,3,10)
# print(U)
# print(C)
# print(iter)

f1 = plt.figure(1)
plt.title('watermelon')
plt.xlabel('density')
plt.ylabel('ratio')
plt.scatter(data[:, 0], data[:, 1], marker='o', color='g', s=50)
plt.scatter(U[:, 0], U[:, 1], marker='o', color='r', s=100)
# plt.xlim(0,1)
# plt.ylim(0,1)
m, n = np.shape(data)
for i in range(m):
    plt.plot([data[i, 0], U[int(C[i]), 0]], [data[i, 1], U[int(C[i]), 1]], "c--", linewidth=0.3)
plt.show()
发布了118 篇原创文章 · 获赞 25 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/lhxsir/article/details/103738149