链路预测算法MATLAB实现

链路预测算法MATLAB实现

链路预测是复杂网络分析中的重要任务,旨在预测网络中尚未连接的两个节点之间未来产生连接的可能性。

程序概述

MATLAB程序实现了以下链路预测算法:

  1. 基于局部信息的相似性指标(Common Neighbors, Jaccard, Adamic-Adar等)
  2. 基于路径的相似性指标(Katz指数)
  3. 基于随机游走的相似性指标(Rooted PageRank, SimRank)
  4. 矩阵分解方法

代码

classdef LinkPrediction%LINKPREDICTION 链路预测算法实现%   包含多种链路预测算法propertiesA;          % 邻接矩阵train_mask; % 训练掩码矩阵test_mask;  % 测试掩码矩阵methods;    % 可用的预测方法endmethodsfunction obj = LinkPrediction(adj_matrix, train_ratio)%LINKPREDICTION 构造函数%   adj_matrix - 网络邻接矩阵%   train_ratio - 训练集比例(0-1)obj.A = adj_matrix;obj.methods = {'CommonNeighbors', 'Jaccard', 'AdamicAdar', ...'PreferentialAttachment', 'Katz', 'RootedPageRank', ...'SimRank', 'MatrixFactorization'};% 划分训练集和测试集if nargin > 1obj = obj.split_dataset(train_ratio);elseobj.train_mask = ones(size(obj.A));obj.test_mask = zeros(size(obj.A));endendfunction obj = split_dataset(obj, train_ratio)%SPLIT_DATASET 划分训练集和测试集%   随机隐藏一部分边作为测试集[n, ~] = size(obj.A);obj.train_mask = ones(n);obj.test_mask = zeros(n);% 获取所有边的索引[rows, cols] = find(triu(obj.A, 1)); % 只取上三角避免重复num_edges = length(rows);num_train = round(num_edges * train_ratio);% 随机选择训练边idx = randperm(num_edges);train_idx = idx(1:num_train);test_idx = idx(num_train+1:end);% 创建掩码矩阵for i = 1:length(test_idx)r = rows(test_idx(i));c = cols(test_idx(i));obj.train_mask(r, c) = 0;obj.train_mask(c, r) = 0;obj.test_mask(r, c) = 1;obj.test_mask(c, r) = 1;end% 确保对角线为0obj.train_mask(1:n+1:end) = 0;obj.test_mask(1:n+1:end) = 0;endfunction scores = common_neighbors(obj)%COMMON_NEIGHBORS 共同邻居算法scores = (obj.A * obj.A) .* obj.train_mask;endfunction scores = jaccard(obj)%JACCARD Jaccard相似系数[n, ~] = size(obj.A);scores = zeros(n);for i = 1:nfor j = i+1:nif obj.train_mask(i, j) == 0continue;endneighbors_i = find(obj.A(i, :));neighbors_j = find(obj.A(j, :));intersection = length(intersect(neighbors_i, neighbors_j));union = length(union(neighbors_i, neighbors_j));if union > 0scores(i, j) = intersection / union;elsescores(i, j) = 0;endscores(j, i) = scores(i, j);endendendfunction scores = adamic_adar(obj)%ADAMIC_ADAR Adamic-Adar指数[n, ~] = size(obj.A);scores = zeros(n);% 计算每个节点的度degrees = sum(obj.A, 2);for i = 1:nfor j = i+1:nif obj.train_mask(i, j) == 0continue;endcommon_neighbors = find(obj.A(i, :) & obj.A(j, :));score = 0;for k = common_neighborsif degrees(k) > 1 % 避免除以0score = score + 1 / log(degrees(k));endendscores(i, j) = score;scores(j, i) = score;endendendfunction scores = preferential_attachment(obj)%PREFERENTIAL_ATTACHMENT 优先连接算法degrees = sum(obj.A, 2);scores = (degrees * degrees') .* obj.train_mask;endfunction scores = katz(obj, beta)%KATZ Katz指数%   beta - 衰减因子,默认0.01if nargin < 2beta = 0.01;end[n, ~] = size(obj.A);I = eye(n);scores = beta * obj.A; % 长度为1的路径% 计算Katz指数:S = βA + β²A² + β³A³ + ...% 使用矩阵求逆近似:S = (I - βA)^-1 - Iscores = inv(I - beta * obj.A) - I;scores = scores .* obj.train_mask;endfunction scores = rooted_pagerank(obj, alpha, max_iter, tol)%ROOTED_PAGERANK Rooted PageRank算法%   alpha - 随机游走概率,默认0.85%   max_iter - 最大迭代次数,默认100%   tol - 收敛容差,默认1e-6if nargin < 2alpha = 0.85;endif nargin < 3max_iter = 100;endif nargin < 4tol = 1e-6;end[n, ~] = size(obj.A);scores = zeros(n);% 创建列随机矩阵(转移概率矩阵)P = obj.A ./ sum(obj.A, 1);P(isnan(P)) = 0; % 处理度为0的节点% 对每个节点计算Rooted PageRankfor i = 1:nr = zeros(n, 1);r(i) = 1;for iter = 1:max_iterr_new = alpha * P * r + (1 - alpha) * r;if norm(r_new - r, 1) < tolbreak;endr = r_new;endscores(:, i) = r;endscores = scores .* obj.train_mask;endfunction scores = simrank(obj, C, max_iter, tol)%SIMRANK SimRank算法%   C - 衰减因子,默认0.8%   max_iter - 最大迭代次数,默认10%   tol - 收敛容差,默认1e-4if nargin < 2C = 0.8;endif nargin < 3max_iter = 10;endif nargin < 4tol = 1e-4;end[n, ~] = size(obj.A);S = eye(n); % 初始化SimRank矩阵% 计算入邻居in_neighbors = cell(n, 1);for i = 1:nin_neighbors{i} = find(obj.A(:, i));end% 迭代计算SimRankfor iter = 1:max_iterS_old = S;for i = 1:nfor j = 1:nif i == jS(i, j) = 1;continue;endin_i = in_neighbors{i};in_j = in_neighbors{j};if isempty(in_i) || isempty(in_j)S(i, j) = 0;continue;endsum_sim = 0;for a = 1:length(in_i)for b = 1:length(in_j)sum_sim = sum_sim + S_old(in_i(a), in_j(b));endendS(i, j) = C * sum_sim / (length(in_i) * length(in_j));endendif norm(S - S_old, 'fro') < tolbreak;endendscores = S .* obj.train_mask;endfunction scores = matrix_factorization(obj, dim, lambda, max_iter, learning_rate)%MATRIX_FACTORIZATION 矩阵分解方法%   dim - 潜在特征维度,默认10%   lambda - 正则化参数,默认0.01%   max_iter - 最大迭代次数,默认100%   learning_rate - 学习率,默认0.01if nargin < 2dim = 10;endif nargin < 3lambda = 0.01;endif nargin < 4max_iter = 100;endif nargin < 5learning_rate = 0.01;end[n, ~] = size(obj.A);% 初始化用户和物品特征矩阵U = randn(n, dim) * 0.01;V = randn(n, dim) * 0.01;% 获取训练集中的非零元素(即存在的边)[rows, cols] = find(obj.train_mask);values = ones(length(rows), 1);% 随机梯度下降for iter = 1:max_itertotal_error = 0;for idx = 1:length(rows)i = rows(idx);j = cols(idx);% 计算预测值和误差prediction = U(i, :) * V(j, :)';error = values(idx) - prediction;total_error = total_error + error^2;% 更新特征向量U_i_old = U(i, :);U(i, :) = U(i, :) + learning_rate * (error * V(j, :) - lambda * U(i, :));V(j, :) = V(j, :) + learning_rate * (error * U_i_old - lambda * V(j, :));end% 添加正则化项total_error = total_error + lambda * (norm(U, 'fro')^2 + norm(V, 'fro')^2);if mod(iter, 10) == 0fprintf('迭代 %d, 误差: %.4f\n', iter, total_error);endend% 计算得分矩阵scores = U * V';scores = scores .* obj.train_mask;endfunction [precision, recall, auc] = evaluate(obj, scores, top_k)%EVALUATE 评估预测结果%   scores - 预测得分矩阵%   top_k - 计算precision@k和recall@k的k值if nargin < 3top_k = 100;end% 获取测试集中的正样本[test_rows, test_cols] = find(obj.test_mask);positive_pairs = [test_rows, test_cols];num_positives = size(positive_pairs, 1);% 获取所有未连接的节点对(负样本+测试正样本)negative_mask = (obj.train_mask == 0) & (obj.A == 0) & (eye(size(obj.A)) == 0);[negative_rows, negative_cols] = find(negative_mask);negative_pairs = [negative_rows, negative_cols];% 随机选择与正样本数量相同的负样本idx = randperm(size(negative_pairs, 1), num_positives);negative_pairs = negative_pairs(idx, :);% 合并正负样本all_pairs = [positive_pairs; negative_pairs];labels = [ones(num_positives, 1); zeros(num_positives, 1)];% 获取预测得分pred_scores = zeros(size(all_pairs, 1), 1);for i = 1:size(all_pairs, 1)pred_scores(i) = scores(all_pairs(i, 1), all_pairs(i, 2));end% 计算AUC[~, ~, ~, auc] = perfcurve(labels, pred_scores, 1);% 计算Precision@K和Recall@K% 获取得分最高的top_k个节点对[~, sorted_idx] = sort(pred_scores(1:num_positives), 'descend');top_predictions = sorted_idx(1:min(top_k, length(sorted_idx)));true_positives = sum(ismember(top_predictions, 1:num_positives));precision = true_positives / top_k;recall = true_positives / num_positives;endfunction results = compare_methods(obj, methods, top_k)%COMPARE_METHODS 比较不同算法的性能%   methods - 要比较的方法列表%   top_k - 计算precision@k和recall@k的k值if nargin < 2methods = obj.methods;endif nargin < 3top_k = 100;endresults = struct();for i = 1:length(methods)method = methods{i};fprintf('正在计算 %s...\n', method);try% 调用相应的方法tic;scores = obj.(lower(method))();time = toc;% 评估性能[precision, recall, auc] = obj.evaluate(scores, top_k);% 保存结果results.(method).scores = scores;results.(method).precision = precision;results.(method).recall = recall;results.(method).auc = auc;results.(method).time = time;fprintf('%s: Precision@%d=%.4f, Recall@%d=%.4f, AUC=%.4f, 时间=%.2fs\n', ...method, top_k, precision, top_k, recall, auc, time);catch MEfprintf('计算 %s 时出错: %s\n', method, ME.message);results.(method).error = ME.message;endendendfunction plot_results(obj, results)%PLOT_RESULTS 可视化比较结果methods = fieldnames(results);num_methods = length(methods);precisions = zeros(num_methods, 1);recalls = zeros(num_methods, 1);aucs = zeros(num_methods, 1);times = zeros(num_methods, 1);for i = 1:num_methodsif isfield(results.(methods{i}), 'error')continue;endprecisions(i) = results.(methods{i}).precision;recalls(i) = results.(methods{i}).recall;aucs(i) = results.(methods{i}).auc;times(i) = results.(methods{i}).time;end% 创建图形figure('Position', [100, 100, 1200, 800]);% 绘制精确度subplot(2, 2, 1);bar(precisions);set(gca, 'XTickLabel', methods, 'XTickLabelRotation', 45);title('Precision@K');ylabel('Precision');grid on;% 绘制召回率subplot(2, 2, 2);bar(recalls);set(gca, 'XTickLabel', methods, 'XTickLabelRotation', 45);title('Recall@K');ylabel('Recall');grid on;% 绘制AUCsubplot(2, 2, 3);bar(aucs);set(gca, 'XTickLabel', methods, 'XTickLabelRotation', 45);title('AUC');ylabel('AUC');grid on;% 绘制运行时间subplot(2, 2, 4);bar(times);set(gca, 'XTickLabel', methods, 'XTickLabelRotation', 45);title('运行时间');ylabel('时间 (秒)');grid on;% 调整布局set(gcf, 'Color', 'w');endend
end% 示例使用代码
function example_usage()% 生成示例网络(无标度网络)n = 100; % 节点数量A = create_scale_free_network(n);% 创建链路预测对象,使用80%的边作为训练集lp = LinkPrediction(A, 0.8);% 比较所有方法的性能results = lp.compare_methods();% 可视化结果lp.plot_results(results);% 单独使用某个方法scores = lp.common_neighbors();[precision, recall, auc] = lp.evaluate(scores);fprintf('\nCommon Neighbors: Precision=%.4f, Recall=%.4f, AUC=%.4f\n', precision, recall, auc);
endfunction A = create_scale_free_network(n)%CREATE_SCALE_FREE_NETWORK 生成无标度网络(Barabási-Albert模型)%   n - 网络节点数% 初始完全图m0 = 5; % 初始节点数A = zeros(n);A(1:m0, 1:m0) = ones(m0) - eye(m0);% 添加新节点for i = m0+1:n% 计算现有节点的度degrees = sum(A(1:i-1, 1:i-1), 2);total_degree = sum(degrees);% 根据度分布选择连接节点if total_degree > 0prob = degrees / total_degree;targets = randsample(1:i-1, m0, true, prob);elsetargets = randperm(i-1, min(m0, i-1));end% 添加连接for j = targetsA(i, j) = 1;A(j, i) = 1;endend
end% 运行示例
example_usage();

说明

这个MATLAB链路预测程序提供了以下功能:

1. 核心类 LinkPrediction

包含多种链路预测算法的实现,以及评估和比较功能。

2. 实现的算法

  1. Common Neighbors (共同邻居):基于两个节点共同邻居的数量
  2. Jaccard Coefficient:共同邻居数除以总邻居数
  3. Adamic-Adar:考虑共同邻居的度,度越小权重越大
  4. Preferential Attachment:基于两个节点的度乘积
  5. Katz Index:考虑所有路径,路径越短权重越大
  6. Rooted PageRank:基于随机游走的相似性度量
  7. SimRank:基于结构上下文的相似性度量
  8. Matrix Factorization:基于矩阵分解的潜在特征方法

3. 评估指标

  • Precision@K:前K个预测中正确预测的比例
  • Recall@K:正确预测的正样本占所有正样本的比例
  • AUC:ROC曲线下面积,衡量分类器整体性能

4. 可视化功能

提供四种评估指标的可视化比较,便于分析不同算法的性能。

推荐代码 链路预测程序,主程序,包含31个链路预测的函数代码 www.youwenfan.com/contentcsg/52463.html

使用

程序最后提供了一个示例使用代码:

  1. 生成一个无标度网络(Barabási-Albert模型)
  2. 创建链路预测对象,划分训练集和测试集
  3. 比较所有算法的性能
  4. 可视化比较结果
  5. 单独使用Common Neighbors算法并进行评估

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/922086.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/922086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

淘宝商品详情 API 的安全强化与生态协同创新路径

一、安全强化&#xff1a;从 “被动防御” 到 “主动免疫” 的体系升级动态身份认证与权限颗粒化构建 “生物特征 设备指纹 行为基线” 的三重认证机制&#xff1a;结合用户操作习惯&#xff08;如点击间隔、滑动轨迹&#xff09;生成动态令牌&#xff0c;对高权限接口&#…

快消26届联合利华校招AI测评及第二轮线上认知能力测评SHL笔试真题及评分要求

在求职的道路上&#xff0c;联合利华作为一家全球知名企业&#xff0c;其招聘流程一直备受关注。尤其是其AI面试环节&#xff0c;更是让许多求职者既期待又紧张。本文将详细总结联合利华AI面试的规律与应对策略&#xff0c;希望能为正在准备面试的你提供一些帮助。一、联合利华…

使用Langchain生成本地rag知识库并搭载大模型

准备设备&#xff1a; 手机aidlux2.0个人版 一、下载依赖pip install langchain langchain-community faiss-cpu pypdf二、安装ollama并下载模型 curl -fsSL https://ollama.com/install.sh | sh #需要科学上网 ollama serve & #让ollama服务在后台运行安装完毕可以查看oll…

L2-【英音】地道语音语调--语调

文章目录语调英式语调四步法语调含义降调升调降升调升降语调如何正确表情达意1. 用降调的句型语调 英语里没有任何一句话具有固定节奏模式 英式语调四步法 意群划分重音核心语调&#xff08;重中之重&#xff09;语调的选择 A French burglar broke-into-a flat while the o…

计算机视觉进阶教学之图像投影(透视)变换

目录 简介 一、了解图像投影(透视)变换 一、定义与原理 二、应用场景 三、实现方法 二、案例分析 1. 辅助函数定义 1.1.cv_show 函数 1.2.order_points 函数 1.3.four_point_transform 函数 1.4.resize 函数 2. 主程序执行流程 2.1.图像缩放处理 2.2.轮廓检测 2.…

Java面试问题记录(二)

三、系统设计与问题排查1、假设你要设计一个 “秒杀系统”&#xff0c;需要考虑高并发、高可用、防超卖等问题&#xff0c;你的整体技术方案是什么&#xff1f;从前端、接口层、服务层、存储层分别说说核心设计点。秒杀系统设计设计核心&#xff1a;瞬时高并发&#xff0c;库存…

k8s部署kafka三节点集群

本来认为部署kafka很简单&#xff0c;没想到也折腾了2-3天&#xff0c;这水平没治了&#xff5e; kafka从3.4.0版本之后&#xff0c;可以不依赖zookeeper直接使用KRaft模式部署&#xff0c;也就是说部署kafka可以不安装zookeeper直接部署。 在官网上没有找到如何使用yaml文件…

在公用同一公网IP和端口的K8S环境中,不同域名实现不同访问需求的解决方案

目录 1. 访问需求 2. 解决方案 3. 具体配置 3.1 允许互联网访问的域名&#xff08;a.lmzf.com&#xff09; 3.2 需IP白名单访问的域名&#xff08;b.lmzf.com&#xff09; 3.3 关键参数说明 3.4 测试验证 1. 访问需求 在腾讯云TKE环境中&#xff0c;多个域名解析到同一…

FlinkCDC 达梦数据库实时同步

一、Flink部署 1.1、JAVA环境 vi /etc/profile export JAVA_HOME/data/flinkcdc/jdk1.8.0_181 export CLASSPATH$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar export PATH$JAVA_HOME/bin:$PATHsource /etc/profilevi ~/.bash_profileexport FLINK_HOME/data/flinkcdc/fli…

Eip开源主站EIPScanner在Linux上的调试记录(二 多生产者连接)

目录 一、背景 二、可行性验证 三、开发调试 一、背景 在一般场景下&#xff0c;只需一路IO连接&#xff0c;但稍微复杂的场景&#xff0c;就需要不同通讯周期的连接&#xff0c;这就需要有多组IO连接。 而大于一组的连接调试方法是一样的&#xff0c;因此主要解决2组连接的…

Oracle APEX 利用卡片实现翻转(方法二)

目录 0. 以 Oracle 的标准示例表 EMP 为例&#xff0c;实现卡片翻转 1. 创建卡片区域 (Cards Region) 2. 定义卡片的 HTML 结构 3. 添加 CSS 实现样式和翻转动画 4. 创建动态操作触发翻转 5. 运行效果 0. 以 Oracle 的标准示例表 EMP 为例&#xff0c;实现卡片翻转 目标如…

低代码拖拽实现与bpmn-js详解

低代码平台中的可视化拖拽功能是其核心魅力所在&#xff0c;它让构建应用变得像搭积木一样直观。下面我将为你梳理其实现原理&#xff0c;并详细介绍 vue-draggable 这个常用工具。 &#x1f9f1; 一、核心架构&#xff1a;三大区域与数据驱动 低代码编辑器界面通常分为三个核心…

【科研绘图系列】R语言绘制模型预测与数据可视化

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍 加载R包 数据下载 函数 导入数据 数据预处理 画图 总结 系统信息 介绍 本文介绍了一种利用R语言进行海洋微生物群落动态分析的方法,该方法通过构建多个统计模型来预测不同环境…

TODO的面试(dw三面、sqb二面、ks二面)

得物的前端三面&#xff08;通常是技术终面&#xff09;会深入考察你的技术深度、项目经验、解决问题的思路以及职业素养。下面我结合搜索结果&#xff0c;为你梳理一份得物前端三面的常问问题及详解&#xff0c;希望能助你一臂之力。 &#x1f9e0; 得物前端三面常问问题及详解…

开发 PHP 扩展新途径 通过 FrankenPHP 用 Go 语言编写 PHP 扩展

通过 FrankenPHP 用 Go 语言编写 PHP 扩展 在 PHPVerse 2025 大会上&#xff08;JetBrains 为纪念 PHP 语言 30 周年而组织的会议&#xff09;&#xff0c;FrankenPHP 开发者 Kvin Dunglas 做了一个开创性的宣布&#xff1a;通过 FrankenPHP&#xff0c;可以使用 Go 语言创建 …

完美解决:应用版本更新,增加字段导致 Redis 旧数据反序列化报错

完美解决&#xff1a;应用版本更新&#xff0c;增加字段导致 Redis 旧数据反序列化报错 前言 在敏捷开发和快速迭代的今天&#xff0c;我们经常需要为现有的业务模型增加新的字段。但一个看似简单的操作&#xff0c;却可能给正在稳定运行的系统埋下“地雷”。 一个典型的场景是…

66-python中的文件操作

1. 文件的编码 UTF-8 GBK GB2312 Big5 GB18030 2. 文件读取 文件操作步骤: 打开文件 读\写文件 关闭文件 open(name,mode,encoding) name:文件名字符串 “D:/haha.txt” mode: 只读、写入、追加 r:以只读方式打开 w: 只用于写 a :用于追加 encoding:编码方式 # -*- coding: utf…

FPGA实例源代码集锦:27个实战项目

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;FPGA是一种可编程逻辑器件&#xff0c;允许用户根据需求配置硬件功能。本压缩包提供27个不同的FPGA应用实例源代码&#xff0c;旨在帮助初学者深入学习FPGA设计&#xff0c;并为专业工程师提供灵感。内容涵盖了…

基于 Vue+Mapbox 的智慧矿山可视化功能的技术拆解

01、项目背景 在全球矿业加速向 “高端化、智能化、绿色化” 转型的浪潮下&#xff0c;传统矿业面临的深地开采难题、效率瓶颈与安全隐患日益凸显。 在矿业转型的迫切需求与政策、技术支撑的背景下依托 GIS 技术&#xff0c;开展了 “中国智矿” GIS 开发项目&#xff0c;旨在…

进程状态(Linux)

进程状态Linux进程状态Linux进程状态进程描述R运行状态S睡眠状态D磁盘休眠状态T停止状态t被追踪状态(调试状态)X死亡状态Z僵死状态其实大致也就可以分为三种运行&#xff0c;阻塞&#xff0c;挂起。运行状态每个cpu里都有一个运行队列&#xff0c;进程在运行队列里&#xff0c;…