侧边栏壁纸
博主头像
这就是之谦博主等级

我们的征途是星辰大海

  • 累计撰写 182 篇文章
  • 累计创建 3 个标签
  • 累计收到 16 条评论
标签搜索

目 录CONTENT

文章目录

基于DBSCAN密度聚类算法的大学生上网行为分析

这就是之谦
2021-10-29 / 0 评论 / 0 点赞 / 435 阅读 / 4,432 字
温馨提示:
本文最后更新于 2021-11-14,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

基于DBSCAN密度聚类算法的大学生上网行为分析

源代码及数据集:

链接:https://pan.baidu.com/s/1ywQCCo9JGTSggoI798v4BA
提取码:h2p3

Ⅰ、项目任务要求

*任务描述:*

随着互联网技术的快速发展以及教育信息化建设的逐步推进,校园网作为给师生提供教学、科研、交流的重要平台,已成为衡量高校现代化和信息化建设的重要指标。但伴随校园网规模的扩大和用户数量的持续增长,校园网也带来一些负面影响。比如有些学生过于沉迷网络,耗费了大量的时间与精力,占用了大量的带宽。因此,分析校园网用户行为是很有意义的。

本次实验通过对大学生上网时间、上网时长进行分析,挖掘得出学生的各种行为倾向与规律,以期能开发出一个大学生上网的行为分析系统。通过此系统分析出学生的行为特征,可以进行实时分析,还可以及时掌握学生的行为发展趋势。同时识别一些异常的网络行为,最后将可能有异常行为发生的用户列举,以便于学校采取对应的策略或者措施引导学生健康上网,从而使互联网真正成为学生获取知识的平台,从而来提高学生整体的综合素质。

此实验内容:****用DBSCAN算法对大学生上网日志数据集(月)按照上网时间、上网时长进行聚类,并写出实验结果分析。****

*主要任务要求:*

1、简述DBSCAN密度聚类算法思想和实现原理。

2、数据集****(*TestData.txt*)****介绍。

3、写出实验结果分析:

3.1 实验运行环境描述。如开发平台、编程语言、调参情况等。

3.2实验结果分析。

(1)按上网时间进行聚类并写出聚类效果;

(2)按上网时长进行聚类并写出聚类效果;

(3)采用轮廓系数评估上述两个聚类效果;

(4)结合两个聚类结果和评估结果对实验结果进行分析说明。

II、方法思想及实现原理陈述(20分)

markdown格式不支持很多文本的显示,自行百度或者下载源代码中有word版本

III、实验结果分析(30分)

3.1 实验运行环境描述。如开发平台、编程语言、调参情况等。

运行环境为python的sklearn平台

3.2实验结果分析。

(1)按上网时间进行聚类并写出聚类效果;

image.png

image.png

可观察到:上网时间大多聚集在22:00和23:00

(2)按上网时长进行聚类并写出聚类效果;

image.png

这里有个问题:如果我们直接进行聚类的话,结果所有数据都被划分为噪声数据,以至于没有一个核心点。

为此,绘制出原始数据的直方图分布,可看到原始数据是不适合用于聚类分析的,因此我们这里使用对数变换来解决该类问题:

image.png
image.png

对数变换后上网时长的聚类结果:

image.png

image.png

(3)采用轮廓系数评估上述两个聚类效果;

聚类评估算法-轮廓系数(Silhouette Coefficient )

对时间聚类的Silhouette Coefficient: 0.710

对时长聚类的Silhouette Coefficient: 0.227

(4)结合两个聚类结果和评估结果对实验结果进行分析说明。

从聚类数目和轮廓系数来看,时长聚类效果不如时间的聚类效果明显。

IV、代码实现(50分)

# -*- coding: utf-8 -*-
'''
对上网开始时间进行聚类
'''
import numpy as np
from sklearn.cluster import DBSCAN
from sklearn import metrics#计算方法
import matplotlib.pyplot as plt
# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


mac2id=dict()
onlinetimes=[]
f=open('TestData.txt',encoding='utf-8')
for line in f:
    items = line.strip().split(",")
    #mac地址
    mac=items[2]
    #上网时长
    onlinetime=int(items[6])
    #时间格式举例:2014-07-20 22:44:18.540000000
    starttime=int(items[4].split(' ')[1].split(':')[0])#只保留时间的小时位

    #保证onlinetime中对应一个mac地址有一个唯一的记录
    if mac not in mac2id:
        mac2id[mac]=len(onlinetimes)
        onlinetimes.append((starttime,onlinetime))
    else:
        onlinetimes[mac2id[mac]]=(starttime,onlinetime)

real_X=np.array(onlinetimes).reshape((-1,2)) #-1代表行数由程序自行根据列数和总数据信息推算出

#***************************************************
# X=real_X[:,0:1]#只得到上网(开始)时间
# plt.hist(X,24)
# plt.title("上网(开始)时间原始数据")
# plt.savefig("上网(开始)时间原始数据.png")
# # plt.show()
# plt.clf()

# # 调用DBSCAN方法进行训练,labels为每个数据的簇标签
# db=DBSCAN(eps=0.01,min_samples=20).fit(X)
#***************************************************
X=real_X[:,1:]#只得到上网时长
plt.hist(X,24)
plt.title("原始数据分布")
plt.savefig("原始数据分布.png")
# plt.show()
plt.clf()

X=np.log(1+real_X[:,1:])#只得到上网时长,对数变换,这里+1是为了防止为0的情况
# X=real_X[:,1:]
plt.hist(X,24)
plt.title("对数变换后数据分布")
plt.savefig("对数变换后数据分布.png")
# plt.show()
plt.clf()
#************************************************
#调用DBSCAN方法进行训练,labels为每个数据的簇标签
db=DBSCAN(eps=0.14,min_samples=10).fit(X)

labels = db.labels_#返回的数据的簇标签,噪声数据标签为-1
print('Labels:\n',labels)

#计算标签为-1的数据(即噪声数据)的比例
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_)

#评价聚类效果:轮廓系数si,原理可参考:http://blog.csdn.net/xueyingxue001/article/details/51966932
'''
            si接近1,则说明样本i聚类合理;
            si接近-1,则说明样本i更应该分类到另外的簇;
            若si 近似为0,则说明样本i在两个簇的边界上。
'''
print("Silhouette Coefficient: %0.3f"% metrics.silhouette_score(X, labels))#聚类效果评价指标
# Silhouette Coefficient: 0.710
# Silhouette Coefficient: 0.227
#打印各簇标号以及各簇内数据
for i in range(n_clusters_):
    print('number of data in Cluster %s is : %s'%(i,len(X[labels==i])))
    #print(list(X[labels == i].flatten()))


#绘制直方图分析
plt.hist(X,24)
plt.title("聚类")
plt.savefig("聚类.png")
# plt.show()
plt.clf()
0

评论区