educoder中Spark GraphX—预测社交圈子

文章展示了三个使用ApacheSpark的GraphX库来处理社交网络数据的示例。主要任务是计算图的连通分量,即社交圈子。在第一部分,直接创建了一个简单的图并计算了连通分量。第二部分读取特定的egonet文件,构造边数据并进行相同的操作。第三部分处理多个egonet文件,提取用户ID,构建图并预测社交圈子。所有代码都在本地模式下运行。
摘要由CSDN通过智能技术生成

第1关:计算连通分量

import org.apache.log4j.{Level, Logger}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.graphx._
object connectComponents{
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("connectComponents ").setMaster("local[4]")
    val sc = new SparkContext(conf) //屏蔽日志
    Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
    Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF)
    //**************Begin*************************
    //构造VertexRDD
    val myVertices = sc.parallelize((1L to 8L).map((_,"")))
    //构造EdgeRDD
    val myEdges = sc.parallelize(Array(Edge(1L,2L,""),Edge(4L,5L,""),Edge(4L,6L,""),Edge(5L,6L,""),Edge(5L,7L,""),Edge(7L,6L,"")))
    //构造图Graph[VD,ED]
    val myGraph=Graph(myVertices,myEdges)
    //计算连通分量
    val connectedcomponents = myGraph.connectedComponents.vertices.map(_.swap).groupByKey.map(_._2).collect
    println("")
    //输出结果
    connectedcomponents.foreach(println)
    //**************End**************************
  }
}

第2关:社交圈子预测1

import org.apache.log4j.{Level, Logger}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.graphx._
object predict1_s{
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("predict1_s").setMaster("local[4]")
    val sc = new SparkContext(conf) //屏蔽日志
    Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
    Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF)
    // 处理egonet文件的每行数据,返回元组形式的边数据
    def get_edges_from_line(line: String): Array[(Long, Long)] = {
      val ary = line.split(":")
      //划分源顶点和目标顶点
      val srcId = ary(0).toInt
      //根据分隔符把字符串切分为一个数组
      val dstIds = ary(1).split(" ")
      val edges = for {
        dstId <- dstIds
        if (dstId != "")
      } yield {
        //将源顶点和目标顶点组合成元组
        (srcId.toLong, dstId.toLong)
      }
      if (edges.size > 0) edges else Array((srcId, srcId))
    }
    //读取239.egonet文件内容
    val egonet_example = sc.textFile("/root/data/egonets/239.egonet")
    //**************Begin*************************
    //根据定义的get_edges_from_line函数构造由边数据组成的Array
    val edges_array = egonet_example.map(x => get_edges_from_line(x)).collect
    //但现在是一个二维数组,需要用flatten函数转化为一维数组
    val edges = edges_array.flatten
    //构造rawEdges:RDD[(VetexId,VertexId)]
    val g_edges = sc.makeRDD(edges)
    //使用fromEdgeTuples构造图
    val g = Graph.fromEdgeTuples(g_edges,1)
    //**************End**************************
    //**************Begin*************************
    //找出图中的连通分量
    val connectedcomponents = g.connectedComponents.vertices.map(_.swap).groupByKey.map(_._2).collect
    println("")
    //输出结果
    connectedcomponents.foreach(println)
    //**************End**************************
  }
}

第3关:社交圈子预测2

import org.apache.log4j.{Level, Logger}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.graphx._
object predict2_s{
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("predict2_s").setMaster("local[4]")
    val sc = new SparkContext(conf) //屏蔽日志
    Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
    Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF)
    // 从path/userId.egonet格式的文件路径中解析出用户ID
    def extract(s: String) = {
      val Pattern = """^.*?(\d+).egonet""".r
      val Pattern(num) = s
      num
    }
    // 处理egonet文件的每行数据,返回元组形式的边数据
    def get_edges_from_line(line: String): Array[(Long, Long)] = {
      val ary = line.split(":")
      val srcId = ary(0).toInt
      val dstIds = ary(1).split(" ")
      val edges = for {
        dstId <- dstIds
        if (dstId != "")
      } yield {
        (srcId.toLong, dstId.toLong)
      }
      if (edges.size > 0) edges else Array((srcId, srcId))
    }
    // 根据文件内容构造边元组
    def make_edges(contents: String) = {
      val lines = contents.split("\n")
      // 根据get_edges_from_line构造元组类型的数组,此时unflat为二维数组
      val unflat = for {
        line <- lines
      } yield {
        get_edges_from_line(line)
      }
      //使用flatten函数降维,并返回值
      val flat = unflat.flatten
      flat
    }
    // 构建图对象,执行connectedComponents()操作,返回结果
    def get_circles(flat: Array[(Long, Long)]) = {
      val edges = sc.makeRDD(flat)
      val g = Graph.fromEdgeTuples(edges,1)
      val cc = g.connectedComponents()
      cc.vertices.map(x => (x._2, Array(x._1))).
        reduceByKey( (a,b) => a ++ b).
        values.map(_.mkString(" ")).collect.mkString(";")
    }
    //读取目录内容
    val egonets = sc.wholeTextFiles("/root/data/egonets")
    //**************Begin*************************
    //获取用户ID
    val egonet_numbers = egonets.map(x => extract(x._1)).collect
    //构造边元组
    val egonet_edges = egonets.map(x => make_edges(x._2)).collect
    //根据get_circles函数构造图,并计算连通分量
    val egonet_circles = egonet_edges.toList.map(x => get_circles(x))
    //**************End**************************
    //**************Begin*************************
    //将用户ID与预测的社交圈子组合,需要使用zip函数
    val result = egonet_numbers.zip(egonet_circles).map(x => x._1 + "," + x._2)
    println("")
    println("UserId,Predicted social circles(Every social circle is used ';' separated.)")
    //换行输出最终结果
    println(result.mkString("\n"))
    //**************End**************************
  }
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小施没烦恼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值