GraphX Advent Calendar - Day 03 - グラフの頂点情報を編集する

f:id:teppei-studio:20100306105411j:plain

GraphX Advent Calendar 三日目です。

今日から何回かにかけて、GraphX でグラフにどのように情報を持たせるか、グラフに持たせた情報をどう編集するのかを説明します。

辺情報から生成したグラフ情報に頂点情報を追加する

昨日も説明した通り、最も簡単なグラフデータの生成方法は、辺情報のTSVファイルを、GraphLoader.edgeListFile で読み込む方法です。

val graph = GraphLoader.edgeListFile(sc, "graphdata/day03-edges.tsv").cache()

この方法では、頂点情報を何も設定できないので、デフォルトの 1 が設定されます。この頂点情報を更新する方法を説明します。

まずは頂点情報のCSVファイルを用意します。

1,Taro
2,Jiro

それをRDDに読み込みます。

val vertexLines = sc.textFile("graphdata/day03-vertices.csv")
val users: RDD[(VertexId, String)]
  = vertexLines.map(line => {
    val cols = line.split(",")
    (cols(0).toLong, cols(1))
  })

この頂点情報を、Graphに合体させるのですが、ここでは、joinVerticesを使います。同じVertexIDに、属性情報をJOINしていきます。

// vertex情報をgraphにJoinさせてgraph2を生成する
val graph2 = graph
  // デフォルトではVertexのAttributeとして
  // intの1が入っているので、それをStringの空文字にする
  .mapVertices((id, attr) => "")
  // user情報をJoinして、VertexのAttributeとしてユーザ名を入れる
  .joinVertices(users){(vid, empty, user) => user }

なお、joinする前に、mapVerticesで頂点情報を空文字(””)にしているのに注目してください。graph.edgeListFile で作ったグラフの頂点情報はデフォルトではLONG型の1が入っています。Stringの情報をJoinするには、事前にString型のデータで上書きしてやる必要があります。

それが、

.mapVertices((id, attr) => "")

のところの処理です。

joinVerticesの処理の中身を見てみると、

.joinVertices(users){(vid, empty, user) => user}

とありますが、(vid, empty, user) のところは、(vid:VertexID, empty:String, user:String) というタプル型になります。

ふたつめの empty:String にはJOIN前に入っていた該当Vertexの値です。前述の通り、空文字(””)が入っています。

もし、既存の情報とJOINする情報を合わせて使いたい時は、第2引数と第3引数の値を合わせてやることで実装できます。

ところで、上述のように、今回JOINした頂点上には、VertexIDが3の値が存在しないため、JOIN結果として、VertexIDが3の頂点情報にはNULLが入ります。

JOINする頂点情報に不足があることが考えられる場合には、joinVerticesではなく、outerJoinVerticesを使います。

// vertex情報をgraphにJoinさせてgraph3を生成する
val graph3 = graph
  // デフォルトではVertexのAttributeとして
  // intの1が入っているので、それをStringの空文字にする
  .mapVertices((id, attr) => "")
  // user情報をJoinして、VertexのAttributeとしてユーザ名を入れる
  .outerJoinVertices(users){(vid, empty, user) => user.getOrElse("None")}

この例だと、outerJoinVerticesで渡される型は、(VertexID, String, Option[String]) になります。該当のVertexIDにマッチする値が無い場合の処理を、getOrElseで書くことができます。

次回予告

さて、今日は頂点情報を追加していく処理を見てきました。明日は、もう少し複雑なデータからグラフを作っていく処理を見ていきたいと思います。

※ 今日紹介したソースコードは、
graphx-advent-samples/Day03.scala at master · ironpeace/graphx-advent-samples · GitHub で見ることができます。