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

Posted

技术标签:

【中文标题】带约束的二部网络保度随机化【英文标题】:bipartite network Degree-preserving randomization with constraints 【发布时间】:2021-04-04 12:45:56 【问题描述】:

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

paper_id topic 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 topic 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 年的主题 0, 1998],[1995] 中的主题 2,[1991,1992] 中的主题 3 和 [1993,1997] 中的主题 4。但是在第二个表中,2246118404论文的改版发表年份是1998年,因为这篇论文是关于主题3的,所以年份只能是1991年或1992年。所以我需要指定改版时的约束条件。

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

example network

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

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

【问题讨论】:

目前还不清楚您要做什么。能否提供一个简单的随机化前后数据示例? @MichaelRovinsky 谢谢你的提问。我已经编辑了这个问题。在第一个表中,您可以看到原始数据的示例。在第二个表中,它是随机化后的数据。前两列保持不变,只有第三列(pub_year)被重新洗牌。 【参考方案1】:

一个简单的脚本来做 yaer 洗牌:

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, "year": 1995,
    "paper_id": 2246118404, "topic": 3, "year": 1992,
    "paper_id": 2017547909, "topic": 1, "year": 1996,
    "paper_id": 2032449907, "topic": 4, "year": 1993,
    "paper_id": 2053684599, "topic": 0, "year": 1991,
    "paper_id": 1968369145, "topic": 1, "year": 1997,
    "paper_id": 2160198778, "topic": 4, "year": 1997,
    "paper_id": 2026639487, "topic": 3, "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)

【讨论】:

感谢您的回答。我还想保持每年发表的论文数量不变。在我的例子中,有两篇论文发表于 1991 年,一篇发表于 1992 年,一篇发表于 1993 年等等。但在你的方法中,这并不能保证。我想一种可能性是添加一个候选年份列表,每次在“for paper in paper”迭代中,我们通过 topicRanges 过滤候选列表并随机选择一个。在循环结束时,我们从列表中删除选定的年份。你认为这行得通吗? 但是,我上面提到的可能性并不能确保我们总能找到结果,因为有时候选年份列表可能为空。 也许我错过了一些东西,但是保持每年论文数量的要求与每年随机化的想法相矛盾,每个主题都有固定的年份范围...... 其实这两个要求并不完全矛盾。考虑一个情况,主题 1 在一年范围内 [1991,2000],主题 2 在一年范围内 [1995,2003]。针对这两个要求的随机化使 1991 年至 1994 年发表的关于主题 1 的论文保持不变,2001 年至 2003 年发表的关于主题 2 的论文保持不变。并且改组只适用于 1995 年至 2000 年之间发表的论文(即两个年份范围的交集)。

以上是关于带约束的二部网络保度随机化的主要内容,如果未能解决你的问题,请参考以下文章

使用或工具在约束空间中实现无偏随机化

算法:随机化亮度和对比度值,有约束

第六章:随机化

所以我试图建立一个光子网络连接,玩家随机生成,但遇到了这个错误。 “实例化”没有过载

随机化非常大文件内容的顺序的有效方法是啥?

试图随机化一个数组,但每次都保持相同的随机化[重复]