常见的数据分析模型有回归,分类,聚类
此次介绍的是无监督学习方面的聚类分析代码
所有代码可直接运行
1 读取数据方法
其实pandas有更方便的pd.readcsv方法实现快速读取csv数据集,还有其它方法读取各种数据集
import numpy as np
def loadDataSet(filename):
"""
读取数据集
Args:
filename:文件名
Return:
dataMat:数据样本矩阵
"""
dataMat=[]
with open(filename,'rb') as f:
for line in f:
line=line.decode('utf-8').strip()
eles=list(map(float,line.split(',')))
dataMat.append(eles)
return dataMat
2 计算样本聚类方法
"""计算俩向量的欧式距离
Args:
vecA:向量A
vecB:向量B
Returns:
欧式距离
def distEclud(vecA,vecB):
"""计算俩向量的欧式距离
Args:
vecA:向量A
vecB:向量B
Returns:
欧式距离
"""
return np.sqrt(np.sum(np.power((vecA-vecB),2)))
3生成聚类中心矩阵
def randCent(dataSet,k):
"""
随机生成k个聚类中心
Args:
dataSet:数据集
k:簇类目
Returns:
centroids:聚类中心矩阵
"""
m,_=dataSet.shape
centroids=dataSet.take(np.random.choice(m,k),axis=0)
return centroids
4 k-mians聚类
def kMeans(dataSet,k,maxIter=5):
"""
k-means
Args:
dataSet:数据集
k:簇类数
Returns:
centroids 聚类中心矩阵
clusterAssment:点分配结果
"""
#随机初始化聚类中心
centroids=randCent(dataSet,k)
init_centroids=centroids.copy()
m,n=np.shape(dataSet)
#点分配结果,第一列指明样本所在的簇,第二列指明样本到聚类中心的距离
clusterAssment=np.mat(np.zeros((m,2)))
#标识聚类中心是否仍在改变
clusterChanged=True
#直至聚类中心不在变化
iterCount=0
while clusterChanged and iterCount<maxIter:
iterCount+=1
clusterChanged=False
#分配样本到簇
for i in range(m):
#计算第i个样本到各个簇类中心的距离
minIndex=0
minDist=np.inf
for j in range(k):
dist=distEclud(dataSet[i,:],centroids[j,:])
if (dist<minDist):
minIndex=j
minDist=dist
#任何一个样本的类簇分配发生变化则认为改变
if (clusterAssment[i,0]!=minIndex):
clusterChanged=True
clusterAssment[i,:]=minIndex,minDist**2
#刷新聚类中心,移动聚类中心到所在簇的均值位置
for cent in range(k):
#通过数组过滤获得簇中的点
ptsInCluster=dataSet[np.nonzero(
clusterAssment[:,0].A==cent)[0]]
if ptsInCluster.shape[0]>0:
#计算均值并移动
centroids[cent,:]=np.mean(ptsInCluster,axis=0)
return centroids,clusterAssment,init_centroids
5 画图展示结果
import matplotlib.pyplot as pl
%matplotlib inline
dataMat=np.mat(loadDataSet('../data/price_diff.csv'))
m,n=np.shape(dataMat)
m,n
#注意,这里我们只设定了对多四个簇的样式,所有前面如果set_k超过4,后面会出现index_error
patterns=['o','D','^','s']
colors=['b','g','y','black']
fig=pl.figure()
title='kmeans with k={}'.format(set_k)
ax=fig.add_subplot(111,title=title)
for k in range(clusterCount):
#绘制聚类中心
ax.scatter(centroids[k,0],centroids[k,1],color='r',marker='+',linewidth=20)
#绘制初始聚类中心
ax.scatter(init_centroids[k,0],init_centroids[k,1],color='purple',marker='*',linewidths=10)
for i in range(m):
#绘制属于该聚类中心的样本
ptsInCluster=dataMat[np.nonzero(clusterAssment[:,0].A==k)[0]]
ax.scatter(ptsInCluster[:,0].flatten().A[0],ptsInCluster[:,1].flatten().A[0],marker=patterns[k],color=colors[k])