从数据集

时间:2016-12-08 21:27:21

标签: r feature-extraction

目前我正致力于从具有给定结构的数据集中实现“关系提取”功能:

Name1  Name2
Bob    Tom
Mike   Bob
Denise John
Kate   Bob
John   Kate
Mike   Tom
Mark   Denise
Denise Kate
Tom    John

两列都是“字符”类型,基本上数据集包含具有“Name1”的用户知道具有“Name2”(对称关系)的用户的信息。 我想要做的是找到“每个人都认识所有人”的用户群(我不确定他们是如何用英语调用的,我的讲师称他们为“超级团体”)。该函数的输出应包含提取的组列表​​和每个组的成员列表。因此,对于上面的示例数据集,它将是(当组具有3个或更多成员时,组被视为“有效”):

Group 1: Bob Tom Mike
Group 2: Denise John Kate

格式真的无关紧要,它只需要包含那种信息。现在,我实际上实现了有效的功能,但是执行时间非常长(对于大约需要大约9小时的约550 000行的数据集) - 我所做的基本上是为每个关系创建朋友的子集,所以对于关系Bob - Tom来自示例数据看起来像这样:

Subset 1:
Name1  Name2
Bob Mike
Bob Kate

Subset 2:
Name1  Name2
Tom Mike
Tom John

然后我检查了来自第一个子集的列“Name2”的用户是否出现在第二个子集中的相同列中...我知道这个方法远非最佳状态我执行这么长时间并不感到惊讶那个功能。我想知道是否有人可以提出更好的解决方案来解决这个问题(我甚至不需要代码,只是链接到一些算法或解释如何以最佳方式进行这种“组提取”)。

3 个答案:

答案 0 :(得分:0)

正如弗兰克评论的那样,你正在描述一个典型的图论问题。

图表是一个结构,其中包含节点(在您的情况下是人)和其中一些节点之间的边缘(在您的情况下是友谊关系)。

事实上,对于"超级组"您正在寻找:每个节点连接到该子集中每个其他节点的节点子集称为 clique 完全连接的子图Wikipedia特别是你似乎对所有基数为3或更高的派系感兴趣。

好消息是找到所有派系是图论中的一个众所周知的问题(Clique Problem),并且存在包中的实现(见下文)。坏消息是它已知是NP完全的。因此,根据大小和拓扑图,即使是最佳实现也可能需要相当长的时间。上面的文章提供了一些有关这方面的进一步信息。

R中的igraph包提供了cliques函数,一旦您将数据作为图形结构加载,它就会为您找到这些集团。在您的情况下,您有一个现有关系列表,我建议您查看该包中的graph_from_edgelist函数。

答案 1 :(得分:0)

你所描述的内容听起来像是图论中的派系。首先,我们加载您的样本数据

dd <- read.table(text="Name1  Name2
Bob    Tom
Mike   Bob
Denise John
Kate   Bob
John   Kate
Mike   Tom
Mark   Denise
Denise Kate
Tom    John", header=T)

然后将其转换为正确的图表

gg <- graph_from_data_frame(dd, directed=F)
plot(gg)

enter image description here

然后你可以找到至少有三个成员的cliquies

cliques(gg, min=3)
# [[1]]
# + 3/7 vertices, named:
# [1] Bob  Mike Tom 
# 
# [[2]]
# + 3/7 vertices, named:
# [1] Denise Kate   John  

答案 2 :(得分:0)

计算内聚块可以为您提供一些见解:

library(igraph)
camp <- graph_from_literal(Bob -Tom,
                           Mike -Bob,
                           Denise -John,
                           Kate - Bob,
                           John - Kate,
                           Mike - Tom,
                           Mark - Denise,
                           Denise - Kate,
                           Tom - John)
campBlocks <- cohesive_blocks(camp)
campBlocks
plot(campBlocks, camp, vertex.label=V(camp)$name, margin=-0.2,
     vertex.shape="rectangle", vertex.size=24, vertex.size2=8,
     mark.border=1, colbar=c(NA, NA,"green","orange") )

enter image description here

内聚阻塞根据结构内聚力确定图顶点的分层子集。此外,您可以使用以下内容查看所需的子图

largest_cliques(camp)

输出:

3/7 vertices, named:
[1] John   Denise Kate  

[[2]]
  3/7 vertices, named:
[1] Bob  Tom  Mike