【问题标题】:Better approach to build graph from list clustering related items by two properties通过两个属性从列表聚类相关项目构建图形的更好方法
【发布时间】:2013-07-06 19:27:01
【问题描述】:

我有一个歌曲列表。对于每首歌曲,我都有艺术家、作家和流派。

我想创建一个有向图,以便查找模式。

所以,我想为每个艺术家都有一个节点,所以我将从基于艺术家对歌曲进行聚类开始。

那我也想找作曲家,把已经聚集的歌曲整理好,让它们离作曲家更近。

稍后我也会根据流派进行分组,但我停留在前两个。

所以,我的第一种方法是只做类似(未测试):

pos_x = 20
for x in songs:
    pos_y = 20
    artist_list = [s for s in songs if s.artist==x.artist]
    for y in len(artist_list):
        artist_list[y].x = pos_x
        pos_x += 10 * len(artist_list[y].title)
        artist_list[y].y = pos_y
        pos_y += 10

然后我会遍历艺术家列表,创建初始图表,但是当多个艺术家在一首歌曲上时会出现问题,例如 We are the world

但是,我相信在 Python 中这是一个非常有缺陷的方法,因为我的下一个方法是获取歌曲,使它们与艺术家相对接近,但循环获取作曲家并对要放入的组进行小改动那些相关联的很近,所以艺术家的歌曲集群可能会被移动。

我正在使用pyglet 来执行此操作,所以基本上我在 OpenGL 中执行此操作。

我可以做的实际定位,但这是我关心的方法,因为我被困在如何解决这个问题上。

更新

我正在寻找的是这样的:

   Song A1          Song A3       Song A2         

                      Artist A     
                                  Artist B

   Song B1                      Song B2

我会有从 A1、A2、A3 到艺术家 A 的线条,以及从 B1、B2 到艺术家 B 的线条,但 A3 和 B1、B2 连接到艺术家 B,但我也希望艺术家 B 的位置更靠近 A2和 B2,因为这两首歌的作曲家是一样的。

因此,艺术家将是一个新节点,与歌曲分开,但歌曲在每个集群中的实际位置将取决于至少一个其他关系。稍后我可能最终也会展示这种关系,这就是我现在在 3D 中映射的原因。

【问题讨论】:

    标签: python-2.7 graph


    【解决方案1】:

    我将采用的方法是在 Python 中生成一个有向图,可以将其写入“点”格式并由 Graphviz (http://www.graphviz.org) 呈现。 Graphviz 和点格式是定义和渲染复杂图形的既定工具。

    好消息是,有 Python 库允许您以 Python 方式定义图形,然后用一行代码写出点文件。 PyGraphviz 看起来是个不错的选择:http://networkx.lanl.gov/pygraphviz。您可以在 Python 中创建图的结构,这就像定义歌曲和艺术家之间、歌曲和作曲家之间的边一样简单,等等。这是 PyGraphviz 教程中的一个 sn-p:

    >>> G.add_node('a') # adds node 'a'
    >>> G.add_edge('b','c') # adds edge 'b'-'c' (and also nodes 'b', 'c')
    

    然后只需编写点文件并将其加载到 Graphviz 中,它将在 2d 空间中布置节点。有多种布局算法,因此您可以试验它们以便以最有用的方式对歌曲进行聚类。

    【讨论】:

    • 我目前在 opengl 而不是 dot 中做,因为我不确定项目的去向,所以我正在制作原型,我可能最终需要以 3D 显示,而且更容易从 OpenGL -> dot 如果我认为这可行,然后说服其他人为我付出代价从 dot 到 OpenGL。我的问题是进行聚类和放置的更好方法,而不是使用 for 循环。
    • 如果我正确理解了这个问题,困难的部分是以最尊重集群的方式在空间中布置节点,对吧?这是一个难题,Graphviz 实现了布局算法来做到这一点。您可以使用 PyGraphviz(或者 NetworkX,参见 this discussion)生成每个节点的坐标(G.layout()),而无需实际生成 PDF 文件,然后您可以使用这些坐标随 OpenGL 进行绘制。
    • 我会看看这些。谢谢你。是的,由于聚类而弄清楚如何布置它们是一个挑战,因为我最终可能需要考虑其他属性并做不止一次,但如果我可以为两个属性做这件事,那么做 3 或四个不会更具挑战性。
    • 我仍然有同样的问题,如果我使用 NetworkX,我需要根据我所看到的来确定它们应该如何放置。
    • 您应该只需要定义节点之间的连接,布局算法应该为您提供位置。看看this simple example——作者只是定义了哪些节点相互连接,调用spring_layout计算节点位置,然后绘制这些位置。
    猜你喜欢
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多