제주 탈출 일지

빅데이터 분석 - 소셜 네트워크 분석 2(R 관련 그래프 실습) 본문

빅데이터 분석

빅데이터 분석 - 소셜 네트워크 분석 2(R 관련 그래프 실습)

귀건 2020. 11. 30. 01:45
728x90
반응형

이전 소셜 네트워크 분석1에서는 소셜 네트워크에 대해 이해할 수 있도록 개념들을 간단하게 정리해보았다. 이번 포스팅에서는 그래프를 R에서 그리는 방법들에 대해서 포스팅하도록 하겠다.

 

간단한 그래프 작성

 

(1)간단한 무방향 그래프

library(igraph)
g <- graph.formula(A--B--C, B--D, E--F--G, H, I)
set.seed(1234) #난수 설정
plot(g)

R에서 그래프를 그리기 위해서는 igraph 패키지가 필요하다. 없다면 install.packages("igraph")로 설치해야 한다. graph.formula를 통해 그래프의 형태가 어떻게 이루어져 있는지 정보를 전달한다.(간단한 그래프이므로 이런 형태로 데이터를 입력한다.) 그리고 seed값을 주어 특정 난수를 지정하는데, 이와 관련된 내용은 아래 포스팅을 참고하길 바란다.

https://m.blog.naver.com/PostView.nhn?blogId=jjy0501&logNo=220787861219&proxyReferer=https:%2F%2Fwww.google.com%2F 

 

R에서 난수 형성하기와 시드값

난수는 여러 가지 목적을 위해서 생성하게 됩니다. 주로는 시뮬레이션이나 혹은 예제를 설명하기 위한 테스...

blog.naver.com

그 후 plot을 통해 그래프를 그린다.

 

g <- graph.formula(A+---B+--C , B+--D, E+--+F+--+G, H, I)
set.seed(1234)
plot(g)

이번에는 A와 B같은 노드들을 연결하는 선이 +-- 와 같은 형태인 것을 볼 수 있는데, 이는 방향 그래프이기 때문이다. 나머지는 위의 그래프를 그릴 때와 동일하다.

 

(2)인접행렬로 그래프 표현

 

소셜 개체들 간 관계를 인접행렬을 가지고 나타낼 수 있다.

#인접행렬
adjmatrix <- matrix(c(0, 1, 1, 0, 0, 0, 0, 1, 0, 0,0, 1, 0, 0, 0, 0), byrow=T, nrow=4)
g <- graph.adjacency(adjmatrix)
V(g)$name = c("M1", "M2", "M3", "M4")
set.seed(1234)
plot(g)

matrix를 통해 0과 1로 이루어진 인접행렬을 만들 것인데, R에서 matrix는 행우선이 아닌 열우선이다. 그래서 byrow 옵션을 줘서 행 우선으로 변경하고, 행의 갯수를 4개로 설정한다. 그러면 다음과 같은 인접 행렬이 저장되게 된다.

  M1 M2 M3 M4
M1 0 1 1 0
M2 0 0 0 1
M3 0 0 0 1
M4 0 0 0 0

이렇게 어떠한 인접행렬을 구성하게 되면, graph.adjacency() 함수를 이용하여 그래프를 그릴 수 있다. 여기서 옵션은 mode=("directed", "undirected") 와 weighted=(True, False)이다. 방향 그래프인지, 무방향 그래프인지, 가중 그래프인지 아닌지를 옵션으로 주게되는 것이다.

V(g)$name = c("M1", "M2", "M3", "M4") 처럼 V(Vertex : 정점)의 name에 값을 넣어줄수도 있다.

 

그럼 다음 예제를 보자.

#인접행렬 2
adjmatrix <- matrix(c(0, 1, 1, 0, 0, 0, 0, 1, 0, 0,0, 1, 0, 0, 0, 0), byrow=T, nrow=4)
g <- graph.adjacency(adjmatrix)

V(g)$name = c("M1","M2", "M3", "M4")
V(g)$label.cex = 2
V(g)$label.color = "green"
V(g)$size=30
V(g)$color ="red"
set.seed(1234)
plot(g)

이번에는 V(g)$속성 들에 관련한 예제이다. V(g)$label.cex, V(g)$label.color 값을 조정할 수 있다. label은 그래프 노드의 글자를 의미한다. 그림을 보면 더 확실히 이해할 수 있다.

아무 설정도 하지 않았을 때
label.cex = 2, label.color = "green"

V(g)$size는 노드의 크기를 설정한다. 30으로 설정하면 위의 그림의 글자와 딱 맞는 형태로 커진다. V(g)$color는 노드의 색을 변경한다. 각 설정을 바꾸면서 공부해보길 바란다.

 

이번에는 E(g) (Edge : 간선)에 대한 속성을 알아본다. 

#인접행렬 3
a.matrix <- matrix(c(0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0), byrow=T, nrow=4)
g <- graph.adjacency(a.matrix)

V(g)$name = c("M1","M2", "M3", "M4")
V(g)$label.cex = 2
V(g)$label.color = "green"

V(g)$size=30
V(g)$color ="red"

E(g)$width = 4
E(g)$color = "blue"

set.seed(1234)
plot(g)

E$width를 설정해주면, 간선의 크기를 늘리거나 줄일 수 있다. E$color를 설정하면 설정한 색으로 간선의 색이 변한다. 

 

마지막으로 속성을 설정하는 다른 방법이다.

a.matrix <- matrix(c(0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0), byrow=T, nrow=4)
g <- graph.adjacency(a.matrix)

V(g)$name = c("M1","M2", "M3", "M4")
set.seed(1234)
plot(g, vertex.label.cex = 2, vertex.label.color = "green", vertex.size=30, vertex.color="red", edge.width=4, edge.color="blue")

 

이전에는 그냥 각 V와 E에 대한 속성을 직접 접근하여 변경 후 plot을 통해 그렸는데, plot에 인자를 주는 것으로도 동일한 결과를 얻을 수 있다.

 

plot으로 그린 결과

 

(3)랜덤 그래프와 척도 없는 그래프 작성

 

랜덤한 갯수의 정점에서과 정점간 엣지(E)가 존재할 확률을 통해 랜덤 그래프를 구할 수 있다.

#랜덤그래프

set.seed(1000)
g <- erdos.renyi.game(100, 0.02)
plot(g, vertex.size = 4, vertex.label=NA, vertex.color="red")

erdos.renyi.game(n, p or m) 함수가 랜덤 그래프를 그려준다. n은 정점의 갯수이고, p는 정점 간 엣지가 존재할 확률, m은 그래프에서의 엣지 수를 의미한다. p 와 m 중 하나의 인자는 필요로 한다. 이렇게 쉽게 랜덤 그래프를 그릴 수 있다.

 

랜덤 그래프

 

다음은 척도 없는 그래프이다. 척도 없는 그래프는 scale free graph인데, 노드간 연결 분포가 멱함수를 따른다는 의미이다. 무슨 말이냐면, 대부분의 노드는 소수의 간선을 가지고, 많은 간선을 가진 노드는 소수이다라는 의미이다. 

#척도 없는 그래프

set.seed(1000)
g <- barabasi.game(100)
plot(g, vertex.size =4, vertex.label = NA, vertex.color="red")

척도없는 그래프는 barabasi.game()함수로 생성한다. 여기서 인자는 정점의 수를 의미한다.

 

척도 없는 그래프

이 그래프를 보면 많은 노드들과 연결된 중심 노드들이 있다. 이 노드를 hub라고 한다. Hub는 소셜 네트워크에서 중요한 인물이다라고 판단할 수 있겠다.

 

(4) R에서 그래프 지표 함수.

 

degree(), graph.density(), closeness() 함수를 사용할 수 있다. 차수, 밀도, 근접 중심성에 대한 내용은 1편에서 다루었으니 참고하길 바란다. 

# 그래프 지표

g <- graph.formula(A-B-D, C-D-F, E-D-F, E-F)
V(g)$size = 20
V(g)$label.cex = 2

set.seed(1234)
plot(g)

degree(g)
graph.density(g)
degree.distribution(g)

#차수 분포 그래프 그리기
plot(degree.distribution(g), xlab ="node degree")
lines(degree.distribution(g))

n <- vcount(g)
degree.centrality <- degree(g)/(n-1) # degree centrality

closeness(g)
betweenness(g)

 

degree() : 노드의 차수(degree)를 알기 위한 함수

graph.density() : 그래프의 밀도를 알기 위한 함수

closeness() : 노드의 근접 중심성을 알기 위한 함수

betweeness() : 매개 중심성을 알기 위한 함수

 

한번 예제를 해보고 자신의 결과가 제대로 나왔는지 확인해보면 좋을 것 같다.

 

정리

그래프를 그리는 3가지에 대해 알아보았다. 간단한 그래프 그리기, 인접행렬로 그리기, 랜덤 그래프 및 척도 없는 그래프이다. 그리고 그래프 지표를 계산하는 함수에 대해서 알아보았다.

다음은 소셜 네트워크 데이터의 시각화에서 다루도록 하겠다.

728x90
반응형
Comments