北京交通大学《大数据》结题报告.docx
《北京交通大学《大数据》结题报告.docx》由会员分享,可在线阅读,更多相关《北京交通大学《大数据》结题报告.docx(82页珍藏版)》请在冰豆网上搜索。
![北京交通大学《大数据》结题报告.docx](https://file1.bdocx.com/fileroot1/2023-4/24/bd50ddbb-6bb1-44c3-9ac2-771b764c4071/bd50ddbb-6bb1-44c3-9ac2-771b764c40711.gif)
北京交通大学《大数据》结题报告
大数据实验报告
——基于matlab和visioC++6.0编程
【实验内容】
1.晨光数据的收集、数据格式预处理
2.相似项发现
(1)电影需求的矩阵表示
(2)最小哈西签名矩阵
(3)利用LSH求电影的Jaccard距离
3.频繁项集
(1)把每个用户下载过的电影集合认为是一个购物篮(旋转列向量变为行向量)
(2)求k=2的频繁项集(两次筛选,先得到频繁项,再扫描找到和之前同时出现的项),并给出支持度(二者都存在的用户占总用户比率)
4.聚类
(1)对晨光的数据进行k-means聚类,给出最佳的聚类数目
5.降维
用PCA/SVD对晨光数据进行降维(用PowerIteration方法求特征向量)
6.为晨光设计一个电影推荐算法,并通过数据验证这个想法
7.以下两个内容二选一
(1)分类:
以聚类结果为输入,任选一种分类方法,对晨光数据进行分类,优化分类性能
(2)流行度统计:
用DGIM方法,跟踪过去一定下载总数中,各视频流行度
【写作要求】
对上述每一个内容,给出:
(1)想要实现的目标
(2)实现的基本原理/方法,设计理由
(3)详细的步骤,每一步的结果
(4)给出结论
(5)问题的难点及其解决方法
一、晨光数据的收集、数据格式预处理
【实现目标】
将晨光中由各同学提交的数据下载下来后,处理为电影名=∑用户名ID,用以后期数据处理。
【基本原理与方法】
使用excel表格进行数据的处理。
【设计理由】
excel处理数据时显示的格式比较规整,方便数据的纵览,且方便后期软件编程时的载入。
【结论】
将收集到的数据处理为电影*用户矩阵,即行为电影,列为用户。
【问题的难点及解决方法】
该过程没有什么难点,主要是数据较多,整理的过程比较繁琐。
二、相似项发现
1电影需求的矩阵表示
【实现目标】
将所得数据进行处理,得到0\1矩阵,用以后期处理。
【基本原理与方法】
电影=∑用户ID,即每来一个电影文件,就将其所属的ID和之前已有的ID比较,若为新用户,则将ID添加到用户组内,反之不做任何处理。
等所有用户ID登记完后,将每一个电影的ID和用户文件库内数据相比较,若该用户下载过该电影,则记为1,否则为0,最终得到用0、1表示的电影需求矩阵。
【设计理由】
在进行后期电影聚类、推荐等等过程中,使用行与行之间的距离来代替两向量之间的相似度。
【详细步骤,每一步的结果】
矩阵初始化得到0、1矩阵KK,即为电影需求矩阵,存为“Matrixinitialization.txt”文件。
clc,clearall
D=importdata('filetr.txt','')%原文有误?
D=importdata('filetr.txt')%载入含字符串和数字的txt
data=D.data%分解得到数据部分
text=D.textdata%分解得到文本部分
C=data%数据赋给新矩阵,方便后期处理
C(isnan(C))=0%消除其中的NAN
[m,n]=size(C)%矩阵C的行列数
y=C(1,:
)
fori=1:
m-1
z=setdiff(C(i+1,:
),y)%C若有y的元素则删除,剩下的给z
y=[y,z]%合并列向量
i=i+1
end%y登记所有用户
y(find(y==0))=[]%删除全0列
%[p,q]=size(y)
%aa=zeros(p,q)
%aa(1:
m,1:
n)=C%将源数据变成和用户数组一样大小的矩阵,方便后期比较
kk=ismember(y(1,:
),C(1,:
))
fori=1:
m-1
k=ismember(y(1,:
),C(i+1,:
))%比较a每一行和y是否有相同元素,有则记为1
kk=[kk;k]
i=i+1
end%形成o/1矩阵
dlmwrite('Matrixinitialization.txt',kk,',')%保存电影需求矩阵为“Matrixinitialization.txt”
%S=sparse(kk)%稀疏矩阵
distance=pdist(kk,'jaccard')%jaccard距离
[p,q]=size(distance)
aa=ones(p,q)
simjac=aa-distance%jaccard相似度
dlmwrite('jaccarddistance.txt',distance,',')%从电影需求矩阵求jaccard距离的txt结果
dlmwrite('jaccarddistance.csv',distance,',')%从电影需求矩阵求jaccard距离的excel结果
dlmwrite('jaccardsimilarity.txt',simjac,',')%从电影需求矩阵求jaccard相似度的txt结果
【结论】
经过程序运算后得到电影需求的0、1矩阵表示如下,矩阵大小为48*2257,即一共有48部电影,设计到的所有用户(用户数据库)一共有2257人:
从该初始化矩阵直接求jaccard距离(两行之间,也就是两电影之间的相似度),计算过程比较慢,但是得到的是最完备的信息:
通过将原始数据经程序运算后转换为0、1矩阵,这是计算机处理后期编程处理的基础。
【问题的难点及解决方法】
由于较少使用程序自带语句,而使用较多的for循环等,使得数据量大后运算速度较慢。
2最小哈希签名矩阵
【实现目标】
将初始化得到的0、1电影需求矩阵转化为最小哈希签名矩阵。
【基本原理与方法】
(1)哈希函数:
设SIG为最终得到的最小哈希签名矩阵,SIG(i,c)为签名矩阵中第i个哈希函数在第C列上的元素。
对于每一行r:
计算h1(r),h2(r),……hn(r);
对每一列C进行:
)若C列第r行为0,不做任何处理;
)若C列第r行为1将SIG(i,C)设为原来的SIG(i,C)和hi(r)的最小值
为此在建立一个哈希表之前需要解决两个主要问题:
)构造一个合适的哈希函数
均匀性H(key)的值均匀分布在哈希表中;
简单以提高地址计算的速度
)冲突的处理
冲突:
在哈希表中,不同的关键字值对应到同一个存储位置的现象。
即关键字K1≠K2,但H(K1)=H(K2)。
均匀的哈希函数可以减少冲突,但不能避免冲突。
发生冲突后,必须解决;也即必须寻找下一个可用地址。
解决冲突的方法:
链接法(拉链法)。
将具有同一散列地址的记录存储在一条线性链表中。
例,除留余数法中,设关键字为(18,14,01,68,27,55,79),除数为13。
散列地址为(5,1,1,3,1,3,1),哈希散列表如图。
开放定址法。
如果h(k)已经被占用,按如下序列探查:
(h(k)+p⑴)%TSize,(h(k)+p⑵)%TSize,…,(h(k)+p(i))%TSize,…
其中,h(k)为哈希函数,TSize为哈希表长,p(i)为探查函数。
在h(k)+p(i-1))%TSize的基础上,若发现冲突,则使用增量p(i)进行新的探测,直至无冲突出现为止。
其中,根据探查函数p(i)的不同,开放定址法又分为线性探查法(p(i)=i:
1,2,3,…),二次探查法(p(i)=(-1)^(i-1)*((i+1)/2)^2,探查序列依次为:
12,-12,22,-22…),随机探查法(p(i):
随机数),双散列函数法(双散列函数h(key),hp(key)若h(key)出现冲突,则再使用hp(key)求取散列地址。
探查序列为:
h(k),h(k)+hp(k),…,h(k)+i*hp(k))。
桶定址法。
桶:
一片足够大的存储空间。
桶定址:
为表中的每个地址关联一个桶。
如果桶已经满了,可以使用开放定址法来处理。
例如,插入A5,A2,A3,B5,A9,B2,B9,C2,采用线性探查法解决冲突。
(2)jaccardindex:
Jaccardindex是用来计算相似性,也就是距离的一种度量标准。
假如有集合A、B,那么J(A,B)=(AintersectionB)/(AunionB)
也就是说,集合A,B的Jaccard系数等于A,B中共同拥有的元素数与A,B总共拥有的元素数的比例。
很显然,Jaccard系数值区间为[0,1]。
(3)Minhash:
传统的hash算法只负责将原始内容尽量均匀随机地映射为一个签名值,原理上相当于伪随机数产生算法。
传统hash算法产生的两个签名,如果相等,说明原始内容在一定概率下是相等的;如果不相等,除了说明原始内容不相等外,不再提供任何信息,因为即使原始内容只相差一个字节,所产生的签名也很可能差别极大。
从这个意义上来说,要设计一个hash算法,对相似的内容产生的签名也相近,是更为艰难的任务,因为它的签名值除了提供原始内容是否相等的信息外,还能额外提供不相等的原始内容的差异程度的信息。
MinHash也是LSH的一种,可以用来快速估算两个集合的相似度。
MinHash由AndreiBroder提出,最初用于在搜索引擎中检测重复网页。
它也可以应用于大规模聚类问题。
h(x):
把x映射成一个整数的哈希函数。
hmin(S):
集合S中的元素经过h(x)哈希后,具有最小哈希值的元素。
那么对集合A、B,hmin(A)=hmin(B)成立的条件是A∪B中具有最小哈希值的元素也在A∩B中。
这里有一个假设,h(x)是一个良好的哈希函数,它具有很好的均匀性,能够把不同元素映射成不同的整数。
所以有,Pr[hmin(A)=hmin(B)]=J(A,B),即集合A和B的相似度为集合A、B经过hash后最小哈希值相等的概率。
有了上面的结论,我们便可以根据MinHash来计算两个集合的相似度了。
一般有两种方法:
第一种:
使用多个hash函数
为了计算集合A、B具有最小哈希值的概率,我们可以选择一定数量的hash函数,比如K个。
然后用这K个hash函数分别对集合A、B求哈希值,对
每个集合都得到K个最小值。
比如Min(A)k={a1,a2,...,ak},Min(B)k={b1,b2,...,bk}。
那么,集合A、B的相似度为|Min(A)k∩Min(B)k|/|Min(A)k∪Min(B)k|,即Min(A)k和Min(B)k中相同元素个数与总的元素个数的比例。
第二种:
使用单个hash函数
第一种方法有一个很明显的缺陷,那就是计算复杂度高。
使用单个hash函数是怎么解决这个问题的呢?
请看:
前面我们定义过hmin(S)为集合S中具有最小哈希值的一个元素,那么我们也可以定义hmink(S)为集合S中具有最小哈希值的K个元素。
这样一来,我们就只需要对每个集合求一次哈希,然后取最小的K个元素。
计算两个集合A、B的相似度,就是集合A中最小的K个元素与集合B中最小的K个元素的交集个数与并集个数的比例。
【设计理由】
经过试验后,我采用的是第一种方法,也就是使用多个哈希函数,将2257个用户哈希到多个不同的桶中,得到桶数目*电影的矩阵,方便后期对所有电影比较相似度。
【详细步骤,每一步的结果】
(1)处理数据:
将初始化得到的电影*用户的0、1矩阵转置后得到用户*电影矩阵:
(2)调用程序,将用户哈希到10个哈希桶内,和无穷大矩阵循环比较后,得到哈希签名矩阵:
clc,clearall
D=importdata('Matrixinitialization.txt')%载入含字符串和数字的txt
C=D'%数据赋给新矩阵,方便后期处理
[mm,nn]=size(C)
a=[0:
mm-1]%原行数编号
aa=length(a)%行数=mm,后期进行哈希函数时的常数1的构造
%ab=12%选取哈希函数量,即桶数目
temp=ones(1,aa)
b=mod(a.*11+temp,aa)%哈希函数1
c=mod(a.*13+temp,aa)%哈希函数2
d=mod(a.*17+temp,aa)%哈希函数3
e=mod(a.*19+temp,aa)%哈希函数4
f=mod(a.*5+temp,aa)%哈希函数5
l=mod(a.*7+temp,aa)%哈希函数6
r=mod(a.*23+temp,aa)%哈希函数7
s=mod(a.*29+temp,aa)%哈希函数8
t=mod(a.*31+temp,aa)%哈希函数9
u=mod(a.*59+temp,aa)%哈希函数10
%v=mod(a.*61+temp,aa)%哈希函数11
%w=mod(a.*67+temp,aa)%哈希函数12
h=[b;c;d;e;f;l;r;s;t;u]%合并行向量,形成10*48的哈希桶
[m,n]=size(h)
hS=inf(m,nn)%签名矩阵初始化,哈希函数个数*原列数
forp=1:
mm
forq=1:
nn
if[C(p,q)==1]%逐列扫描
a=1%元素为1进行哈希桶和原初始化矩阵比较大小
fori=1:
m%循环判断、赋值
if[h(i,p)<=hS(i,q)]
hS(i,q)=h(i,p)
continue
else
end
end
elsea=0
end
end
end
dlmwrite('签名矩阵.txt',hS,',')%最小签名矩阵
%由minhash求相似度,后期和其它方法作对比
[m1,n1]=size(hS)
cc=1%自相似度为1
fori=1:
n1-1
forj=i:
n1-1
a=intersect(hS(:
i),hS(:
j+1))
b=union(hS(:
i),hS(:
j+1))
c=length(a)./length(b)
cc=[cc,c]%相似度保存在CC矩阵里
end
end
dlmwrite('similarity.csv',cc,',')%由最小哈希求相似度,并保存在excel文件中,方便后期比较
【结论】
通过如上程序处理后,得到哈希签名矩阵如下,一共有10个桶(行数),48个电影(列数):
通过选取多个哈希函数可将用户哈希到多个桶中,通过每一个哈希函数可得到一个哈希值,该值作为电影签名的一个数值。
一个电影可表示为多个哈希值的组合,也就是所谓的签名。
通过哈希签名,可将原数量巨大的初始化0、1矩阵大大缩减,以减少存储空间,提高运算效率,同时通过哈希签名是否相同即可判定电影的相似度大小,这种方法很实用。
【问题的难点及解决方法】
(1)哈希函数构造问题:
选取的哈希函数不能向下包容,即极可能不冲突,使得同一个电影不多次哈希到同一桶中,使其分布均匀化。
我采用的是素数构造方法,但是不可避免的还是有冲突存在(第一列),这一点事关哈希函数的合适构造问题;
(2)哈希函数数量:
从原理上来说,哈希函数数目越多,得到的哈希签名矩阵越完备,求得的距离也就越准确,但不可避免的也会带来计算的复杂度和时间复杂度,所以根据用户数大小选择合适的哈希函数数量是一个值得权衡的事情。
经过多次增减哈希函数,我最终采用的是10个哈希函数,这样运算速度不至于很慢,同时也能基本反映相似度。
3用LSH求jaccard距离
【实现目标】
通过minhash得到LSH,并由LSH求得电影间的相似度。
【基本原理与方法】
(1)局部敏感哈希:
即使可以使用最小哈希将大文档压缩成小的签名并同时保持任意文档之间的预期相似度,但是高效寻找具有最大相似度的文档对仍然是不可能的。
主要原因在于,即使文档本身的数目并不很大,但需要比较的文档对的数目可能很大。
实际中往往只需要得到那些最相似的或者相似度超过某一下界的文档,因此我们只需要关注那些可能相似的文档对,而不需要研究所有的文档对。
(2)哈希桶:
哈希表中同一个位置可能存有多个元素,以应对哈希冲突问题。
这样,哈希表中的每个位置表示一个哈希桶。
(3)局部敏感:
称一个函数族H={h:
S->U}是(r1,r2,p1,p2)局部敏感的,如果满足下面两个条件(D为空间距离度量,Pr表示概率):
1)若空间中两点p和q之间的距离D(p,q)p1
2)若空间中两点p和q之间的距离D(p,q)>r2,则Pr(h(p)=h(q))条件在r1p2的条件下有意义。
通俗来讲,就是距离较近的点映射到同一个位置的概率大,距离较远的点映射到同一个位置的概率小。
这对下面将点集映射得到候选结果集的操作很重要,能保证得到的候选结果集是可用的。
(4)面向最小哈希签名的LSH:
LSH的一个一般性做法就是对目标项进行多次哈希处理,使得相似项会比不相似项更可能哈希到同一桶中。
然后将至少有一次哈希到同一桶中的文档对看成是候选对,我们只检查这些候选对之间的相似度。
(5)行条化策略:
很显然,如果两个字符串相似,那么它们对应的签名向量应该也相似,在局部某个范围内极有可能相同,如果采用哈希的话,就可以映射到同一个桶。
设想我们对签名矩阵划分若干个行条,每一个行条里有数列,如果两个字符串相似,那猜测肯定在某个行条里,这两个字符串对应的签名向量应该相等,它们会映射到同一个桶里。
对每一个行条,我们设置一个大桶,对行条中的每一列计算其hash值,相同hash值的列会映射到同一个hash桶。
在hash桶里的列,就组成了候选对。
对最后得到的候选对再计算jaccard相似度。
可以对所有行条使用相同的哈希函数,但是对每个行条我们都使用一个独立的桶数组,因此即使是不同行条中的相同列向量,他们也不会被哈希到同一桶中。
【设计理由】
为了提高计算速度,节约存储空间,所以比较相似度时不再使用初始化的电影需求0、1矩阵,而是使用针对minhash的LSH,这样只计算那些多次哈希到同一个桶里的候选对。
【详细步骤,每一步的结果】
(1)载入minhash的签名矩阵,该矩阵由第二步完成:
(2)将签名矩阵划为5个行条,每行条内有2行(b=5,r=2),这要得到的阈值为0.477,使得S曲线中成为候选对的概率接近0.5,也即最优化;
(3)分块后的行条分别哈希到25个桶内,按模块保存哈希到同一桶中的原哈希签名矩阵中的向量,并求同一桶中两向量之间的距离:
clc;clearall
D=importdata('签名矩阵.txt')%载入最小哈希签名的txt
[m,n]=size(D)
b1=[D(1,:
);D(2,:
)]%划分M矩阵为b=5,r=2的小矩阵,阈值0.447
b2=[D(3,:
);D(4,:
)]
b3=[D(5,:
);D(6,:
)]
b4=[D(7,:
);D(8,:
)]
b5=[D(9,:
);D(10,:
)]
[m1,n1]=size(b1)
%分块后的矩阵哈希到桶内
forj=1:
n1%将签名哈希到5*5=25个桶中,桶编号从00到24
fori=1:
m1
bb(i,j)=mod(b1(i,j),5)%%处理第一行条
end
end
fori=1:
n1%求和桶编号,得到缩小的桶编号,从0到8
b(i)=bb(1,i)+bb(2,i)
end
%寻找同一行条下哈希到一个桶内的列向量,形成新小矩阵
t=ones(m,1)
forj=0:
8
Mj=zeros(m,1)
fori=1:
48
ifb(i)==j
Mj=[Mj,D(:
i)]
else
end
if(i==48)
t=[t,Mj]
else
end
end
%
%[m3,n3]=size(Mj)
%cc=1%自相似度为1
%forq=1:
n3-1
%a=intersect(Mj(:
j),Mj(:
j+1))
%b=union(Mj(:
j),Mj(:
j+1))
%c=length(a)./length(b)
%cc=[cc,c]%相似度保存在CC矩阵里
%end
%dlmwrite('.csv',T,',')
end
t(:
2)=[]
t(:
1)=[]
T=t%以列向量为0作为一个哈系桶的标志
dlmwrite('b1.csv',T,',')%将哈希到同一桶中的列向量分块保存
dlmwrite('similarity.csv',c,',')%由最小哈希求相似度,并保存在excel文件中,方便后期比较
(4)计算哈希到同一桶中的列向量之间的距离:
[m1,n1]=size(Mj1)
c1=1%自相似度为1
forj=1:
n1-1
a=intersect(Mj1(:
j),Mj1(:
j+1))
b=union(Mj1(:
j),Mj1(:
j+1))
c=length(a)./length(b)
c1=[c1,c]%相似度保存在CC矩阵里
end
b1行条下哈希到同一桶中的向量,以列向量为0作为区分:
b1行条下求相似度:
b2行条下哈希到同一桶中的向量,以列向量为0作为区分:
b2行条下求相似度:
b3行条下哈希到同一桶中的向量,以列向量为0作为区分:
b3行条下求相似度:
b4行条下哈希到同一桶中的向量,以列向量为0作为区分:
b4行条下求相似度:
b5行条下哈希到同一桶中的向量,以列向量为0作为区分:
b5行条下求相似度:
【结论】
以b4行条和b5行条下的[34,3,52,58,9,22,70,0,46,4]和[154,4,73,8,7,4,10,10,2,3]为例,二者恰好至少有两次被哈希到同一个桶里,说明有较高的相似度,经过比对后,b4内求得的相似度为0.125,b5内求得的为0.11765,二者数值比较接近,说明该方法确实能得到较为准确的电影间相似度。
当不断增加哈希函数量至和电影数相同时,得到的相似度近似为初始化矩阵中求得的精确相似度。
将minhash签名矩阵进行行条化策略后,通过构建哈希桶,使得只需处理至少有一次落在同一个桶内的候选对,这样就可提高计算速度,节约存储空间。
但是,和minhash一样,由于使用的哈希数目有限,得到的哈希值分布范围较大,所以两值相同的概率减小,也就是说会忽略掉一些相关信息,所以得到的相似度会减小。
总体上来衡量的话,LSH可以较为准确快捷的得到相似度。
【问题的难点及解决方法】
(1)哈希函数选择。
较为合适的选择哈希函数可以将行条内的向量较为准确的映射到相应的桶内,所以我还是选择和minhash一样的素数构造方法。
(2)行条数b的选择。
为了使成为候选对的概率接近S曲线斜率的0.5处,需计算b、r的值,使阈值接近0.5。
(3)不同行条下的同一列向量会被哈希到不同的桶内,所以多次循环可以实现同一列向量和不同向量之间的相似度计算,也就弥补了由信息缺失而引起的相似度减小的损失。
三、降维
【实现目标】
用PCA/SVD对晨光数据进行降维(用PowerIteration方法求特征向量)
【基本原理与方法】
(1)PCA:
将原来的样本数据投影到一个新的空间中,相当于我们在矩阵分析里面学习的将一组矩阵映射到另外的坐标系下。
通过一个转换坐标,也可以理解成把一组坐标转换