GraphFrames分析豆瓣用戶及小組

上篇已經(jīng)介紹了通過Spark Graphx構(gòu)建圖续誉,在構(gòu)圖過程中要準(zhǔn)備一個Long類型的字段作為節(jié)點(diǎn)的VertexID朦促,而對于上篇中用到的數(shù)據(jù)集,顯然增加了工作量(將oid[String類型]轉(zhuǎn)換為Long)。
GraphFrames能夠避免這樣的操作。

GraphFrames

GraphFrames是以DataFrame為基礎(chǔ)的構(gòu)圖組件阱洪。
(GraphFrames is a package for Apache Spark which provides DataFrame-based Graphs. )
它的目標(biāo)是保留GraphX功能的同時充分利用Spark DataFrames的優(yōu)勢來擴(kuò)展GraphX的功能。其擴(kuò)展功能包括motif 預(yù)測菠镇,DataFrame序列化以及高性能的圖查詢冗荸。
( It aims to provide both the functionality of GraphX and extended functionality taking advantage of Spark DataFrames. This extended functionality includes motif finding, DataFrame-based serialization, and highly expressive graph queries.)

利用GraphFrames進(jìn)行構(gòu)圖

主要流程和上篇沒太大差異。主要是利用GraphFrames構(gòu)圖時利耍,節(jié)點(diǎn)DataFrames需要指明某列為id列(可以使String類型)蚌本,邊DataFrames需要指明src、dst列(可以使String類型)隘梨。代碼如下:

    //將RDD轉(zhuǎn)為DataFrame
    val personsdf = sqlContext.createDataFrame(personsRDD).toDF("id", "name", "no", "groupno", "vertextype")
    val groupsdf = sqlContext.createDataFrame(groupsRDD).toDF("id", "name", "tags", "groupno", "vertextype").dropDuplicates("groupno")

    val groupsds = groupsdf.select("id", "groupno", "tags")
    val relation = personsdf.join(groupsds, personsdf("groupno") === groupsds("groupno")).toDF("src","personname","personno","groupno","personvertextype","dst","groupno","tags").select("src","dst","tags")

    val personsds = personsdf.dropDuplicates("id", "no").toDF("id", "name", "tags", "groupno", "vertextype")
    val unionds = personsds.union(groupsdf)

    val graph = GraphFrame(unionds, relation)

linkurious.js

linkurious.js是純Javascript開發(fā)的js庫程癌。它利用Sigma.js進(jìn)行結(jié)構(gòu)數(shù)據(jù)的解析及可視化,其提供Canvas出嘹、WebGL席楚、SVG三種渲染模式來渲染圖的節(jié)點(diǎn)和邊咬崔。
(Linkurious.js is developed in pure Javascript. It uses Sigma.js for its graph data structure and visualization engine, which provides both Canvas, WebGL and SVG renderers for nodes and edges. )

利用linkurious.js進(jìn)行圖的可視化

首先税稼,需要將DataFrames輸出成gexf格式的數(shù)據(jù)結(jié)構(gòu)文件

    def graphFrametoGexf(g: GraphFrame) : String = {
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
        "<gexf xmlns=\"http://www.gephi.org/gexf\" xmlns:viz=\"http://www.gephi.org/gexf/viz\">\n" +
        "  <graph mode=\"static\">\n" +
        "    <nodes>\n" +
        g.vertices.rdd.map(v => if(v.get(4)=="p")
        {"      <node id=\"" + v.get(0) + "\" label=\"" +
          v.get(1) + "\">\n        <viz:color b=\"51\" g=\"51\" r=\"255\"/>\n      </node>\n"} else
        {"      <node id=\"" + v.get(0) + "\" label=\"" +
          v.get(1) + "\">\n        <viz:color b=\"255\" g=\"51\" r=\"51\"/>\n      </node>\n"
        }).collect.mkString +
        "    </nodes>\n" +
        "    <edges>\n" +
        g.edges.rdd.map(e =>
        "    <edge source=\"" + e.get(0) +
          "\" target=\"" + e.get(1) + "\" label=\"" + e.get(2) +
          "\" />\n").collect.mkString +
        "    </edges>\n" +
        "  </graph>\n" +
        "</gexf>"

    val strgexf = graphFrametoGexf(graph)
    //println(strgexf)
    val writer = new PrintWriter(new File("D:\\Tomcat7.0\\webapps\\linkurious.js\\examples\\data\\4444.gexf"))
    writer.print(strgexf)
    writer.close()

其次,利用linkurious.js進(jìn)行可視化

sigma.parsers.gexf('data/4444.gexf', {
  // container: 'graph-container',
  renderer: {
    container: document.getElementById('graph-container'),
    type: 'canvas'
  },
  settings: {
    edgeColor: 'default',
    defaultEdgeColor: '#ccc',
    animationsTime: 5000,
    drawLabels: true,
    labelThreshold: 5,
    scalingMode: 'inside',
    batchEdgesDrawing: true,
    hideEdgesOnMove: true,
    sideMargin: 1
  }
}, function(s) {
  s.graph.nodes().forEach(function (n) {
    if (!s.graph.degree(n.id)) {
      s.graph.dropNode(n.id);
    }
    else {
      n.x = Math.random();
      n.y = Math.random();
    }
  });
  s.refresh();

  // Configure the ForceLink algorithm:
  var fa = sigma.layouts.configForceLink(s, {
    worker: true,
    autoStop: true,
    background: true,
    scaleRatio: 30,
    gravity: 3,
    easing: 'cubicInOut'
  });

  // Bind the events:
  fa.bind('start stop', function(e) {
    console.log(e.type);
    document.getElementById('layout-notification').style.visibility = '';
    if (e.type == 'start') {
      document.getElementById('layout-notification').style.visibility = 'visible';
    }
  });

  // Start the ForceLink algorithm:
  sigma.layouts.startForceLink();
});

測試

利用200個用戶及400個組進(jìn)行構(gòu)圖測試垮斯,顯示效果流暢郎仆。(注意:節(jié)點(diǎn)名字不能包括Unicode字符,否則linkurious.js無法解析)


關(guān)系圖.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末兜蠕,一起剝皮案震驚了整個濱河市扰肌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌熊杨,老刑警劉巖曙旭,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盗舰,死亡現(xiàn)場離奇詭異,居然都是意外死亡桂躏,警方通過查閱死者的電腦和手機(jī)钻趋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剂习,“玉大人蛮位,你說我怎么就攤上這事×廴疲” “怎么了失仁?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長们何。 經(jīng)常有香客問我萄焦,道長,這世上最難降的妖魔是什么冤竹? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任楷扬,我火速辦了婚禮,結(jié)果婚禮上贴见,老公的妹妹穿的比我還像新娘烘苹。我一直安慰自己,他們只是感情好片部,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布镣衡。 她就那樣靜靜地躺著,像睡著了一般档悠。 火紅的嫁衣襯著肌膚如雪廊鸥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天辖所,我揣著相機(jī)與錄音惰说,去河邊找鬼。 笑死缘回,一個胖子當(dāng)著我的面吹牛吆视,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播酥宴,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼啦吧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拙寡?” 一聲冷哼從身側(cè)響起授滓,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后般堆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體在孝,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年淮摔,在試婚紗的時候發(fā)現(xiàn)自己被綠了浑玛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡噩咪,死狀恐怖顾彰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胃碾,我是刑警寧澤涨享,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站仆百,受9級特大地震影響厕隧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俄周,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一吁讨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧峦朗,春花似錦建丧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至尺铣,卻和暖如春拴曲,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凛忿。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工澈灼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人店溢。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓叁熔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親逞怨。 傳聞我的和親對象是個殘疾皇子者疤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容