오늘은 들어가기 앞서 사전 펼치듯 몇 가지 용어에 대해 설명해야할 필요가 있다.
네트워크(Network): 그물망
그래프를 바탕으로 함. 그래프의 가지에 특정한 정량적인 값들을 대응시킨 가중 그래프에 해당한다.
응용: 각 지점 간의 최소 경로를 찾는 최적화 문제, 친구 관계, 협업 관계, 인터넷 연결망 구조, 웹의 연결, 질병 전파, 분자 그래프 등으로 표현되는 다양한 사회 및 자연 현상을 파악하는데 응용.
중심성 | 중심화
연결정도: 각 노드가 어느 정도로 많은 관계를 맺고 있는지를 나타내는 지표 | 연결 정도의 전체 경향
근접: 한 점이 다른 모든 점들에 얼마나 가까운가를 나타내는 지표 | 근접 정도의 전체 경향
중개: 연결망서 한 노드가 다른 노드들 사이에 위치하는 정도를 나타내는 지표 | 중개 정도의 전체 경향
밀도: 네트워크서 이론적으로 연결 가능한 최대연결수(풀 매쉬: 밀도=1) 대비 실제 얼마나 많은 관계를 맺고 있는가를 나타낸 상대적인 비율.
최단경로: 두 노드 간 가장 짧은 연결 경로
-거리: 경로 상의 연결 수
평균거리: 네트워크를 구성한느 두 노드 간 평균 거리
네트워크엔 여러 모형이 있다. 별처럼 중심점 하나서 뻗어나가는 모양의 별형, Y처럼 생긴 Y형, 원처럼 생긴 원형은 그 대표적인 녀석이다. 우린 네트워크 값만 보고도 어떤 모형에 가까운지 알아낼 수 있다. 이걸 생성할 수 있는 코드의 시작부는 아래와 같다.
make_star()
make_ring()
make_graph()
이제 네트워크 및 관련 용어들의 뜻을 알았다. 그럼 카테고리에 걸맞도록, R언어에서 이 네트워크라는 것과 어떻게 놀아날 수 있는지 알아보도록 하자. igraph라는 패키지를 설치해야 한다. 이미 깔려있으면 install 부분은 생략하자.
install.packages("igraph")
library(igraph)
igraph가 컴퓨터에 안착했다면 다음 단계로 넘어가자.
{
G.star <- make_star(6, mode="undirected", center=1) %>%
set_vertex_attr("name", value = c("A", "B", "C", "D", "E", "F"))
G.star
plot(G.star, vertex.color=rainbow(6), vertex.size=60)
tkplot(G.star, vertex.color=rainbow(6), vertex.size=20)
G.ring <- make_ring(6, directed = FALSE, circular = TRUE) %>%
set_vertex_attr("name", value = c("A", "B", "C", "D", "E", "F"))
tkplot(G.ring, vertex.color=rainbow(6), vertex.size=20)
G.Y <- make_graph(edges=NULL, n=NULL, directed=FALSE)
G.Y <- G.Y + vertices("A", "B", "C", "D", "E", "F")
G.Y <- G.Y + edges("A", "B",
"A", "C",
"A", "D",
"D", "E",
"E", "F")
tkplot(G.Y, vertex.color=rainbow(6), vertex.size=20)
}
R언어를 쓰면서 터득한 잔기술이 하나 있는데, 바로 중괄호를 쓰는 것이다. ctr+Enter 매번 누르는 것도 귀찮은 일이니까, 아예 하나로 묶어서 한 번에 처리할 수 있게 하는 것이다. 다만 이 방식에 단점이 있다면, R 코드가 하나하나 실행되는 걸 확인하기엔 너무 빠르다는 것이다.
이번 게시글에선 다른 잔기술도 소개한다. 줄 앞부분의 tkplot을 주목하자.
tkplot(G.ring, vertex.color=rainbow(6), vertex.size=20)
모 정당의 텃밭인 TK가 아니다. 이 tk는 R스튜디오의 plots창이 아닌, 별도의 윈도우 창에 plot 결과를 생성하는 물건이다. 여러 결과를 동시에 띄워놓고 보고 싶다면 이것만한 물건이 없다. (적어도 내가 알기로는 그렇다)
지금은 고작 간단한 그림일 뿐이지만, 현실에선 눈 빠질 정도로 복잡한 모양이 되기 십상이다. 이럴 때 우린 무엇을 통해 이 녀석들의 밀도나 중점 등을 파악할 수 있을까.
# 연결 정도 중심성과 중심화
{
degree(G.star, normalized = FALSE)
degree(G.star, normalized = TRUE)
CD <- centralization.degree(G.star, normalized = FALSE)
CD
CD <- centralization.degree(G.ring, normalized = FALSE)
CD
Tmax <- centralization.degree.tmax(G.ring)
Tmax
CD$centralization / Tmax
}
# 근접 중심성과 중심화
{
closeness(G.star, normalized=FALSE)
closeness(G.star, normalized=TRUE)
CC <- centralization.closeness(G.star, normalized = FALSE)
CC
CC$centralization / (6-1)
CC$theoretical_max / (6-1)
CC$centralization / CC$theoretical_max
CC
}
# 중개 중심성과 중심화
{
betweenness(G.star, normalized=FALSE)
betweenness(G.star, normalized=TRUE)
CB <- centralization.betweenness(G.star, normalized=FALSE)
CB
CB$centralization
CB$theoretical_max
CB$centralization / CB$theoretical_max
CB
}
실행하면 그래프는 없는 대신, 이런 메시지를 얻을 수 있다.
> # 근접 중심성과 중심화
> closeness(G.star, normalized=FALSE)
A B C D E F
0.2000000 0.1111111 0.1111111 0.1111111 0.1111111 0.1111111
> closeness(G.star, normalized=TRUE)
A B C D E F
1.0000000 0.5555556 0.5555556 0.5555556 0.5555556 0.5555556
> CC <- centralization.closeness(G.star, normalized = FALSE)
> CC
$res
[1] 1.0000000 0.5555556 0.5555556 0.5555556 0.5555556 0.5555556
$centralization
[1] 2.222222
$theoretical_max
[1] 2.222222
> CC$centralization / (6-1)
[1] 0.4444444
> CC$theoretical_max / (6-1)
[1] 0.4444444
> CC$centralization / CC$theoretical_max
[1] 1
> CC
$res
[1] 1.0000000 0.5555556 0.5555556 0.5555556 0.5555556 0.5555556
$centralization
[1] 2.222222
$theoretical_max
[1] 2.222222
네트워크 밀도 / 최단거리(A - E 間)및 평균 거리 구하는 코드
# 네트워크 밀도
graph.density(G.star)
graph.density(G.Y)
graph.density(G.ring)
# 최단경로와 평균 거리
shortest.paths(G.Y)
distances(G.Y, v = "A", to="E")
get.shortest.paths(G.Y, "A", "E")$vpath[[1]]
average.path.length(G.Y)
실행결과
> # 최단경로와 평균 거리
> shortest.paths(G.Y)
A B C D E F
A 0 1 1 1 2 3
B 1 0 2 2 3 4
C 1 2 0 2 3 4
D 1 2 2 0 1 2
E 2 3 3 1 0 1
F 3 4 4 2 1 0
> distances(G.Y, v = "A", to="E")
E
A 2
> get.shortest.paths(G.Y, "A", "E")$vpath[[1]]
+ 3/6 vertices, named, from 74f45f1:
[1] A D E
> average.path.length(G.Y)
[1] 2.133333
페이스북 연결망 실습: 글쓴이는 이를 c드라이브 TEMP 폴더에 설치했다.
열어보니 웬 숫자열이 세로로 한참 뻗어 있더라.
아래의 첫번째 프로그램을 실행하려고 하면 파일 저장소를 찾는다. 위의 파일을 찾아서 선택해주면 된다. 글쓴이는 facebook으로 시작하는 파일을 택했다.
# 11.4 페이스북 사용자 네트워크 분석
# 페이스북 사용자 데이터 읽기와 그래프 출력
# install.packages("igraph"")
library(igraph)
{
df.fb <- read.table(file.choose(), header=F)
head(df.fb)
tail(df.fb)
G.fb <- graph.data.frame(df.fb, directed=FALSE)
G.fb
par(mar=c(0,0,0,0))
plot(G.fb,
vertex.label = NA,
vertex.size = 10,
vertex.color = rgb(0,1,0,0.5))
dev.off()
}
# 1~50번째 사용자들 간의 그래프
{
V(G.fb)$name
v.set <- V(G.fb)$name[1:50]
v.set
G.fb.part <- induced_subgraph(G.fb, v=v.set)
tkplot(G.fb.part,
vertex.label.cex = 1.2,
vertex.size = degree(G.fb.part)*1.5,
vertex.color = "yellow",
vertex.frame.color = "gray")
}
# ID가 1인 사용자와 연결된 그래프
{
v2 <- which(V(G.fb)$name == "1")
v2
v.set <- neighbors(G.fb, v=v2)
v.set
v3 <- c(v2, v.set)
v3
G.fb.id <- induced_subgraph(G.fb, v=v3)
V(G.fb.id)$color <- ifelse(V(G.fb.id)$name == "1", "red", "yellow")
tkplot(G.fb.id,
vertex.label.cex = 1.2,
vertex.size = degree(G.fb.id)*1.5,
vertex.frame.color = "gray")
}
# 연결정도가 가장 큰 사용자와 연결된 그래프
{
v.max <- V(G.fb)$name[degree(G.fb)==max(degree(G.fb))]
v.max
degree(G.fb, v.max)
v.max.idx <- which(V(G.fb)$name == v.max)
v.max.idx
v.set <- neighbors(G.fb, v=v.max.idx)
v3 <- c(v.max.idx, v.set)
v3
G.fb_2 <- induced_subgraph(G.fb, v=v3)
V(G.fb_2)$color <- ifelse(V(G.fb_2)$name == v.max, "red", "yellow")
V(G.fb_2)$label <- ifelse(V(G.fb_2)$name == v.max, v.max, NA)
V(G.fb_2)$size <- ifelse(V(G.fb_2)$name == v.max, 50, 5)
plot(G.fb_2)
}
# 연결정도 중심성과 중심화 지표
{
degree(G.fb, normalized=FALSE)
degree(G.fb, normalized=TRUE)
CD <- centralization.degree(G.fb, normalized = FALSE)
CD
CD$centralization
Tmax <- centralization.degree.tmax(G.fb)
Tmax
CD$centralization / Tmax
}
# 근접 중심성과 중심화 지표
closeness(G.fb, normalized=FALSE)
closeness(G.fb, normalized=TRUE)
CB <- centralization.closeness(G.fb, normalized = FALSE)
n <- vcount(G.fb)
n
CB$centralization / (n-1)
CB$theoretical_max / (n-1)
CB$centralization / CB$theoretical_max
# 중개 중심성과 중심화 지표
betweenness(G.fb, normalized=FALSE)
betweenness(G.fb, normalized=TRUE)
CB <- centralization.betweenness(G.fb, normalized = FALSE)
CB$centralization
CB$theoretical_max
CB$centralization / CB$theoretical_max
# 밀도
graph.density(G.fb)
# 거리
shortest.paths(G.fb)[1:10, 1:10]
distances(G.fb, v = "3", to="7")
get.shortest.paths(G.fb, "3", "7")$vpath[[1]]
average.path.length(G.fb)
# 연결정도 분포
plot(degree(G.fb),
xlab="사용자 ID", ylab="연결 정도",
main="사용자별 연결정도",
type='h')
x <- degree(G.fb, normalized=F)
summary(x)
hist(x,
xlab="연결 정도", ylab="빈도",
main="연결정도 분포",
breaks=seq(0, max(x), by=1))
G.fb.dist <- degree.distribution(G.fb)
plot(G.fb.dist,
type="h",
xlab="연결정도 분포", ylab="확률밀도",
main="연결정도 분포")
실행시키면 뭐가 빠졌나? 어디 잘못되었나 싶을 정도로 느리게 실행된다. 그래봤자 상대적인 것이라 15초 안에 끝난다.
그러고나면 몇 가지 노드망 그림들이 촤라락 등장한다.
100번째 있는 이웃. 저장하고 전체 노드 대비 찾아온다.
가장 연결이 많이된 인싸 107번 노드 색을 붉은색으로 하고, 나머지는 노랑으로 해서 구별한다.
이미지는 나중에 추가하겠다.
더 알고 싶으면 아래의 링크도 참고해보자.
4 장 R을 이용한 네트워크 분석 | 빅데이터분석및실습(2)
네트워크의 특성치 - 중심성과 밀도 그래프 중심성 (centralization) : 전체 네트워크에서 가장 영향력 있는 노드의 다른 노드들에 대한 상대적인 영향력을 측정 \[ C_D= \frac{\sum_{i=1}^{|V|} (C_D^* - C_D(i))}{
bigdata.dongguk.ac.kr
.
'R언어' 카테고리의 다른 글
인공지능 신경망 구축 (0) | 2022.06.07 |
---|---|
R 스튜디오 테마 바꾸기 (0) | 2022.04.05 |
R언어 3강 (0) | 2022.03.29 |
R언어 연산 (0) | 2022.03.22 |