红酒数据聚类
Wine 数据集包含来自 3 种不同起源的葡萄酒的共 178 条记录(共 178 种葡萄酒),13 个属 性是葡萄酒的 13 种化学成分,通过化学分析可以推断葡萄酒的起源。
要求实现一种聚类方法,完成 178 条记录的聚类,把整个数据集中的数据分成 3 类(对应 3 种不同的起源的葡萄酒)
程序代码
'''
-*- coding:utf-8 -*-
时间:2019-6-6 星期四
作者:zzx
功能:红酒数据集聚类
'''
import random
import numpy as np
from sklearn import preprocessing
def selectInitMeanVec(Data,k):#选择初始均值向量
indexInitMeanVec = random.sample(range(m), k)
initMeanVec = Data[indexInitMeanVec, :]
return initMeanVec
def calcDistance(Data, k, MeanVec):#计算距离并归入簇中
Dist = np.zeros((k, 1))
Label = np.zeros((m, 1))
for i in range(m):
for j in range(k):
a = Data[i, :]-MeanVec[j, :]
Dist[j] = np.sqrt(sum(a**2))
Label[i] = np.argmin(Dist)
return Label
def updateMeanVec(Data, Label, k, oldMeanVec):#更新均值向量
newMeanVec = np.zeros((k, n))
numSamples = np.zeros((k, 1), dtype=int)
for i in range(k):
num = 0
D = np.zeros((k, 0))
for j in range(m):
if Label[j] == i:
D = np.append(D, Data[j, :])
num += 1
numSamples[i] = num
D = np.reshape(D, (-1, n))
newMeanVec[i, :] = np.mean(D, axis=0)
#如果本次更新后某一簇中无样本,取上一次均值向量为本次均值向量
if num == 0:
newMeanVec[i, :] = oldMeanVec[i, :]
return newMeanVec, numSamples
if __name__ == '__main__':
data = np.loadtxt("wine.csv", delimiter=',')[:, 0:14]
Data = preprocessing.scale(data)
k = 3
global m, n
m, n = Data.shape
initMeanVec = selectInitMeanVec(Data, k)
oldMeanVec = initMeanVec.copy()
Label = calcDistance(Data, k, initMeanVec)
for i in range(200):
newMeanVec, numSamples = updateMeanVec(Data, Label, k, oldMeanVec)
oldMeanVec = newMeanVec.copy()
Label = calcDistance(Data, k, newMeanVec)
# print(Label, Data)
print('---第%d轮迭代完成'%(i+1))
print(numSamples)
l = 1
for L in Label:
if 0 in Label[l]:
print("第一个簇:%d" %l)
elif 1 in Label[l]:
print("第二个簇:%d" %l)
elif 2 in Label[l]:
print("第三个簇:%d" %l)
else:
pass
l += 1