有兴趣请关注我的博客https://blog.csdn.net/qq_40731414
朱朱朱朱红喜的邮箱[email protected]
请使用C均值聚类方法对数据集进行聚类,给每个样本一个类别标签,并画出聚类结果(参考图trainning sample的画法),并与其真实标签(在truelabel.mat中)进行对比,计算聚类的准确率;
采用距离作为相似性指标,从而发现给定数据集中的K个类,且每个类的中心是根据类中所有值的均值得到,每个类用聚类中心来描述。对于给定的一个包含n个d维数据点的数据集X以及要分得的类别K,选取欧式距离作为相似度指标,聚类目标是使得各类的聚类平方和最小,聚类中心为对应类别中各数据点的平均值,同时为了使得算法收敛,在迭代过程中,应使最终的聚类中心尽可能的不变 。
在样本集合中选择C个点作为初始类中心;
在剩下的样本点中选择一个,计算其到各个中心点的距离,选取距离最短者将其归为那个类别;
选择下一个样本,重复2直到计算完所有样本,若集合不发生变化或达到迭代上限则转5否则转4;
根据当前的类划分情况重新计算中心点,重复步骤2;
结束算法。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/6/16 13:58
# @Author : 朱红喜
# @File : C-means.py
# @Software: PyCharm
import numpy as np
from ClassifyHandle import ClassifyHandle
from FileUtil import FileUtil
from PlotUtil import PlotUtils
class_number = 3 # 按照老师的给的数据图 把150个数据分为三类
datas = FileUtil.open_matfile("data4train.mat") # 数据集
centers = [] # 聚类中心
# 选取三个数据作为三个初始聚类中心
for i in range(class_number):
centers.append(datas[i])
# 将数据集分类到三个类中
result = ClassifyHandle.classify(centers, datas)
print("######################第一次分类(初始)结果#########################")
print(result)
# 画出散点图
PlotUtils.plot(result)
end_flag = 1 # 循环标志
# 循环计算各类中心并重新分类直到无法再分类,结束循环
while end_flag:
new_centers = [] # 新的分类中心
# 通过分类结果计算获得新的分类中心
for i in range(result.__len__()):
new_centers.append(ClassifyHandle.get_new_center(result[i]))
PlotUtils.single_plot(new_centers)
# 如果新的分类中心与原来的分类中心相同说明分类结束,循环结束
# if new_centers == centers:
if np.array_equal(new_centers, centers):
end_flag = 0
else:
centers = new_centers.copy()
result = ClassifyHandle.classify(centers, datas)
# 画出散点图
# PlotUtils.plot(result)
# 将结果输出
print("######################最终的分类结果#########################")
print(result)
# 将数据输出到mat文件
FileUtil.save_matflie("cmeans_result.mat", result)
# 画出散点图
PlotUtils.plot(result)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/6/16 15:07
# @Author : 朱红喜
# @File : ClassifyHandle.py
# @Software: PyCharm
from MathUtil import MathUtil
class ClassifyHandle:
# 将每个数据分类
@staticmethod
def classify(centers, datas):
result = []
for i in range(centers.__len__()):
result.append([])
result[i].append(centers[i])
for i in range(datas.__len__()):
min_distance = float('inf') # 初始化最小距离
class_index = 0 # 每个类别下标
for j in range(centers.__len__()):
# 依次计算每个数据到每一个类中心的欧式距离
# 根据欧式距离分类
distance = MathUtil.compute_distance(centers[j], datas[i])
if min_distance > distance:
min_distance = distance
class_index = j
# 将属于这个类别的数据加入这个类中
result[class_index].append(datas[i])
return result
# 计算每一个类的中心
@staticmethod
def get_new_center(datas):
# 初始类中心,默认就是第一个位置的数据点
# 即计算聚类中的所有数据点的各自维度的算术平均数
data = datas[0].copy()
# 遍历本类的所有数据
for i in range(datas.__len__()):
# 每个数据是二维的,遍历每个维度,将各自维度求和
for j in range(data.__len__()):
data[j] += datas[i][j]
# 求每个维度和的算术平均
for k in range(data.__len__()):
data[k] /= datas.__len__()
return data
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/6/16 14:20
# @Author : 朱红喜
# @File : MathUtil.py
# @Software: PyCharm
import math
class MathUtil:
# 计算二维欧式距离
@staticmethod
def compute_distance(data, center):
distance = 0
# 每个数据包含二维的数据,计算二维的欧式距需要循环两次
# math.sqrt((x_1-y_1)**2+(x_2-y_2)**2)
for i in range(data.__len__()):
# distance += (data[i] - center[i]) ** 2
distance += math.pow((data[i] - center[i]), 2)
distance = math.sqrt(distance)
return distance
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/6/16 14:20
# @Author : 朱红喜
# @File : FileUtil.py
# @Software: PyCharm
import scipy.io as sio
import numpy as np
import matplotlib.pyplot as plt
# 文件读写操作类
class FileUtil:
# 读取mat文件,获得数据
@staticmethod
def open_matfile(filename):
# "data4train.mat"
# 读出来的字典类型
mat_data = sio.loadmat(filename)
# 测试下mat文件到底输出了什么
# 键值对形式的同时 还会有附加信息
# for key, value in mat_data.items():
# print(key, ':', value)
# 取出有用的矩阵数据集
datas = mat_data['data4train']
# print(datas)
# 转置,每一行为一个记录,每一列为一个字段
datas = datas.T
print(datas)
return datas
# 将结果保存到mat文件中
@staticmethod
def save_matflie(filename, result):
sio.savemat(filename, {'result': result}) # "cmeans_result.mat"
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/6/28 12:13
# @Author : 朱红喜
# @File : PlotUtil.py
# @Software: PyCharm
from ColorSelect import ColorSelect
import matplotlib.pyplot as plt
class PlotUtils:
# 画出结果散点图
@staticmethod
def plot(result):
# 画出散点图
plt.title("C-means algorithm")
plt.xlim(-2, 15)
plt.ylim(-2, 15)
plt.xlabel("x")
plt.ylabel("y")
for i in range(result.__len__()):
for j in range(result[i].__len__()):
print(i, end='')
plt.plot(result[i][j][0], result[i][j][1], ColorSelect.color_select(i))
plt.show()
@staticmethod
def single_plot(centers):
# 画出类中心点
plt.title("C-means algorithm")
plt.xlim(-2, 15)
plt.ylim(-2, 15)
plt.xlabel("x")
plt.ylabel("y")
for i in range(centers.__len__()):
plt.plot(centers[i][0], centers[i][1], ColorSelect.color_select(i))
plt.show()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/6/17 17:39
# @Author : 朱红喜
# @File : ColorSelect.py
# @Software: PyCharm
class ColorSelect:
# 颜色筛选器
@staticmethod
def color_select(index):
color_dict = {0: 'go', 1: 'ro', 2: 'bo'}
return color_dict[index]
作者:朱红喜
转载请注明出处
参考博客:https://blog.csdn.net/aaalswaaa1/article/details/81675679
https://blog.csdn.net/weixin_40938820/article/details/82559991
https://blog.csdn.net/zb1165048017/article/details/48579743
https://blog.csdn.net/u011591807/article/details/84349181
https://www.cnblogs.com/kylinlin/p/5299078.html