zoukankan      html  css  js  c++  java
  • 机器学习 --- k-means

    此文转载自:https://blog.csdn.net/weixin_44196785/article/details/110188840#commentBox

    k-means是属于机器学习里面的非监督学习,通常是大家接触到的第一个聚类算法,其原理非常简单,是一种典型的基于距离的聚类算法。
    聚类算法中,将相似的数据划分为一个集合,一个集合称为一个簇。 k-means(k均值)聚类,之所以称为 k均值,是因为它可以发现k个簇,且每个簇的中心采用簇中所含值的均值计算而成。
    本实训项目将基于Python语言搭建出一个k-means模型,并基于sklean实现对红酒数据进行聚类。

    距离度量

    #encoding=utf8    
    import numpy as np
    
    def distance(x,y,p=2):
        '''
        input:x(ndarray):第一个样本的坐标
              y(ndarray):第二个样本的坐标
              p(int):等于1时为曼哈顿距离,等于2时为欧氏距离
        output:distance(float):x到y的距离      
        ''' 
        #********* Begin *********#
        return np.linalg.norm(x-y, p)
        #********* End *********#
    

    什么是质心

    # encoding=utf8
    import numpy as np
    
    
    # 计算样本间距离
    def distance(x, y, p=2):
        '''
        input:x(ndarray):第一个样本的坐标
              y(ndarray):第二个样本的坐标
              p(int):等于1时为曼哈顿距离,等于2时为欧氏距离
        output:distance(float):x到y的距离
        '''
        # ********* Begin *********#
        return (np.sum(np.subtract(x, y) ** p)) ** (1 / p)
        # ********* End *********#
    
    
    # 计算质心
    def cal_Cmass(data):
        '''
        input:data(ndarray):数据样本
        output:mass(ndarray):数据样本质心
        '''
        # ********* Begin *********#
        return [np.mean(col) for col in np.transpose(data)]
        # ********* End *********#
    
    
    # 计算每个样本到质心的距离,并按照从小到大的顺序排列
    def sorted_list(data, Cmass):
        '''
        input:data(ndarray):数据样本
              Cmass(ndarray):数据样本质心
        output:dis_list(list):排好序的样本到质心距离
        '''
        # ********* Begin *********#
        return sorted([distance(row, Cmass) for row in data])
        # ********* End *********#
    
    

    加粗样式

    # encoding=utf8
    import numpy as np
    
    
    # 计算一个样本与数据集中所有样本的欧氏距离的平方
    def euclidean_distance(one_sample, X):
        one_sample = one_sample.reshape(1, -1)
        distances = np.power(np.tile(one_sample, (X.shape[0], 1)) - X, 2).sum(axis=1)
        return distances
    
    
    def cal_dis(old_centroids, centroids):
        dis = 0
        for i in range(old_centroids.shape[0]):
            dis += np.linalg.norm(old_centroids[i] - centroids[i], 2)
        return dis
    
    
    class Kmeans():
        """Kmeans聚类算法.
        Parameters:
        -----------
        k: int
            聚类的数目.
        max_iterations: int
            最大迭代次数.
        varepsilon: float
            判断是否收敛, 如果上一次的所有k个聚类中心与本次的所有k个聚类中心的差都小于varepsilon,
            则说明算法已经收敛
        """
    
        def __init__(self, k=2, max_iterations=500, varepsilon=0.0001):
            self.k = k
            self.max_iterations = max_iterations
            self.varepsilon = varepsilon
            np.random.seed(1)
    
        # ********* Begin *********#
        # 从所有样本中随机选取self.k样本作为初始的聚类中心
        def init_random_centroids(self, X):
            m, n = X.shape
            center = np.zeros((self.k, n))
            for i in range(self.k):
                index = int(np.random.uniform(0, m))
                center[i] = X[index]
            return center
    
        # 返回距离该样本最近的一个中心索引[0, self.k)
        def _closest_centroid(self, sample, centroids):
            distances = euclidean_distance(sample, centroids)
            return np.argsort(distances)[0]
    
        # 将所有样本进行归类,归类规则就是将该样本归类到与其最近的中心
        def create_clusters(self, centroids, X):
            m, n = X.shape
            clusters = np.mat(np.zeros((m, 1)))
            for i in range(m):
                index = self._closest_centroid(X[i], centroids)
                clusters[i] = index
            return clusters
    
        # 对中心进行更新
        def update_centroids(self, clusters, X):
            centroids = np.zeros([self.k, X.shape[1]])
            for i in range(self.k):
                pointsInCluster = []
                for j in range(clusters.shape[0]):
                    if clusters[j] == i:
                        pointsInCluster.append(X[j])
                centroids[i] = np.mean(pointsInCluster, axis=0)  # 对矩阵的行求均值
            return centroids
    
        # 将所有样本进行归类,其所在的类别的索引就是其类别标签
        def get_cluster_labels(self, clusters, X):
            return
    
        # 对整个数据集X进行Kmeans聚类,返回其聚类的标签
        def predict(self, X):
            # 从所有样本中随机选取self.k样本作为初始的聚类中心
            centroids = self.init_random_centroids(X)
            clusters = []
            iter = 0
            # 迭代,直到算法收敛(上一次的聚类中心和这一次的聚类中心几乎重合)或者达到最大迭代次数
            while iter < self.max_iterations:
                iter += 1
    
                # 将所有进行归类,归类规则就是将该样本归类到与其最近的中心
                clusters = self.create_clusters(centroids, X)
    
                # 计算新的聚类中心
                old_centroids = centroids[:]
                centroids = self.update_centroids(clusters, X)
                if cal_dis(old_centroids, centroids) < self.varepsilon:
                    break
    
                # 如果聚类中心几乎没有变化,说明算法已经收敛,退出迭代
            return np.array(clusters).reshape([X.shape[0], ])
    
        # ********* End *********#
    
    

    sklearn中的k-means

    #encoding=utf8
    from sklearn.cluster import KMeans
    
    def kmeans_cluster(data):
        '''
        input:data(ndarray):样本数据
        output:result(ndarray):聚类结果
        '''
        #********* Begin *********#
        km = KMeans(n_clusters=3,random_state=888)
        result = km.fit_predict(data)
    
        #********* End *********#
        return result
    
    
    
    
    
    
    

    大家做这个不容易,记得点赞哦!!!!!!!!感谢大家的支持!!!!!!

       

    更多内容详见微信公众号:Python测试和开发

    Python测试和开发

  • 相关阅读:
    leetcode108 Convert Sorted Array to Binary Search Tree
    leetcode98 Validate Binary Search Tree
    leetcode103 Binary Tree Zigzag Level Order Traversal
    leetcode116 Populating Next Right Pointers in Each Node
    Python全栈之路Day15
    Python全栈之路Day11
    集群监控
    Python全栈之路Day10
    自动部署反向代理、web、nfs
    5.Scss的插值
  • 原文地址:https://www.cnblogs.com/phyger/p/14054573.html
Copyright © 2011-2022 走看看