DISCOVER__PAGERANK的SQL版本实现
PAGERANK的SQL版本实现
前提
有安装好的数据库。mysql/oracle...之类都可(此处我选用了Oracle)。
对PageRank算法已有一定的了解。
脚本
--Table1: GoogleMatrix_b1 DROP TABLE GoogleMatrix_b1; CREATE TABLE GoogleMatrix_b1 ( POut varchar2(20),--链出,指向别人。 PIn varchar2(20),--链入,被指向的人。 Weight number --权重,pin的被叫分钟数 ); --Table2:GoogleMatrix_b2 DROP TABLE GoogleMatrix_b2; CREATE TABLE GoogleMatrix_b2 AS SELECT T.*, --找到对端的的链入数和对自己的链入比例 COUNT(*) OVER(PARTITION BY T.POut)Ocnt,--链出数,指向别人的数量 T.WEIGHT/SUM(T.WEIGHT) OVER(PARTITION BY T.POut)InitVal--初始的S矩阵 FROM GoogleMatrix_b1 T ;
--Table3:GoogleMatrix DROP TABLE GoogleMatrix; CREATE TABLE GoogleMatrix AS SELECT T.*, InitVal*0.85+(1-0.85)/Ocnt Gval --各节点的初始值.完成google矩阵的计算,此处0.85为经验系数。 FROM GoogleMatrix_b2 T ; --Table4:PageRank迭代表: DROP TABLE PageRank; CREATE TABLE PageRank ( CalCnt number(8),--被计算的次数 Pin varchar2(20),--节点 CurPR float --当前pageRank值 ); INSERT INTO PageRank SELECT DISTINCT 0,T.POut, 1 --此处的1为Q值,系数。用于迭代PageRank的初始值 FROM GoogleMatrix T ; COMMIT; --TABLE5:此处循环此处可能要提高,数据量大的话,数据稳定性的计算周期要加长,最好加入矩阵之间的值的差距的计算。 declare for i in 1 .. 8 loop insert into PageRank SELECT i, t.pin, SUM(t2.CurPR*T.Gval) CURPR FROM GoogleMatrix t, (select t.* from PageRank T, (select max(t.CalCnt) calcnt from PageRank t) t2 where t.calcnt = t2.calcnt )t2 WHERE T.Pout=t2.Pin GROUP BY T.PIN ; commit; end loop; end; /
存在的问题
此处没有对dead ends进行处理,已研究了一个处理方法,但还不是特别的成熟。
因为矩阵不可能完全的展开。如果要分析的数据达到1亿个节点(目前可能处理的问题也有这么大),那么展开的话就是1亿*1亿。
根本没有空间进行存储。