分析学生上网日志——聚类DBSCAN实例练习

#分析学生开始上网时间和上网时长的模式
#单个学生上网日志(记录编号、学生编号、MAC地址、IP地址、开始、停止上网时间、上网时长)
#1.建立工程,引入sklearn相关包
import numpy as np
import sklearn.cluster as skc
from sklearn import metrics
import matplotlib.pyplot as plt
#2.加载数据,预处理数据
#读取每条数据中的mac地址,开始上网时间,上网时长
mac2id=dict()
onlineTimes=[]
f=open('TestData.txt',encoding='utf-8')#注意编码方式
for line in f:
    mac=line.split(',')[2]
    startTime=int(line.split(',')[4].split()[1].split(':')[0])#要用int 不能eval
    onlineTime=int(line.split(',')[6])#读取每条数据的mac地址,开始上网时间,上网时长
    if mac not in mac2id:#mac2id字典中键为mac地址,值为对应mac地址的上网时间和上网时长
        mac2id[mac]=len(onlineTimes)
        onlineTimes.append((startTime,onlineTime))
    else:
        onlineTimes[mac2id[mac]]=[(startTime,onlineTime)]
#2.1上网时间聚类,创建DBSCAN,进行训练,获得标签
real_X=np.array(onlineTimes).reshape(-1,2)#变换成n行2列维度的数组
X=real_X[:,0:1]#提取每行的第一列数,即startTime
db=skc.DBSCAN(eps=0.01,min_samples=20).fit(X)
labels=db.labels_
print('Labels:%s'%labels)#输出数据被记上的标签
#计算噪声数据(标签为-1)的比例
ratio=len(labels[labels[:]==-1])/len(labels)
#labels[:]==-1生成一个布尔数组,labels[labels[:]==-1]挑出原labels内为-1的元素
print('Noise ratio:{:.2%}'.format(ratio)) #要加:
#计算簇的个数(先把labels变为集合,集合无重复,计算总label个数,减去噪声label)
n_clusters_=len(set(labels))-(1 if -1 in labels else 0)
print('Estimated number of cluster:%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()))#array.flatten()为折叠成一维数组 
#直方图展示,分析结果
plt.subplot(121)
plt.hist(X,24)
plt.xlabel('上网时间')
plt.ylabel('上网时长')
plt.axis([0,25,0,70])

#2.2上网时长聚类,创建DBSCAN,进行训练,获得标签
Y=np.log(1+real_X[:,1:])
db=skc.DBSCAN(eps=0.14,min_samples=10).fit(Y)
labels=db.labels_
print('Labels_Y:%s'%labels)
ratio=len(labels[labels[:]==-1])/len(labels)
print('Noise ratio:{:.2%}'.format(ratio))
n_clusters_=len(set(labels))-(1 if -1 in labels else 0)
print('Estimated number of cluster:%d'%n_clusters_)
print('Silhouette Coefficient:%0.3f'%metrics.silhouette_score(Y,labels))
#统计每一个簇内的样本个数,均值,标准差
for i in range(n_clusters_):
    print('Cluster',i,':')
    count=len(Y[labels==i])
    mean=np.mean(real_X[labels==i][:,1])
    std=np.std(real_X[labels==i][:,1])
    print('\t number of sample:%d'%count)
    print('\t mean of sample  :%.2f'%mean)
    print('\t std of sample   :{:.2f}'.format(std))
plt.subplot(122)
plt.subplots_adjust(wspace=0.3)#调整subplots之间横向间距,纵向用hspace
x=np.linspace(0,len(labels),len(labels))
plt.plot(x,real_X[:,1])       

猜你喜欢

转载自blog.csdn.net/weixin_42183992/article/details/86076602
今日推荐