You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于GraphX从二分网络构建加权演员单分图的技术求助

从电影-演员二分图转换为演员加权单分图

刚上手Spark、Scala和GraphX的话,从电影-演员二分图转成演员间的加权单分图确实需要几个关键步骤,我来帮你拆解清楚,一步步实现:

首先要注意,你当前的代码没有过滤表头行(示例里的movie actor),导致生成了一条无效的Edge(1,1,null),所以第一步先修正数据读取:

1. 读取并清洗原始数据

先过滤掉表头,把数据转换成(电影ID, 演员ID)的键值对RDD:

import org.apache.spark.graphx.{Edge, Graph}

// 读取文件,过滤表头行,生成(movieId, actorId)的RDD
val movieActorPairs = sc.textFile("file:///home/actorMovie")
  .filter(line => !line.startsWith("movie")) // 跳过表头
  .map(line => {
    val fields = line.split(" ")
    (fields(0).toLong, fields(1).toLong)
  })

2. 按电影分组生成演员列表

接下来,把同一个电影的所有演员聚合到一起,这样我们就能找到每部电影里的演员组合:

// 按电影ID分组,得到每个电影对应的所有演员ID集合
val movieActors = movieActorPairs.groupByKey()

3. 生成演员两两组合

对每部电影的演员列表,生成所有无序的演员对(比如演员A和B,只生成一次(A,B)而不是(A,B)和(B,A)),避免后续重复统计:

// 遍历每个电影的演员列表,生成i<j的演员对
val actorPairs = movieActors.flatMap { case (_, actors) =>
  val actorList = actors.toList
  // 双重循环生成所有不重复的演员对
  for {
    i <- actorList.indices
    j <- i + 1 until actorList.size
  } yield {
    val (a1, a2) = (actorList(i), actorList(j))
    // 保证对的顺序统一,避免(A,B)和(B,A)被当成不同的对
    if (a1 < a2) (a1, a2) else (a2, a1)
  }
}

4. 统计共同参演次数(边的权重)

现在每对演员每共同参演一部电影就会出现一次,我们只需要统计每对的出现次数,这个次数就是边的权重:

// 统计每对演员的共同参演电影数
val weightedActorPairs = actorPairs
  .map(pair => (pair, 1)) // 给每个对标记计数1
  .reduceByKey(_ + _) // 按对聚合,累加计数

5. 构建演员加权单分图

最后把统计后的结果转换成GraphX的Edge结构,构建单分图:

// 转换为GraphX的Edge,权重是共同参演次数
val actorEdges = weightedActorPairs.map { case ((srcId, dstId), weight) =>
  Edge(srcId, dstId, weight)
}

// 构建演员单分图,defaultValue是顶点的默认属性(可以根据需求修改,比如演员名字等)
val actorGraph = Graph.fromEdges(actorEdges, defaultValue = 0)

验证结果

你可以通过以下代码查看生成的边:

actorEdges.collect().foreach(println)

针对你的示例数据,输出应该类似:

Edge(1,2,1)
Edge(1,3,1)
Edge(1,4,1)
Edge(1,5,1)
Edge(1,6,1)
Edge(1,7,1)
Edge(3,4,1)
Edge(3,5,1)
...

比如Edge(1,2,1)表示演员1和2共同参演了1部电影(就是电影2),完全符合你的需求。

内容的提问来源于stack exchange,提问作者Neil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:37:07