zoukankan      html  css  js  c++  java
  • k-meanas原理自实现

    import numpy as np
    import matplotlib.pyplot as plt
    
    def build_data():
        """
        准备数据
        :return:准备好的数据
        """
        data_list = []
        # 加载数据
        with open("./test.txt") as f:
            # 将所有的元素读成一个列表
            lines = f.readlines()
            # 循环对每一行元素进行单独处理
            for line in lines:
                # print(line)
                # 去除line 前后的空白字符
                line_obj = line.strip().split('	')
                # print(line_obj)
                # print(type(line_obj))
                # print("*"*20)
                # 把 line_obj 里面的每一个元素 转化为float,追加到一列表中
                data_list.append([float(line_obj[0]), float(line_obj[1])])
    
        # 列表嵌套列表的数据 ,每一个列表元素是原来的每一行元素
        # print(data_list)
        # 将列表嵌套列表转化为二维数组
        data_array = np.array(data_list)
        # print(data_array)
        # 将二维数组 转化为矩阵
        data = np.mat(data_array)
        # print(data)
        # print(type(data))
        return data
    
    
    def center_init(data, k):
        """
        初始化聚类中心
        :param data: 所有的样本数据
        :param k: 聚类的类别数目
        :return: 聚类中心
        """
        # 随机在 data中挑选4行 作为初始化的聚类中心
        # 获取data 的列数
        columns_num = data.shape[1]
        # 获取data 的行数
        index_num = data.shape[0]
        # 先初始化一个全为0 的中心,然后,后续替换里面的值
        center = np.zeros(shape=(k, columns_num))
        # 每次初始化一个聚类中心,需要循环初始化k次
        for i in range(k):
            #  随机在80行里面选一个下标
            # np.random.uniform() --->默认生成【0,1) 小数,可以更改最小值与最大值
            r = int(np.random.uniform(0, index_num))
    
            center[i, :] = data[r, :]
    
        return center
    
    
    def distance(v1, v2):
        """
        计算点1 跟点2 的距离
        :param v1: 点1
        :param v2: 点2
        :return: 距离
        """
    
        dist = np.sqrt(np.sum(np.power((v1 - v2), 2)))
    
        return dist
    
    
    def k_means_owns(data, k):
        """
        自实现聚类算法
        :param data: 所有的样本数据
        :param k: 聚类的类别数目
        :return: 聚类中心 、每一个样本属于哪一类别
        """
    
    
        # 获取data 的 行数
        index_num = data.shape[0]
        columns_num = data.shape[1]
        # 1、初始化聚类中心
        center = center_init(data, k)
        # print(center)
    
        #  需要将这个样本属于哪一类,而且距离也要保存起来吧
        new_data = np.zeros(shape=(index_num,columns_num))
        # 2、计算距离
        # 每一个样本 都与每一个聚类中心进行计算距离
        # 设置开关
        flag = True
        while flag:
            flag = False # 关闭开关
            for i in range(index_num):
                min_dist = 10000000000
                min_index = -1
                # i 代表每一行的样本的下标
                for j in range(k):
                    # 每一个样本需要 与每一个聚类中心进行计算距离
                    # 样本点data[i,:]   聚类中心center[j,:]
                    dist = distance(data[i,:],center[j,:])
    
                    if dist < min_dist :
                        min_dist = dist
                        min_index = j
                if new_data[i,1] != min_index:
                    flag = True # 打开
                    new_data[i,:] = min_dist,min_index
            # 调整聚类中心
            for p in range(k):
                # p  0 1 2 3
                # 找出属于同一类别
                p_clustor = data[new_data[:,1] == p,:]
    
                # 计算这一类别的中心
                #  先找出 这一类的簇第0 列的均值,与第1列的均值分别作为center 的行、列
                center[p,:] = p_clustor[:,0].mean(),p_clustor[:,1].mean()
    
        return  new_data,center
    
    
    def show_res(data,new_data,center):
        """
        结果展示
        :param data: 原始数据
        :param new_data: 主要包含了聚类距离与最终类别的数据
        :param center: 最终的聚类中心
        :return: None
        """
        # 1、创建画布
        plt.figure()
        # 2、绘图
        # 获取原始数据的行数
        index_num = data.shape[0]
    
        #
        colors = ['r','g','pink','y']
        # 绘制散点图
        # 一个点的绘制,需要给该点进行添加颜色
        for i in range(index_num):
            plt.scatter(data[i,0],data[i,1],c=colors[int(new_data[i,1])])
    
        # 绘制聚类中心
        #
        plt.plot(center[:,0],center[:,1],'bx',markersize=12)
        # print(center[:,0])
        # print(center[:,1])
        # 3、展示
        plt.show()
    
    
    
    def main():
        """
        主函数
        :return:
        """
        # 1、构建数据
        data = build_data()
    
        # 2、进行自实现k-means
        # 确定聚类的类别数目
        k = 4
        new_data, center = k_means_owns(data, k)
    
        print(new_data)
        print("*" * 80)
        print(center)
    
        # 3、结果展示
        # 进行绘制结果图形展示
        show_res(data,new_data,center)
    
    
    if __name__ == '__main__':
        main()
    

      

  • 相关阅读:
    简单工厂、工厂方法、抽象工厂
    c#之反射总结
    设计模式Builder(建造者)模式
    c#之委托和事件的区别
    c#之委托总结
    javascript之流程控制 和函数的容易忽略点
    javascript之六种数据类型以及特殊注意点
    Sublime Text 快捷键
    链接中获取文件名
    js 获取当天23点59分59秒 时间戳 (最简单的方法)
  • 原文地址:https://www.cnblogs.com/wutanghua/p/11537135.html
Copyright © 2011-2022 走看看