数据挖掘上机报告

``一、报告任务
对于一个通信数据包,文件中每一行为:X,Y,代表IP为X的主机发向IP为Y的主机的一个数据包。使用Count-Min Sketch方法识别Top-10频繁通信主机对。
二、算法原理
Count-Min Sketch算法,用于解决大数据统计难题。算法的特点是:不存储所有的不同的元素,只存储它们Sketch的计数。基本的思路是为:
1.创建一个长度为m的数组,用来计数,初始化每个元素的计数值为0;
2.对于一个新来的元素,哈希到0到m之间的一个数,比如哈希值为i,作为数组的位置索引;
3.这时,数组对应的位置索引i的计数值加1;
4.那么,这时要查询某个元素出现的频率,只要简单的返回这个元素哈希后对应的数组的位置索引的计数值即可。
考虑到使用哈希,会有冲突,即不同的元素哈希到同一个数组的位置索引,这样,频率的统计都会偏大。可以使用多个数组,和多个哈希函数,来计算一个元素对应的数组的位置索引;那么,要查询某个元素的频率时,返回这个元素在不同数组中的计数值中的最小值即可。
Count-Min Sketch算法的特点是:只会估算偏大,永远不会偏小;只需要固定大小的内存和计算时间,和需要统计的元素多少无关;对于低频的元素,估算值相对的错误可能会很大。
三、参数选取
1.hash函数的选取:依据对象中的成员变量的值,依照一定的规则计算出一个整数。这个整数就是哈希值。哈希值最重要的两个属性是:
1)假设a.equals(b),那么a.hashCode()==b.hashCode()
2)理想状况下,假设!a.equals(b),那么a.hashCode()!=b.hashCode()
本报告中取用的6个哈希函数为:
hash1=(a*b)%c
hash2=(a+b)%c
hash3=abs(a-b)%c
hash4=(a|b)%c
hash5=(a^b)%c
hash6=(a&b)%c
2.哈希表宽度:总的键值对个数为18866027,数量级为107。一般来说,选择哈希表宽度越宽,内存占用越多,但是统计越准确。经过检验,在使用6个哈希函数情况下,选择哈希表宽度数量级最小为103,能够节省内存且对结果影响不明显。
四、计算结果
经过计算,TOP10频繁通信主机对如下表所示:
表1TOP10频繁通信主机对
X主机IP Y主机IP 通信次数
647067801 1281048150 89002
1148279497 1767542340 83314
3309037651 2254759 79542
352061493 1281048150 61993
3986324625 1281048150 60681
4196430673 1281048150 58824
4033332886 1281048150 57050
1191936803 1714489407 56650
1381261349 1654615343 56172
23675731 1281048150 52888
使用直接计数方法统计出TOP10频繁通信主机对,并与Count-Min sketch进行对比。在同样使用6个哈希函数情况下,不同哈希表宽度频率统计误差如下图所示。

由上图可见,当哈希函数选择6个时,哈希表宽度为104数量级最合适。
五、程序

#创建6个哈希函数
def hash1(a,b,c):
    hi = (a * b) % c
    return hi
def hash2(a,b,c):
    hi = (a + b) % c
    return hi
def hash3(a,b,c):
    hi = abs(a - b) % c
    return hi
def hash4(a,b,c):
    hi = int(a | b) % c
    return hi
def hash5(a,b,c):
    hi = int(a ^ b ) % c
    return hi
def hash6(a,b,c):
    hi = int(a & b) % c
    return hi

def creat_Hash_label(m,k):
#创建初始哈希表,m为哈希表宽度,k为哈希函数个数
    init_Hash_label = []
    for i in range(k):
        temp = []
        for lens in range(m):
            temp.append(0)
        init_Hash_label.append(temp)
    return init_Hash_label

def record_frequency(Hash_label,data):
    n = len(data)
    #print(n)
#利用哈希表统计频数
    for i in range(n):
        info = data[i].split()
        #读取每一对通信数据
        a = int(info[0])
        b = int(info[1])

        t1 = hash1(a, b, m)
        t2 = hash2(a, b, m)
        t3 = hash3(a, b, m)
        t4 = hash4(a, b, m)
        t5 = hash5(a, b, m)
        t6 = hash6(a, b, m)
        #计算由6个hash函数得到的值

        Hash_label[0][t1] += 1
        Hash_label[1][t2] += 1
        Hash_label[2][t3] += 1
        Hash_label[3][t4] += 1
        Hash_label[4][t5] += 1
        Hash_label[5][t6] += 1
        #将hash表中计数+1
    return Hash_label

def count_frequency(Hash_label):
    Top10_frequency = [0,0,0,0,0,0,0,0,0,0]
    Top_XY = {}
    #定义初始值
    n = len(data)
    print(n)
    for i in range(n):
        if i % 1000000 == 0:
            print('已完成:%.2f'%((i/20000000)+0.1))
    #       #统计进度
        info = data[i].split()
        a = int(info[0])
        b = int(info[1])
        str_temp = data[i]

        t1 = hash1(a, b, m)
        t2 = hash2(a, b, m)
        t3 = hash3(a, b, m)
        t4 = hash4(a, b, m)
        t5 = hash5(a, b, m)
        t6 = hash6(a, b, m)

        min_max = min(Hash_label[0][t1], Hash_label[1][t2], Hash_label[2][t3],
                      Hash_label[3][t4], Hash_label[4][t5], Hash_label[5][t6])
        if(min_max > Top10_frequency[9] and (str_temp not in Top_XY)):
            Top_XY[str_temp] = min_max
            #记录通信主机对以及频率
            Top10_frequency[9] = min_max
            #将频繁通信主机对加入
            Top10_frequency.sort(reverse= True)
            #重新排序

    Top_XY = sorted(Top_XY.items(), key=lambda item: item[1], reverse=True)
    Top10_XY = {}
    number = 0
    for items in Top_XY:
        Top10_XY[items[0]] = items[1]
        number += 1
        if number == 10:
            break
    #统计前十的主机对
    return Top10_XY

file = open('equinix-chicago.dirA.20140320-130000.UTC.anon.pcap.flow.txt','r')
data = file.readlines()
file.close()
m = 1880341  #哈希表宽度
init_Hash_label = creat_Hash_label(m,6) #生成初始哈希表
Hash_label = record_frequency(init_Hash_label,data) #将数据统计到哈希表中
Top10_XY = count_frequency(Hash_label)  #统计频繁通信主机对
print(Top10_XY)














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值