本文为中国大学MOOC网礼欣、嵩天《Python机器学习应用》学习笔记
一、K-means算法分析31省市消费水平
代码:
import numpy as np
from sklearn.cluster import KMeans
def loadData(filePath):
fr = open(filePath,'r+') # r+:以读写的方式打开一个文本文件
lines = fr.readlines() #以readlines方式打开整个文件
retData = [] #存储城市的各项消费信息
retCityName = [] #存储城市名称
for line in lines:
items = line.strip().split(",")
retCityName.append(items[0])
retData.append([float(items[i]) for i in range(1,len(items))])
return retData,retCityName #返回城市名称及消费信息
if __name__ == '__main__':
data,cityName = loadData('city.txt') #利用loadData方法读取数据
km = KMeans(n_clusters=4) #创建实例
label = km.fit_predict(data) #label为聚类后各数据所属的标签
#调用Kmeans() fit_predict()方法进行计算簇中心以及为簇分配序号(0,1,2,3,)
expenses = np.sum(km.cluster_centers_,axis=1) #axis表示按行求和,返回值为列表
#横向计算每个城市的总开销,并把它归类到相应的簇里面。然后对每个簇进行求平均数。得到expense[i]i从0到3
#print(expenses)
CityCluster = [[],[],[],[]] #将城市按label分成设定的簇
for i in range(len(cityName)):
CityCluster[label[i]].append(cityName[i])
for i in range(len(CityCluster)):
print("Expenses:%.2f" % expenses[i]) #输出每个簇的平均花费
print(CityCluster[i]) #输出每个簇的城市名
二、DBSCAN密度聚类分析大学生上网
(DBSCAN密度聚类所依据为曼哈顿距离)
1.上网时间
import numpy as np
import sklearn.cluster as skc
from sklearn import metrics
import matplotlib.pyplot as plt
mac2id=dict()
onlinetimes=[]
f=open('TestData.txt',encoding='utf-8')
for line in f:
mac=line.split(',')[2] #读取每条数据中的mac地址,开始上网时间,上网时长,line.split(',')为第三个元素
onlinetime=int(line.split(',')[6]) #读取的数据默认为字符串,上网时长 1558
starttime=int(line.split(',')[4].split(' ')[1].split(':')[0]) #2014-07-20 22:44:18.540000000
if mac not in mac2id: #mac2id是一个字典,其key为mac地址,value为对应mac地址的上网时长和开始上网时间
mac2id[mac]=len(onlinetimes)
onlinetimes.append((starttime,onlinetime)) #将一个元组作为元素添加到列表中
else:
onlinetimes[mac2id[mac]]=[(starttime,onlinetime)] #更新
real_X=np.array(onlinetimes).reshape((-1,2)) #np.array(onlinetimes)为一个矩阵 [ 22 1558]
#调用DBSCAN算法进行训练,labels为每个数据的簇标签
X=real_X[:,0:1] #[22] 取二维矩阵的第0到(1-1)维
db=skc.DBSCAN(eps=0.01,min_samples=20).fit(X)
labels = db.labels_
#打印数据被记上的标签,计算标签为-1(噪声数据)的比例
print('Labels:')
print(labels)
raito=len(labels[labels[:] == -1]) / len(labels) #计算噪点比例
print('Noise raito:',format(raito, '.2%'))
#计算簇的个数并打印,评价聚类效果
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
print('Estimated number of clusters: %d' % n_clusters_)
print("Silhouette Coefficient: %0.3f"% metrics.silhouette_score(X, labels)) #求轮廓系数
#打印各簇标号以及各簇内数据
for i in range(n_clusters_):
print('Cluster ',i,':')
print(list(X[labels == i].flatten()))
plt.hist(X,24)
plt.show() #绘制直方图
2.上网时长
import numpy as np
import sklearn.cluster as skc
from sklearn import metrics
import matplotlib.pyplot as plt
mac2id=dict()
onlinetimes=[]
f=open('TestData.txt',encoding='utf-8')
for line in f:
mac=line.split(',')[2] #读取每条数据中的mac地址,开始上网时间,上网时长,line.split(',')为第三个元素
onlinetime=int(line.split(',')[6]) #读取的数据默认为字符串,上网时长 1558
starttime=int(line.split(',')[4].split(' ')[1].split(':')[0]) #2014-07-20 22:44:18.540000000
if mac not in mac2id: #mac2id是一个字典,其key为mac地址,value为对应mac地址的上网时长和开始上网时间
mac2id[mac]=len(onlinetimes)
onlinetimes.append((starttime,onlinetime)) #将一个元组作为元素添加到列表中
else:
onlinetimes[mac2id[mac]]=[(starttime,onlinetime)] #更新
real_X=np.array(onlinetimes).reshape((-1,2)) #np.array(onlinetimes)为一个矩阵 [ 22 1558]
#调用DBSCAN算法进行训练,labels为每个数据的簇标签
X=np.log(1+real_X[:,1:]) #[22] 取二维矩阵的第1维,并对其进行取对数操作 [ 7.35179987]
db=skc.DBSCAN(eps=0.14,min_samples=10).fit(X)
labels = db.labels_
#打印数据被记上的标签,计算标签为-1(噪声数据)的比例
print('Labels:')
print(labels)
raito=len(labels[labels[:] == -1]) / len(labels) #计算噪点比例
print('Noise raito:',format(raito, '.2%'))
#计算簇的个数并打印,评价聚类效果
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
print('Estimated number of clusters: %d' % n_clusters_)
print("Silhouette Coefficient: %0.3f"% metrics.silhouette_score(X, labels)) #求轮廓系数
#打印各簇内的样本个数、均值、标准差
for i in range(n_clusters_):
print('Cluster ',i,':')
count=len(X[labels==i])
mean=np.mean(real_X[labels==i][:,1])
std=np.std(real_X[labels==i][:,1]) #计算标准差
print('\t number of sample:',count)
print('\t mean of sample:',format(mean,'.1f')) #设置浮点数精度
print('\t std of sample:',format(std,'.1f'))
plt.hist(X,24)
plt.show() #绘制直方图
小技巧:
左边的数据不适应于聚类分析,对其进行对数变换后,或可使其变得适用于聚类分析。