1. 程式人生 > >分析學生上網日誌——聚類DBSCAN例項練習

分析學生上網日誌——聚類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])