带约束的二分网络度保持随机化

问题描述

我正在处理一个样本数据,其中包含多篇论文、它们所属的主题以及这些论文的发表年份,它看起来像这样:

paper_id 话题 pub_year
2031361154 0 1998
2088633475 1 1995
1987003396 2 1995
2246118404 3 1992
2017547909 1 1996
2032449907 4 1993
2053684599 0 1991
1968369145 1 1997
2160198778 4 1997
2026639487 3 1991

我正在尝试重新调整这些论文的发表年份(保持每个主题和每年发表的论文数量不变)作为空模型的准备。如果没有约束,这可以通过 np.random.permutation 来完成。改组出版年份后的示例表是这样的:

paper_id 话题 reshuffled_pub_year
2031361154 0 1998
2088633475 1 1997
1987003396 2 1995
2246118404 3 1992
2017547909 1 1996
2032449907 4 1993
2053684599 0 1991
1968369145 1 1997
2160198778 4 1995
2026639487 3 1991

但我想确保那些论文的改组年份留在相应主题的时间段内。例如,在第一个表中,主题 1 的论文仅在 1995、1996 和 1997 年发表,因此主题 1 的所有论文的改组年份都停留在 1995 年至 1997 年期间。类似地,[1991, 1998],[1995] 中的主题 2,[1991,1992] 中的主题 3 和 [1993,1997] 中的主题 4。但是在第二张表中,改组后的论文2246118404的发表年份是1998年,因为这篇论文是关于主题3的,年份只能是1991或1992,所以我需要指定改组时的约束条件。

我已经搜索了有关此的网页和论文,我认为这个问题可以建模为具有约束的二部网络保度随机化。这个二分网络中的两个节点类型是topic和pub_year,下图给出了一个示例网络:

example network

为了重新调整这个二分网络中的链接,我使用 python 在 configuration_model 中尝试了 networkx。所以我可以保证话题的度数和年数(但这和np.random.permutation没什么区别?)。但据我所知,configuration_model 不接受任何约束。在此示例中,tp1 具有到 y1 和 y2 的链接。因此,在所需的重组网络中,tp1 不能链接到 y3 和 y4。同样,(tp2,y4)、(tp3,y1/y3)、(tp4,y1/y2)之间也没有链接

我想知道我是否朝着正确的方向前进,即将此任务建模为二部网络改组问题。如果是这样,我可以使用任何工具来完成这项任务吗?

解决方法

一个简单的脚本来做 yaer shuffle:

import random

# replace it with your data
papers = [
    {"paper_id": 2031361154,"topic": 0,"year": 1998},{"paper_id": 2088633475,"topic": 1,"year": 1995},{"paper_id": 1987003396,"topic": 2,{"paper_id": 2246118404,"topic": 3,"year": 1992},{"paper_id": 2017547909,"year": 1996},{"paper_id": 2032449907,"topic": 4,"year": 1993},{"paper_id": 2053684599,"year": 1991},{"paper_id": 1968369145,"year": 1997},{"paper_id": 2160198778,{"paper_id": 2026639487,"year": 1991}
]

topicRanges = {}
for paper in papers:
    topic = paper["topic"]
    if topic in topicRanges:
        topicRanges[topic] = {
            "min": min(paper["year"],topicRanges[topic]["min"]),"max": max(paper["year"],topicRanges[topic]["max"])
        }
    else:
        topicRanges[topic] = {"min": paper["year"],"max": paper["year"]}

shuffled = []
for paper in papers:
    topic = paper["topic"]
    topicRange = topicRanges[topic]
    year = random.randint(topicRange["min"],topicRange["max"])
    shuffled.append(
        {"paper_id": paper["paper_id"],"topic": topic,"year": year})

print(shuffled)