PageRank 算法

​ 作为 Google 最早的一个网页排名算法,该算法在早期的搜索引擎中是搜索结果最为准确的,同时也是 Google 发家的一个重要算法。尽管这些年来该算法不再是 Google 对于网页排名的唯一算法,但是它的核心思想还是值得我们去研究一下的。

​ 算法简单描述:首先假定每个网页被引用的概率是相同的,然后通过计算每个网页被其它网页链接的权值进行进一步的概率计算,得到每个页面被引用的概率,再乘上对应的修正因子以及加上最小的概率,最后按照这个概率进行排序。

​ 简化的计算公式如下所示:

\[PR(p_i) = \frac{1 - d}{N} + d\sum\limits_{p_j\in M(p_i)} \frac{PR(p_j)}{L(p_j)}
\]

​ 其中 PR(pi) 表示 pi 网页被引用的概率;d 表示阻尼系数,表示任意时刻yong'hu访问到某一网页之后访问下一页面的概率;N 表示总的网页个数;L 表示 pj 所链接的网页总数;M 表示 pi 链接的集合。

PLPGSQL

​ PLPGSQL 是 PostgreSQL 的一个可加载的过程语言,通过 PLPGSQL 可以用于:创建函数和触发器、执行一般程序语言的控制语句、定义数据变量等一般程序设计语言的能做的事。因此,使用 PostgreSQL 实现 PageRank 再理论上是可行的。

实现

​ 这里的实现的目标是通过人际之间的关系,将集合内的人按照威望的高度从高到低排序。这里的威望只是单纯地计算他与其它人的联系数量得出的。按照 PageRank 的思想,可以通过 PageRank 完成这个任务。

  • 首先创建数据表

    -- 用户数据表,包含一些基本的数据,在本次实现中实际主要用到的只有 ID
    CREATE TABLE IF NOT EXISTS vk_user
    (
    id VARCHAR(20) NOT NULL UNIQUE PRIMARY KEY,
    first_name TEXT,
    last_name TEXT,
    is_closed BOOLEAN,
    can_access_close BOOLEAN,
    domain TEXT,
    online INT,
    track_code TEXT
    ); -- 这些用户之间的关联关系表
    CREATE TABLE IF NOT EXISTS friend
    (
    self_id VARCHAR(20) NOT NULL,
    friend_id VARCHAR(20) NOT NULL,
    PRIMARY KEY (self_id, friend_id),
    CONSTRAINT self_id_foreign FOREIGN KEY (self_id) REFERENCES vk_user (id),
    CONSTRAINT friend_id_foreign FOREIGN KEY (friend_id) REFERENCES vk_user (id)
    ); -- 每个用户的朋友信息情况表,这里的 rate 就相当于上文公式内的 1/L(pj)
    CREATE TABLE IF NOT EXISTS friend_num
    (
    id VARCHAR(20) NOT NULL UNIQUE PRIMARY KEY,
    rate FLOAT,
    CONSTRAINT id_foreign FOREIGN KEY (id) REFERENCES vk_user (id)
    ); -- 用于保留最终结果的数据表,类似于得到的搜索结果向量
    CREATE TABLE friend_rank
    (
    id VARCHAR(20) PRIMARY KEY NOT NULL UNIQUE,
    rank FLOAT,
    CONSTRAINT rank_id_foreign FOREIGN KEY (id) REFERENCES friend_num (id)
    );
  • 插入数据

    -- 数据插入部分,这部分数据是来源自己的生活大致得到的
    INSERT INTO vk_user (id, first_name, last_name, is_closed, can_access_close, domain, online, track_code)
    VALUES ('1', 'Xianghai', 'Liu', false, true, 'www.google.com', 13564, '7c4a8d09ca3762af61e59520943dc26494f8941b'),
    ('2', 'Yongfeng', 'Zhao', false, true, 'www.vk.vom', 26497, 'df6c025064f6cfca940c8b24c212f226e06d1ce7'),
    ('3', 'Jian', 'Du', false, true, 'www.google.com', 13246, '570d931f9e3a5b3315081cbdbffa375bbc3732b0'),
    ('4', 'Gang', 'Xu', false, true, 'www.baidu.com', 15674, '479ce1e3f7d2c2f067fbc41132d489276f511c3c'),
    ('5', 'Yulong', 'Guo', true, false, 'www.vk.com', 56794, 'cb17d8ce007c1e12aa8c6facf27f3802c20085a9'),
    ('6', 'Zhiping', 'Deng', true, true, 'www.google.com', 13546, 'ddd2161b25f5e83b457ac416435bd2a9b0cd319c'),
    ('7', 'Yongjian', 'Chang', true, false, 'www.baidu.com', 79843, '278f8ea5e2c88aa508eed086d7dd819d89c10fae'),
    ('8', 'Hao', 'Zhou', false, false, 'www.vk.vom', 15434, '9f9c58540ed85334688e8cd46254e953e71e6845'),
    ('9', 'Xiaohan', 'Chen', true, true, 'www.google.com', 16798, '60cd5914aa6c63d0c17133f0b3bfd28caab3193d'),
    ('10', 'Zixuan', 'Liu', true, false, 'www.baidu.com', 16574, '580e58f8918e7da55445c28247300476dc16a10b');
    INSERT INTO friend (self_id, friend_id)
    VALUES ('1', '2'),('1', '3'),('1', '6'),('1', '7'),('1', '9'),('10', '9'),('2', '3'),('2', '4'),
    ('2', '5'),('2', '6'),('2', '7'),('2', '8'),('2', '9'),('2', '1'),('3', '2'),('3', '4'),
    ('3', '5'),('3', '1'),('4', '3'),('4', '5'),('4', '8'),('4', '2'),('5', '2'),('5', '3'),
    ('5', '4'),('6', '7'),('6', '8'),('6', '1'),('6', '2'),('7', '1'),('7', '2'),('7', '6'),
    ('8', '4'),('8', '2'),('9', '1'),('9', '2'),('9', '10');
    -- 数据插入结束 -- 根据上文的信息得到 friend_num 的数据
    INSERT INTO friend_num
    SELECT friend.self_id,
    round(1::numeric / count(friend.friend_id)::numeric, 4) AS friend_num
    FROM friend
    GROUP BY self_id;
  • 计算函数创建

    CREATE OR REPLACE FUNCTION PageRank() RETURNS VOID AS
    $$
    DECLARE
    -- 阻尼系数
    conversionFactor FLOAT := 0.85;
    DECLARE ratio FLOAT;
    DECLARE rank FLOAT;
    DECLARE nodeNum INT;
    DECLARE MainId VARCHAR(20);
    DECLARE ObjectId VARCHAR(20);
    BEGIN
    -- 每次执行时,都要删除原有记录,因为结果是通过插入的方式得到的
    DELETE FROM friend_rank WHERE TRUE;
    -- 得到整个集合的节点数,对应上文公式中的 N
    SELECT count(friend_num.id) FROM friend_num INTO nodeNum;
    -- 遍历每个节点,得到对应的概率
    FOR MainId IN SELECT friend_num.id FROM friend_num
    LOOP
    rank := 0.0;
    -- 遍历每个非自生节点,得到其它节点对当前节点的权重概率贡献并累加
    FOR ObjectId IN SELECT friend_num.id FROM friend_num
    LOOP
    IF MainId = ObjectId OR ObjectId NOT IN (SELECT friend_id FROM friend WHERE self_id = MainId) THEN
    rank := rank + 0.0;
    ELSE
    SELECT friend_num.rate FROM friend_num WHERE id = ObjectId INTO ratio;
    rank := rank + ratio * round(1::numeric / nodeNum::numeric, 4) * conversionFactor +
    round((1 - conversionFactor)::numeric / nodeNum::numeric, 4);
    end if;
    end loop;
    INSERT INTO friend_rank VALUES (MainId, rank);
    end loop;
    END;
    $$ LANGUAGE plpgsql;
  • 执行查询

    -- 首先,调用 PageRank 函数更新结果向量
    SELECT PageRank(); -- 连接用户表,得到相关的排名信息
    SELECT vk_user.id, first_name, last_name, friend_rank.rank FROM vk_user JOIN friend_rank ON vk_user.id = friend_rank.id ORDER BY rank DESC;

    ​ 最终得到如下查询结果:

    ​ 与日常生活的情况相结合,结合实际情况,确实是这个人更加 ”权威“ 一些。由此可见,PageRank 的效果还是相当不错的。

    ​ 如果你也有自己的交际圈,你也可以用这个算法试一试,没准能带给你一些不一样的体验!

使用 PostgreSQL 实现 PageRank的更多相关文章

  1. postgresql 基本语法

    postgresql数据库创建/修改/删除等写入类代码语法总结: 1,创建库 2,创建/删除表 2.1 创建表 create table myTableName 2.2 如果表不存在则创建表 crea ...

  2. postgresql无法安装pldbgapi的问题

    要对函数进行调试需要安装插件pldbgapi,当初在windows上面的postgresql实例中执行了一下语句就安装上了: create extension pldbgapi; 但是在linux中执 ...

  3. ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库

    前段时间在园子里看到了小蝶惊鸿 发布的有关绿色版的Linux.NET——“Jws.Mono”.由于我对.Net程序跑在Linux上非常感兴趣,自己也看了一些有关mono的资料,但是一直没有时间抽出时间 ...

  4. MongoDB与PostgresQL无责任初步测试

    PostgresQL一秒能插入多少条记录,MongoDB呢?读取的情况又如何?我写了一些简单的程序,得出了一些简单的数据,贴在这里分享,继续往下阅读前请注意下本文标题中的“无责任”,这表示此测试结果不 ...

  5. [PostgreSQL] 图解安装 PostgreSQL

    图解安装 PostgreSQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5894462.html 序 园友的一篇<Asp.Net Cor ...

  6. 【十大经典数据挖掘算法】PageRank

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 我特地把PageRank作为[十大经 ...

  7. Asp.Net Core 项目实战之权限管理系统(3) 通过EntityFramework Core使用PostgreSQL

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  8. PostgreSQL介绍以及如何开发框架中使用PostgreSQL数据库

    最近准备下PostgreSQL数据库开发的相关知识,本文把总结的PPT内容通过博客记录分享,本随笔的主要内容是介绍PostgreSQL数据库的基础信息,以及如何在我们的开发框架中使用PostgreSQ ...

  9. PostgreSql性能测试

    # PostgreSql性能测试 ## 1. 环境+ 版本:9.4.9+ 系统:OS X 10.11.5+ CPU:Core i5 2.7G+ 内存:16G+ 硬盘:256G SSD ## 2. 测试 ...

  10. postgresql 导出数据字典文档

    项目上需要整理目前数据库的数据字典文档.项目不规范,这种文档只要后期来补.这么多张表,每个字段都写到word文档里真心头大.就算前面写了个查询表结构的sql,但是最后整理到word里还是感觉有点麻烦. ...

随机推荐

  1. c语言代码练习14

    //设计一个猜数字游戏,需要提示猜大了还是小了,直到猜对为止 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include & ...

  2. 一种对数据库友好的GUID的变种使用方法

    概述 .NET生成的GUID唯一性很好,用之方便,但是,缺少像雪花算法那样的有序性.虽然分布式系统中做不到绝对的有序,但是,相对的有序对于目前数据库而言,索引效率等方面的提升还是有明显效果的(当然,我 ...

  3. 如何提高redux开发效率?当然是redux-tookit啦!

    前言 使用react-redux的朋友都经历过这种痛苦吧? 定义一个store仓库,首先创建各种文件,比如reducer.action.store...,然后 将redux和react连接使用.整个流 ...

  4. 从一次Kafka宕机说起(JVM hang)

    一.背景 时间大概是在夏天7月份,突然收到小伙伴的情报,我们线上的一个kafka实例的某个broker突然不提供服务了,也没看到什么异常日志,反正就是生产.消费都停了.因为是线上服务,而且进程还在,就 ...

  5. AI图形算法的应用之一:通过图片模板对比发现油田漏油

    最近研究了一下OPENCV的图像算法,开发了一个小应用. 可以通过图像和模板进行对比,发现油田或其他作业区漏油. 直接上效果,模板如下 自己模拟了一个漏油的现场图片,如下 通过图形化算法,找到漏油点, ...

  6. PTA1030完美数列二分法解决超时

    #include"bits/stdc++.h" using namespace std; const int N=100010; long long ans,n,p; long l ...

  7. synchronized 解决方案

    4.2 synchronized 解决方案 为了避免临界区的竞态条件发生,有多种手段可以达到目的. 阻塞式的解决方案:synchronized,Lock 非阻塞式的解决方案:原子变量 本次课使用阻塞式 ...

  8. Vivado生成bitstream时报错[Opt 31-67] Problem: A LUT3 cell in the design is missing a connection on input pin I1, which is used by the LUT equation

    这个原因主要是因为有一个引脚没有用到,解决方法. 1.打开Schematic. 2.根据提示的模块去找,比如说我的报错. [Opt 31-67] Problem: A LUT3 cell in the ...

  9. ubuntu20 安装 mysql5.7.31 , 卸载mysql 8.0, Mysql只能本地登录,无法远程登录

    ubuntu 18 可以直接命令安装:# 安装mysql服务sudo apt-get install mysql-server# 安装客户端sudo apt install mysql-client# ...

  10. 小满OKKICRM与金蝶云星空对接集成客户资料

    小满OKKICRM与金蝶云星空对接集成客户列表查询(更新列表)&客户新增(小满客户对接金蝶客户-P) 数据源平台:小满OKKICRM 小满科技成立于2013年,是阿里巴巴集团战略投资的高新技术 ...