Network Analysis

Author

Alfa Nugraha

Pengantar Analisis Jejaring

Jejaring (network) adalah kumpulan entitas/node/vertek/simpul yang saling berhubungan, dengan suatu edge, yang dapat berkomunikasi atau bertukar informasi satu sama lain.

Jejaring dapat ditemukan dalam berbagai konteks, termasuk sistem sosial (social network), teknologi (technological network), dan biologis (biological network).

  • Dalam jejaring sosial (social network), simpulnya mungkin adalah individu, dan hubungan di antara mereka mungkin mewakili hubungan seperti persahabatan, ikatan keluarga, atau kolaborasi profesional.
  • Dalam jejaring teknologi (technological network), node dapat berupa perangkat seperti komputer atau ponsel pintar, dan koneksi di antara keduanya dapat berupa koneksi internet atau seluler.
  • Dalam jejaring biologis (biological network), simpulnya bisa berupa sel atau protein, dan hubungan di antara keduanya mungkin mewakili interaksi kimia atau fisik.

Analisis jejaring (network analysis) merupakan metode mempelajari hubungan antar entitas dalam suatu jejaring. Metode ini melibatkan analisis hubungan, atau tautan, antara entitas, serta karakteristik entitas itu sendiri. Analisis jejaring dapat digunakan untuk mempelajari berbagai sistem, termasuk jejaring sosial, jejaring transportasi, dan jejaring biologis.

Terdapat berbagai alat bantu dan teknik yang telah tersedia untuk analisis jejaring di antaranya:

  • Teori graf
  • Metode visualisasi jejaring
  • Centrality measures
  • Deep learning (Search Convolutional Neural Network)

I. Teori graf

Graf pertama kali dikenal pada seorang mathematician Swiss, Leonhard Euler, berhasil mengungkapkan Misteri Teka-teki Jembatan Konigsberg tahun 17361. Ia ingin mengetahui apakah terdapat rute tertentu sehingga seseorang dapat melalui tujuh jembatan yang ada tepat sekali. Euler menyimpulkan bahwa hal tersebut tidak dapat dilakukan tapi dapat diselesaikan dengan geometri, aljabar, atau perhitungan biasa sehingga muncul konsep eulerian graph yang menjadi salah satu topik pada matematika diskret. Graf merupakan alat yang digunakan untuk merepresentasikan objek-objek pada suatu diskrit dan hubungan yang terdiri antara objek-objek tersebut.

  • 1 Jembatan tersebut dulu berada di kota Prussia, sekarang menjadi Kaliningrad, Rusia https://maa.org/press/periodicals/convergence/leonard-eulers-solution-to-the-konigsberg-bridge-problem

  • Struktur jejaring ditunjukkan dengan suatu graf. Graf merupakan gambar atau pola dari penghubungan antara himpunan elemen-elemen tidak kosong yang disebut titik (verteks/node/simpul) dengan himpunan pasangan tidak terurut titik-titik tersebut yang disebut sisi (edge). Representasi visual dari graf adalah dengan menyatakan objek sebagai titik, sedangkan hubungan antara objek ditanyakan sebagai sisi.

    Graf dinotasikan dengan \(G=(V,E)\), dimana \(V=\{v_1,v_2,v_3,...,v_n\}\) adalah himpunan tidak kosong dari simpul dan \(E=\{e_1=v_1v_2,e_2=v_2v_3,...,e_{n-1}=v_{n-1}v_n\}\) adalah himpunan edge yang menghubungkan sepasang simpul.

    Jadi, sebuah graf dimungkinkan tidak mempunyai edge satu buah pun, tetapi simpulnya harus ada minimal satu.

    Jenis-jenis Graf

    Graf dapat dikelompokkan menjadi beberapa kategori atau jenis, tergantung pada perspektif pengelompokkannya. Berbagai variasi dari graf dapat dibedakan berdasarkan orientasi arah pada sisinya2 dan berdasarkan strukturnya3:

  • 2 Munir, R. 2012. Matematika Diskrit. Revisi kelima. Bandung: Informatika.

  • 3 Wibisono, S. 2008. Matematika Diskrit. Yogyakarta: Graha Ilmu.

    • Undirected graphs, tidak memiliki arah hanya sekedar memiliki keterkaitan
    • Directed graphs, arah sebagai bagian penting
    • Multi graph, graf yang mempunyai satu atau lebih pasangan edge ganda
    • Weighted graphs, edge berisi bobot
    • Self-loops, node terhubung ke diri sendiri

    II. Visualisasi Jejaring

    Pertanyaan kunci dalam merancang visualisasi jejaring adalah:

    • Apa tujuan yang ingin diperoleh?
    • Properti atau sifat jejaring seperti apa yang ingin disorot?
    • Apa permasalahan utama yang ingin ditangani?

    Contoh visualisasi di atas adalah variasi tujuan dalam melihat gambaran suatu jejaring, dalam beberapa kasus bagan sederhana atau bahkan yang lebih kompleks bisa saja lebih sesuai.

    Format lain dalam visualisasi jejaring memiliki beberapa elemen penting sebagai pengatur output yang ingin disajikan. Beberapa yang utama yaitu warna, ukuran, bentuk, dan posisi.

    Layout graf modern dapat dioptimalkan dengan kecepatan and estetik, khususnya meminimumkan titik overlaps dan persilangan edge, serta memastikan panjang edge yang serupa yang melalui graf.

    III. Centrality Measures

    Salah satu pendekatan dalam menganalisis suatu jejaring adalah mengukur kekuatan, pengaruh, atau karakteristik suatu individu berdasarkan pola hubungan mereka4. Dalam teori graf dan analisis jejaring, aspek tersebut berkaitan sekali dengan sentralitas (centrality). Ukuran sentralitas simpul dalam graf menentukan kepentingan relatif dari simpul dalam graf, sebagai contoh:

  • 4 Tsvetova M, Kouznetsov A. 2011. Social Network Analysis for Startup. O’Reilly, USA

    • seberapa penting seseorang dalam jejaring sosial
    • seberapa penting keberadaan sebuah ruang di dalam gedung
    • seberapa baik jalan yang digunakan dalam jejaring perkotaan

    Definisi yang paling sederhana dari sentralitas node adalah bahwa node sentral haruslah node yang paling aktif atau node yang memiliki ikatan paling banyak dengan node lain dalam jejaring. Dari definisi tersebut maka terdapat beberapa teknik yang secara luas digunakan untuk mengukur sentralitas, yaitu:

    • Degree centrality (sentralitas derajat)

      Ide dasar dari degree centrality adalah untuk menghitung berapa edge yang terikat pada sebuah node dengan variasi pada distribusi nilai secara proporsional kepada simpul tetangganya. Node yang memiliki nilai derajat paling tinggi adalah Node yang paling sentral.

    • Closeness centrality (sentralitas kedekatan)

      Ukuran sentralitas ini menggambarkan kedekatan suatu node dengan node lain. Kedekatan ini diperoleh dari nilai kebalikan (inverse) dari jumlah bobot terpendek antara individu ke semua individu lain. Semakin tinggi nilai kedekatan artinya suatu node mempunyai ikatan erat dengan node lainnya.

    • Betweenness centrality (sentralitas keantaraan)

      Keantaraan mengukur banyaknya koneksi suatu individu. Keantaraan suatu node \(V\) secara matematis adalah perbandingan antara jalur terpendek antar semua anggota jejaring yang melewati \(V\) dibandingkan jalur yang terbentuk antar semua node (dengan dan tanpa melewati \(V\))

    • Eigenvector centrality (sentralitas vektor ciri)

      Ukuran ini dapat dikatakan sebagai versi rekursif dari sentralitas derajat dimana sebuah node akan memiliki bobot yang lebih tinggi bila terhubung pada node yang juga memiliki keterhubungan tinggi

    • PageRank centrality

      Sentralitas ini adalah varian dari sentralitas vektor ciri dimana ukurannya menggunakan proses penelusuran secara acak dalam mengidentifikasi node yang biasa dijumpai pada jalur tersebut. Tiap-tiap node dianggap sebagai sentral.

    Beberapa contoh di atas adalah sebagian contoh dari banyak ukuran sentralitas. Terdapat banyak sekali ukuran dan algoritma yang sudah dikembangkan dalam mengukur sentralitas.

    Sebagai latihan, hitunglah sentralitas derajat, kedekatan, dan keantaraan pada graf berikut ini:

    IV. Community Detection

    Deteksi komunitas (community detection) pada analisis jejaring adalah cara yang digunakan untuk menemukan kelompok yang terdiri dari sejumlah simpul yang mirip atau memiliki hubungan kuat dan padat satu sama lain dibanding simpul lainnya.

    Deteksi komunitas merupakan salah satu permasalahan pada Social Network Analysis (SNA). SNA sendiri merupakan representasi graf dengan aktor sebagai simpul dan relasi antar aktor sebagai edge pada graf.

    Teknik dan algoritma yang dikembangkan untuk menentukan komunitas pada suatu jejaring graf sudah banyak dilakukan, berikut ini beberapa kajian yang dapat ditelusuri5:

  • 5 Latifah, R., Rosanti, N., Amri, N. 2022. Kajian Literatur Deteksi Komunitas dan Analisis Jaringan di Indonesia. JUST IT: Jurnal Sistem Informasi, Teknologi Informasi dan Komputer, 13(1).

  • No Metode Publikasi
    1 Louvain (Antonio et al., 2021; Mutiara et al., 2021)
    2 Newman Algorithm (Nazir et al., 2014)
    3 Fastgreedy Algorithm (Setiawan et al., 2021)
    4 Multilevel community detection (Latifah & Adriani, 2016)
    5 Danon Algorithm (Latifah & Adriani, 2016)
    6 k-click percolation (Studiawan et al., 2016)
    7 Walktrap (Setiawan et al., 2021)
    8 Leading eigenvector (Latifah, 2016)
    9 Link rank (Yudhoatmojo & Samuar, 2017)
    10 Local seed expansion (Negara et al., 2017)
    11 Katz centrality (Sari et al., 2017)
    12 Fruchterman-Reingold (Irma Yuliana et al., 2017)
    13 Wakita Tsurumi (Irma Yuliana et al., 2017)
    14 Meanshift clustering (Armiati et al., 2018)
    15 Facetnet Algorithm (Atastina et al., 2018)
    16 Girvan-Newman Algorithm (Putu et al., 2021; Saputri et al., 2018)
    17 Infomap (Saputri et al., 2018)
    18 Spectral clustering (Nurmasyitah, Imelda Atastina, 2018)
    19 CNM-centrality algorithm (Rahmadiani et al., 2018)
    20 DBSCAN algorithm (Ningsih et al., 2018)
    21 Label propagation (Rakhmawati & Mufidah, 2020)
    22 Algoritma Genetika (Aditama & Azhari, 2020)
    23 Greedy modularity (Putu et al., 2021)

    Dalam konsep pemetaan jejaring, ukuran kekuatan pengelompokkan hingga terbaginya komunitas-komunitas yang ditandai terbentuknya gumpalan-gumpalan diberikan oleh suatu parameter yang dinamakan modularitas. Modularitas merepresentasikan hubungan antar node dengan komunitas yang sama (intra-komunitas) dibandingkan dengan total jejaring. Jejaring yang memiliki hubungan antar simpul intra-komunitas yang besar berarti memiliki hubungan inter-komunitas yang rendah.

    Modularitas pertama kali diperkenalkan oleh Newman sebagai indikator baik tidaknya suatu pengelompokan jaringan yang dilakukan. Hingga nanti kajian pemetaan deteksi komunitas adalah kajian dimana memaksimalkan nilai fungsi modularitas.

    Beberapa algoritma pada pembahasan berikut digunakan untuk mendeteksi suatu kelompok yang berisi simpul yang terhubung dengan kuat dan edge yang lebih sedikit antar kelompok:

    • Berdasarkan keterhubungan tepi (edge betweenness) Newman-Girvan

      Ide dasar dari pendekatan ini adalah probabilitas besar edge-edge yang menghubungkan modul-model terpisah memiliki nilai keterhubungan tepi yang tinggi karena semua rute terpendek dari satu modul ke modul lain harus melewatinya. Jadi, tujuan algoritma ini adalah ngin memperoleh komunitas yang berisi node dengan jalur terpendek.

    • Berdasarkan propagasi label

      Menetapkan label dari suatu node, secara acak, kemudian mengganti label pada setiap node dengan label yang paling sering muncul di antara node sebelahnya atau tetangganya. Langkah tersebut diulang hingga setiap node mempunyai label yang umum dan serupa dengan node sebelahnya

    • Berdasarkan optimisasi greedy dari modularitas

      Tujuan dari algorima ini adalah mencari subgraf atau komunitas yang padat dan saling berkumpul melalui pengoptimalan nilai modularitas secara langsung

    Analisis Jejaring menggunakan R

    Terdapat banyak sekali pustaka yang populer yang dapat digunakan untuk melakukan analisis jejaring di R, salah satunya adalah igraph.

    Tujuan utama paket ini adalah untuk menyediakan sekumpulan contoh gugus data dan fungsi untuk:

    1. implementasi algoritma graf dengan mudah,
    2. penanganan dan pembuatan graf dengan ukuran besar, dengan jutaan node dan edge,
    3. memungkinkan pembuatan graf dengan waktu yang efektif melalui bahasa pemgrograman high-level seperti R

    Implementasi Graf

    Berbagai contoh jenis graf berikut ini dapat divisualisasikan dengan berbagai perintah yang tersedia pada igraph

    Graf tak berarah

    g1 <- graph(
      edges=c(1,2,2,3,3,1),
      directed=F
    )
    g1
    ## IGRAPH f4cba0a U--- 3 3 -- 
    ## + edges from f4cba0a:
    ## [1] 1--2 2--3 1--3
    plot(g1)

    Graf berarah

    g2 <- graph(
      edges = c(1,2,2,3,3,1),
      n=10
    )
    g2
    ## IGRAPH f4e9115 D--- 10 3 -- 
    ## + edges from f4e9115:
    ## [1] 1->2 2->3 3->1
    plot(g2)

    g3 <- graph(
      c("John", "Jim", "Jim", "Jill", "Jill", "John") # nama simpul
    ) 
    g3
    ## IGRAPH f4f7c81 DN-- 3 3 -- 
    ## + attr: name (v/c)
    ## + edges from f4f7c81 (vertex names):
    ## [1] John->Jim  Jim ->Jill Jill->John
    plot(g3)

    Empty graph

    Bentuk graf yang tidak memiliki edge

    # membuat graf dengan 40 node tanpa edge
    eg <- make_empty_graph(40)
    plot(eg, vertex.size=10, vertex.label=NA)

    Full graph

    Bentuk graf yang seluruh nodenya terhubung satu sama lain

    fg <- make_full_graph(40)
    plot(fg, vertex.size=10, vertex.label=NA)

    Simple star graph

    Membuat graf dengan susunan layout seperti bintang

    st <- make_star(40)
    plot(st, vertex.size=10, vertex.label=NA)

    Tree graph

    Membuat graf dengan susunan layout seperti pohon

    tr <- make_tree(40, children = 3, mode = "undirected")
    plot(tr, vertex.size=10, vertex.label=NA) 

    Ring graph

    Membuat graf dengan susunan layout seperti cincin

    rn <- make_ring(40)
    plot(rn, vertex.size=10, vertex.label=NA)

    Erdos-Renyi random graph model

    Graf juga dapat dibangkitkan secara acak dengan argumen n adalah banyaknya node, m adalah banyaknya edge.

    er <- sample_gnm(n=100, m=40) 
    plot(er, vertex.size=6, vertex.label=NA) 

    Rewiring a graph

    rn.rewired <- rewire(rn, each_edge(prob=0.1))
    plot(rn.rewired, vertex.size=10, vertex.label=NA)

    rn.neigh <- connect.neighborhood(rn, 5)
    plot(rn.neigh, vertex.size=8, vertex.label=NA)

    Jika terdapat dua atau lebih graf yang dibentuk, graf tersebut dapat dikombinasikan ke dalam satu layout

    plot(rn, vertex.size=10, vertex.label=NA) 

    plot(tr, vertex.size=10, vertex.label=NA) 

    plot(rn %du% tr, vertex.size=10, vertex.label=NA) 

    Adjacency Matrix

    Matriks Ketetanggaan (adjacency matrix) merupakan matriks yang diperoleh dari merepresentasikan suatu graf dengan cara melihat hubungan antar node yang ada pada suatu graf. Matriks ketetanggaan didefinisikan dengan himpunan nilai (0, 1) dimana 0 menunjukkan antar node tidak ada edge satu sama lain dan 1 sebaliknya. Matriks tersebut dapat dipanggil dengan perintah berikut

    # matrix sparse
    g3[]
    ## 3 x 3 sparse Matrix of class "dgCMatrix"
    ##      John Jim Jill
    ## John    .   1    .
    ## Jim     .   .    1
    ## Jill    1   .    .

    Centrality di R

    Diketahui graf berikut ini, hitung ukuran sentralitasnya

    gx <- graph(
        edges=c(1,2,2,3,3,1,2,5,3,5,3,4,5,6,5,7),
        directed=F
    )
    plot(gx)

    CINNA

    Sebelum menghitung ukuran sentralitas dengan lima ukuran yang telah disebutkan di atas menggunakan igraph, pustaka lain, yaitu CINNA (Central Informative Nodes in Network Analysis) dikembangkan sebagai pustaka untuk menghitung, menganalisis, dan membandingkan ukuran berbagai sentralitas yang sudah banyak tersedia dan dikaji oleh peneliti analisis jejaring.

    install.packages("CINNA")

    Fungsi yang populer pada pustaka ini salah satunya proper_centralities() yang dapat memberikan ukuran sentralitas yang tepat pada suatu objek graf

    pr_cent <- proper_centralities(gx)
    ##  [1] "subgraph centrality scores"                      
    ##  [2] "Topological Coefficient"                         
    ##  [3] "Average Distance"                                
    ##  [4] "Barycenter Centrality"                           
    ##  [5] "BottleNeck Centrality"                           
    ##  [6] "Centroid value"                                  
    ##  [7] "Closeness Centrality (Freeman)"                  
    ##  [8] "ClusterRank"                                     
    ##  [9] "Decay Centrality"                                
    ## [10] "Degree Centrality"                               
    ## [11] "Diffusion Degree"                                
    ## [12] "DMNC - Density of Maximum Neighborhood Component"
    ## [13] "Eccentricity Centrality"                         
    ## [14] "Harary Centrality"                               
    ## [15] "eigenvector centralities"                        
    ## [16] "K-core Decomposition"                            
    ## [17] "Geodesic K-Path Centrality"                      
    ## [18] "Katz Centrality (Katz Status Index)"             
    ## [19] "Kleinberg's authority centrality scores"         
    ## [20] "Kleinberg's hub centrality scores"               
    ## [21] "clustering coefficient"                          
    ## [22] "Lin Centrality"                                  
    ## [23] "Lobby Index (Centrality)"                        
    ## [24] "Markov Centrality"                               
    ## [25] "Radiality Centrality"                            
    ## [26] "Shortest-Paths Betweenness Centrality"           
    ## [27] "Current-Flow Closeness Centrality"               
    ## [28] "Closeness centrality (Latora)"                   
    ## [29] "Communicability Betweenness Centrality"          
    ## [30] "Community Centrality"                            
    ## [31] "Cross-Clique Connectivity"                       
    ## [32] "Entropy Centrality"                              
    ## [33] "EPC - Edge Percolated Component"                 
    ## [34] "Laplacian Centrality"                            
    ## [35] "Leverage Centrality"                             
    ## [36] "MNC - Maximum Neighborhood Component"            
    ## [37] "Hubbell Index"                                   
    ## [38] "Semi Local Centrality"                           
    ## [39] "Closeness Vitality"                              
    ## [40] "Residual Closeness Centrality"                   
    ## [41] "Stress Centrality"                               
    ## [42] "Load Centrality"                                 
    ## [43] "Flow Betweenness Centrality"                     
    ## [44] "Information Centrality"                          
    ## [45] "Dangalchev Closeness Centrality"                 
    ## [46] "Group Centrality"                                
    ## [47] "Harmonic Centrality"                             
    ## [48] "Local Bridging Centrality"                       
    ## [49] "Wiener Index Centrality"

    Output di atas berisi daftar 49 ukuran sentralitas yang dapat digunakan untuk menganalisis graf tersebut.

    Karena menghitung seluruh ukuran di atas akan cukup memakan waktu, maka dipilih lima ukuran teratas untuk membandingkan ukuran mana yang paling baik. Fungsi calculate_centralities dapat digunakan untuk kajian komparasi ukuran sentralitas. Fungsi ini menggunakan algoritma analisis komponen utama (PCA) dimana ukuran sentralitas sebagai peubahnya. Kontribusi dari peubah tersebut memperhitungkan keragaman relatif terhadap PCA (dalam persen).

    Dengan fungsi ini, sentalitas yang memiliki lebih banyak informasi tentang node sentral dan yang dapat mendeskripsikan node-node berpengaruh dalam suatu jaringan dapat dideteksi dengan lebih akurat.

    calculate_centralities(gx, include = pr_cent[1:5]) %>%
      pca_centralities(scale.unit = TRUE)

    Pada plot di atas, Topological Coefficient adalah ukuran yang memiliki nilai kontribusi lebih di antara empat ukuran lain. Dengan kata lain, ukuran tersebut dapat menentukan node sentral dengan lebih akurat.

    Pustaka ini juga dapat memvisualisasikan hasil graf dari pilihan tipe ukuran yang diinginkan, dalam hal ini ukuran Topological Coefficient sebagai ukuran terbaik.

    visualize_graph(gx, centrality.type = "Topological Coefficient" )

    Menghitung sentralitas

    Berikutnya dihitung sentralitas degree, closeness, betweenness, eigenvector, dan PageRank

    cen_deg <- degree(gx)
    cen_clo <- closeness(gx)
    cen_bet <- betweenness(gx)
    cen_evc <- evcent(gx)
    cen_pgr <- page.rank(gx)

    Perbandingan ukuran tersebut terhadap masing-masing simpul dapat dilihat pada tabel berikut

    node degree closeness betweenness eigenvector pagerank
    1 2 0.0833333 0.0 0.6736624 0.1214178
    2 3 0.1111111 1.5 0.9078567 0.1757399
    3 4 0.1250000 6.5 1.0000000 0.2362177
    4 1 0.0769231 0.0 0.3530991 0.0716248
    5 4 0.1250000 9.0 0.8974482 0.2471176
    6 1 0.0769231 0.0 0.3168881 0.0739411
    7 1 0.0769231 0.0 0.3168881 0.0739411

    Community Detection di R

    Berikut ini daftar fungsi-fungsi yang dapat digunakan pada igraph untuk mendeteksi komunitas atau kelompok atau subgraf dalam analisis jejaring menggunakan R

    as.character(lsf.str("package:igraph", pattern="cluster_"))
    ##  [1] "cluster_edge_betweenness"  "cluster_fast_greedy"      
    ##  [3] "cluster_fluid_communities" "cluster_infomap"          
    ##  [5] "cluster_label_prop"        "cluster_leading_eigen"    
    ##  [7] "cluster_leiden"            "cluster_louvain"          
    ##  [9] "cluster_optimal"           "cluster_spinglass"        
    ## [11] "cluster_walktrap"
    as.character(lsf.str("package:igraph", pattern="community"))
    ## [1] "edge.betweenness.community"    "fastgreedy.community"         
    ## [3] "infomap.community"             "label.propagation.community"  
    ## [5] "leading.eigenvector.community" "multilevel.community"         
    ## [7] "optimal.community"             "spinglass.community"          
    ## [9] "walktrap.community"

    Dengan pattern cluster_ dan community dapat dilihat bahwa selain teknik yang menjadi pokok bahasan di atas, terdapat banyak sekali cara yang dapat digunakan. Berikut ini adalah hasil deteksi komunitas menggunakan pendekatan edge betweenness, propagasi label, dan greedy.

    Deteksi komunitas berdasarkan keterhubungan tepi (edge betweenness) Newman-Girvan

    Deteksi komunitas berdasarkan propagasi label

    clp <- cluster_label_prop(gx)
    plot(clp, gx)

    Deteksi komunitas berdasarkan optimisasi greedy dari modularitas

    cfg <- cluster_fast_greedy(as.undirected(gx))
    plot(cfg, as.undirected(gx))

    Modularitas

    Modularitas secara rinci dapat dilihat menggunakan perintah berikut

    class(ceb)
    ## [1] "communities"
    
    # number of communities
    length(ceb)     
    ## [1] 2
    
    # community membership for each node
    membership(ceb) 
    ## [1] 1 1 1 1 2 2 2
    
    # how modular the graph partitioning is
    modularity(ceb) 
    ## [1] 0.21875
    
    # boolean vector: TRUE for edges across communities
    crossing(ceb, gx)   
    ## [1] FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE

    Pemodelan Statistika menggunakan Analisis Jejaring

    Pemodelan statistik umumnya bertujuan untuk memperoleh suatu model yang mampu dengan baik menjelaskan variabel responnya. Upaya yang sering dilakukan untuk meningkatkan kebaikan model yang diharapkan ialah dengan menggunakan variabel prediktor yang mampu menjelaskan variabel respon tersebut. Selain itu, informasi mengenai sikap dan pola antar observasi, dapat juga dijadikan tambahan variabel prediktor di dalam model.

    Jejaring antar observasi yang ada dapat dijadikan tambahan variabel prediktor dalam model.

    Persiapan data

    Diketahui jejaring pertemanan dari 17 orang pada data node-data-model.csv dan edges-data-model.csv. Manfaatkanlah network tersebut untuk memodelkan banyaknya pengeluaran per bulan (spending) terhadap penghasilannya (income). Bandingkan model yang dihasilkan ketika dengan dan tanpa menggunakan jejaring

    model_node <- read.csv("node-data-model.csv", header=T, as.is=T)
    head(model_node)
    ##    id  name spending income
    ## 1 a01  Tedd       20     20
    ## 2 a02  John       21     25
    ## 3 a03  Mark       24     30
    ## 4 a04 David       26     32
    ## 5 a05   Lia       22     20
    ## 6 a06  Evan       31     50
    model_edge <- read.csv("edges-data-model.csv", header=T, as.is=T)
    head(model_edge)
    ##   from  to weight
    ## 1  a01 a02     10
    ## 2  a01 a02     12
    ## 3  a01 a03     22
    ## 4  a01 a04     21
    ## 5  a04 a11     22
    ## 6  a05 a15     21
    model_edge <- aggregate(model_edge[,3], model_edge[,-3], sum)
    model_edge <- model_edge[order(model_edge$from, model_edge$to),]
    colnames(model_edge)[3] <- "weight"
    rownames(model_edge) <- NULL
    model_net <- graph_from_data_frame(d=model_edge, vertices=model_node, directed=F)
    model_net
    ## IGRAPH f675a3d UNW- 17 49 -- 
    ## + attr: name (v/c), spending (v/n), income (v/n), weight (e/n)
    ## + edges from f675a3d (vertex names):
    ##  [1] Tedd  --John   Tedd  --Mark   Tedd  --David  Tedd  --Rudy   Tedd  --John  
    ##  [6] John  --Mark   John  --James  John  --Tina   Tedd  --Mark   Mark  --David 
    ## [11] Mark  --Lia    Mark  --Rosa   Mark  --Tina   Mark  --Robert Mark  --Sims  
    ## [16] Mark  --David  David --Evan   David --Robert David --Sims   David --Loney 
    ## [21] Tedd  --Lia    John  --Lia    Lia   --James  Lia   --Rudy   Evan  --Evan  
    ## [26] Evan  --Icha   Evan  --Loney  Mark  --Ingrid Ingrid--Rosa   Ingrid--Tina  
    ## [31] Ingrid--Lina   Mark  --Rosa   Ingrid--Rosa   Rosa  --James  James --Tina  
    ## [36] Mark  --Tina   Evan  --Sims   Sims  --Lady   Sims  --Lina   Sims  --Lady  
    ## + ... omitted several edges
    plot(model_net)

    Pemodelan regresi memanfaatkan network

    Pemodelan regresi linear secara umum:

    \(y = X\beta+\epsilon\)

    Pemodelan regresi memanfaatkan jejaring:

    \(y = \alpha W y + X\beta+\epsilon\)

    Dengan \(\alpha\) konstanta, \(W\) merupakan matriks pembobot yang berasal dari obeservasi jejaring yang sudah distandarisasi

    # Pembentukan matriks pembobot
    a <- as_adjacency_matrix(model_net)
    b <- apply(a,1,sum)
    w <- round(a/b,2)
    w
    ## 17 x 17 sparse Matrix of class "dgCMatrix"
    ##    [[ suppressing 17 column names 'Tedd', 'John', 'Mark' ... ]]
    ##                                                                             
    ## Tedd   .    0.25 0.25 0.12 0.12 .    .    .    .    .    .    .    .    .   
    ## John   0.33 .    0.17 .    0.17 .    .    .    0.17 0.17 .    .    .    .   
    ## Mark   0.15 0.08 .    0.15 0.08 .    0.08 0.15 .    0.15 0.08 0.08 .    .   
    ## David  0.11 .    0.22 .    .    0.11 .    .    .    .    0.11 0.11 .    .   
    ## Lia    0.20 0.20 0.20 .    .    .    .    .    0.20 .    .    .    .    .   
    ## Evan   .    .    .    0.14 .    0.14 .    .    .    .    .    0.14 .    .   
    ## Ingrid .    .    0.20 .    .    .    .    0.40 .    0.20 .    .    .    0.20
    ## Rosa   .    .    0.40 .    .    .    0.40 .    0.20 .    .    .    .    .   
    ## James  .    0.25 .    .    0.25 .    .    0.25 .    0.25 .    .    .    .   
    ## Tina   .    0.20 0.40 .    .    .    0.20 .    0.20 .    .    .    .    .   
    ## Robert .    .    0.33 0.33 .    .    .    .    .    .    .    .    .    0.33
    ## Sims   .    .    0.17 0.17 .    0.17 .    .    .    .    .    .    0.33 0.17
    ## Lady   .    .    .    .    .    .    .    .    .    .    .    0.50 .    0.25
    ## Lina   .    .    .    .    .    .    0.25 .    .    .    0.25 0.25 0.25 .   
    ## Rudy   0.40 .    .    0.20 0.20 0.20 .    .    .    .    .    .    .    .   
    ## Icha   .    .    .    .    .    0.67 .    .    .    .    .    .    .    .   
    ## Loney  .    .    .    0.40 .    0.20 .    .    .    .    .    .    0.20 .   
    ##                      
    ## Tedd   0.25 .    .   
    ## John   .    .    .   
    ## Mark   .    .    .   
    ## David  0.11 .    0.22
    ## Lia    0.20 .    .   
    ## Evan   0.14 0.29 0.14
    ## Ingrid .    .    .   
    ## Rosa   .    .    .   
    ## James  .    .    .   
    ## Tina   .    .    .   
    ## Robert .    .    .   
    ## Sims   .    .    .   
    ## Lady   .    .    0.25
    ## Lina   .    .    .   
    ## Rudy   .    .    .   
    ## Icha   .    .    0.33
    ## Loney  .    0.20 .
    # Regresi tanpa network
    model_reg1 <- lm(spending ~ income, data=model_node)
    summary(model_reg1)
    ## 
    ## Call:
    ## lm(formula = spending ~ income, data = model_node)
    ## 
    ## Residuals:
    ##     Min      1Q  Median      3Q     Max 
    ## -2.4649 -1.0666 -0.1154  0.8846  4.0392 
    ## 
    ## Coefficients:
    ##             Estimate Std. Error t value Pr(>|t|)    
    ## (Intercept) 14.07497    1.13795   12.37 2.86e-09 ***
    ## income       0.34958    0.03348   10.44 2.82e-08 ***
    ## ---
    ## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
    ## 
    ## Residual standard error: 1.731 on 15 degrees of freedom
    ## Multiple R-squared:  0.879,  Adjusted R-squared:  0.871 
    ## F-statistic:   109 on 1 and 15 DF,  p-value: 2.824e-08
    # Regresi dengan network
    wy <- w %*% model_node$spending
    model_reg2 <- lm(model_node$spending ~ as.vector(wy) + model_node$income)
    summary(model_reg2)
    ## 
    ## Call:
    ## lm(formula = model_node$spending ~ as.vector(wy) + model_node$income)
    ## 
    ## Residuals:
    ##     Min      1Q  Median      3Q     Max 
    ## -1.7890 -1.1027 -0.2725  1.3798  2.3228 
    ## 
    ## Coefficients:
    ##                   Estimate Std. Error t value Pr(>|t|)    
    ## (Intercept)        1.67772    4.19812   0.400  0.69546    
    ## as.vector(wy)      0.49248    0.16275   3.026  0.00907 ** 
    ## model_node$income  0.34960    0.02695  12.973 3.42e-09 ***
    ## ---
    ## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
    ## 
    ## Residual standard error: 1.394 on 14 degrees of freedom
    ## Multiple R-squared:  0.9269, Adjusted R-squared:  0.9164 
    ## F-statistic: 88.72 on 2 and 14 DF,  p-value: 1.118e-08

    Pada ringkasan hasil di atas, dapat disimpulkan bahwa model regresi klasik yang dikombinasikan dengan bobot jejaring memberikan nilai yang lebih baik dan signifikan dibanding tanpa jejaring.

    Stochastic Block Model

    Stochastic Block Model (SBM) adalah model data jejaring yang memformalkan ide bahwa setiap simpul dalam jejaring adalah milik suatu komunitas, dan bahwa setiap simpul membuat ikatan dengan simpul lain berdasarkan komunitasnya. Model ini digunakan untuk menggambarkan proses pembangkitan suatu graf data dimana simpul diatur ke dalam block (atau klaster atau kelompok).

    Banyak sekali algoritma yang digunakan dalam membangkitkan graf data pada SBM, salah satunya adalah Markov Chain Monte Carlo (MCMC). Model yang digunakan untuk membangkitkan data diacak ke suatu layout yang mungkin hingga fit pada data amatan. Teknik ini menghasilkan banyak kemungkinan model dengan berbagai layout graf yang proporsional dengan bentuk data yang digunakan.

    Beberapa pustaka yang mengimplementasikan simulasi pada SBM yaitu sbm, sbmR dan blockmodels.

    install.packages(blockmodels)
    gx_mat <- as.matrix(get.adjacency(gx))
    
    sbm_out <- BM_bernoulli("SBM", 
                            gx_mat, 
                            verbosity = 3, 
                            plotting = "",
                            exploration_factor = 5)
    sbm_out
    ## blockmodels object
    ##     model: bernoulli 
    ##     membership: SBM 
    ##     network: 7 x 7 scalar network 
    ##     Estimation not done.
    ##     Run $estimate(). You can specify a reinitialization effort, by default 1.
    sbm_out$estimate()
    ## -> Estimation for 1 groups
    ## 
    -> Computation of eigen decomposition used for initalizations
    ## 
    ## -> Pass 1
    ##     -> With ascending number of groups
    ##         -> For 2 groups
    ## 
            -> For 3 groups
    ## 
            -> For 4 groups
    ## 
            -> For 5 groups
    ## 
        -> With descending number of groups
    ##         -> For 4 groups
    ## 
    
            -> For 3 groups
    ## 
            -> For 2 groups
    ## 
    -> Pass 2
    ##     -> With ascending number of groups
    ##         -> For 2 groups
    ##         -> For 3 groups
    ## 
            -> For 4 groups
    ##         -> For 5 groups
    ##     -> With descending number of groups
    ##         -> For 4 groups
    ##         -> For 3 groups
    ##         -> For 2 groups
    # extract the fit which is best according to ICL (Integrated Completed Likelihood), a measure for selecting the best model
    best_fit_assignments <- sbm_out$memberships[[which.min(sbm_out$ICL)]] 
    # probabilities of belonging to each group
    best_fit_assignments$Z
    ##            [,1]       [,2]       [,3]       [,4]       [,5]
    ## [1,] 0.01369863 0.01369863 0.01369863 0.01369863 0.94520548
    ## [2,] 0.01369863 0.94520548 0.01369863 0.01369863 0.01369863
    ## [3,] 0.01369863 0.94520548 0.01369863 0.01369863 0.01369863
    ## [4,] 0.01369863 0.01369863 0.01369863 0.01369863 0.94520548
    ## [5,] 0.94520548 0.01369863 0.01369863 0.01369863 0.01369863
    ## [6,] 0.01369863 0.01369863 0.01369863 0.94520548 0.01369863
    ## [7,] 0.01369863 0.01369863 0.01369863 0.94520548 0.01369863
    class_assignments <- apply(best_fit_assignments$Z, 1, which.max)
    class_assignments
    ## [1] 5 2 2 5 1 4 4
    sbm_output = sna::blockmodel(gx_mat, 
                                 class_assignments, 
                                 glabels = "Contoh", 
                                 plabels = colnames(gx_mat))
    plot(sbm_output)

    plot(gx, vertex.color=class_assignments)

    Studi Kasus: Jenis Media di USA

    Berikut ini ada studi kasus untuk melihat jejaring berbagai jenis media di USA. Dua gugus data berukuran kecil berikut ini berisi organisasi yang bergerak di bidang media. Data pertama berisi media yang terkoneksi dengan sumber media lainnya melalui sebuah jejaring hyperlink dan mention. Data yang kedua berisi jejaring yang menghubungkan media dengan konsumer media tersebut.

    nodes <- read.csv("Dataset1-Media-Example-NODES.csv", header=T, as.is=T)
    head(nodes)
    ##    id               media media.type type.label audience.size
    ## 1 s01            NY Times          1  Newspaper            20
    ## 2 s02     Washington Post          1  Newspaper            25
    ## 3 s03 Wall Street Journal          1  Newspaper            30
    ## 4 s04           USA Today          1  Newspaper            32
    ## 5 s05            LA Times          1  Newspaper            20
    ## 6 s06       New York Post          1  Newspaper            50
    nrow(nodes)
    ## [1] 17
    length(unique(nodes$id))
    ## [1] 17
    links <- read.csv("Dataset1-Media-Example-EDGES.csv", header=T, as.is=T)
    head(links)
    ##   from  to weight      type
    ## 1  s01 s02     10 hyperlink
    ## 2  s01 s02     12 hyperlink
    ## 3  s01 s03     22 hyperlink
    ## 4  s01 s04     21 hyperlink
    ## 5  s04 s11     22   mention
    ## 6  s05 s15     21   mention
    nrow(links)
    ## [1] 52
    nrow(unique(links[,c("from", "to")]))
    ## [1] 49

    Penyesuaian edge yang lebih dari satu

    Penyesuaian edge yang lebih dari satu dengan cara menjumlahkan hubungannya menjadi suatu bobot

    links_weight <- aggregate(links[,3], links[,-3], sum)
    links_weight <- links_weight[order(links_weight$from, links_weight$to),]
    
    colnames(links_weight)[4] <- "weight"
    rownames(links_weight) <- NULL
    
    head(links_weight)
    ##   from  to      type weight
    ## 1  s01 s02 hyperlink     22
    ## 2  s01 s03 hyperlink     22
    ## 3  s01 s04 hyperlink     21
    ## 4  s01 s15   mention     20
    ## 5  s02 s01 hyperlink     23
    ## 6  s02 s03 hyperlink     21

    Eksplorasi graf

    Tahapan untuk membuat visualisasi graf dari data frame

    net <- graph_from_data_frame(d=links_weight, vertices=nodes, directed=T)
    net
    ## IGRAPH f72b98a DNW- 17 49 -- 
    ## + attr: name (v/c), media (v/c), media.type (v/n), type.label (v/c),
    ## | audience.size (v/n), type (e/c), weight (e/n)
    ## + edges from f72b98a (vertex names):
    ##  [1] s01->s02 s01->s03 s01->s04 s01->s15 s02->s01 s02->s03 s02->s09 s02->s10
    ##  [9] s03->s01 s03->s04 s03->s05 s03->s08 s03->s10 s03->s11 s03->s12 s04->s03
    ## [17] s04->s06 s04->s11 s04->s12 s04->s17 s05->s01 s05->s02 s05->s09 s05->s15
    ## [25] s06->s06 s06->s16 s06->s17 s07->s03 s07->s08 s07->s10 s07->s14 s08->s03
    ## [33] s08->s07 s08->s09 s09->s10 s10->s03 s12->s06 s12->s13 s12->s14 s13->s12
    ## [41] s13->s17 s14->s11 s14->s13 s15->s01 s15->s04 s15->s06 s16->s06 s16->s17
    ## [49] s17->s04
    # The edges of the "net" object
    E(net) 
    ## + 49/49 edges from f72b98a (vertex names):
    ##  [1] s01->s02 s01->s03 s01->s04 s01->s15 s02->s01 s02->s03 s02->s09 s02->s10
    ##  [9] s03->s01 s03->s04 s03->s05 s03->s08 s03->s10 s03->s11 s03->s12 s04->s03
    ## [17] s04->s06 s04->s11 s04->s12 s04->s17 s05->s01 s05->s02 s05->s09 s05->s15
    ## [25] s06->s06 s06->s16 s06->s17 s07->s03 s07->s08 s07->s10 s07->s14 s08->s03
    ## [33] s08->s07 s08->s09 s09->s10 s10->s03 s12->s06 s12->s13 s12->s14 s13->s12
    ## [41] s13->s17 s14->s11 s14->s13 s15->s01 s15->s04 s15->s06 s16->s06 s16->s17
    ## [49] s17->s04
    # Edge attribute "type"
    E(net)$type 
    ##  [1] "hyperlink" "hyperlink" "hyperlink" "mention"   "hyperlink" "hyperlink"
    ##  [7] "hyperlink" "hyperlink" "hyperlink" "hyperlink" "hyperlink" "hyperlink"
    ## [13] "mention"   "hyperlink" "hyperlink" "hyperlink" "mention"   "mention"  
    ## [19] "hyperlink" "mention"   "mention"   "hyperlink" "hyperlink" "mention"  
    ## [25] "hyperlink" "hyperlink" "mention"   "mention"   "mention"   "hyperlink"
    ## [31] "mention"   "hyperlink" "mention"   "mention"   "mention"   "hyperlink"
    ## [37] "mention"   "hyperlink" "mention"   "hyperlink" "mention"   "mention"  
    ## [43] "mention"   "hyperlink" "hyperlink" "hyperlink" "hyperlink" "mention"  
    ## [49] "hyperlink"
    # The vertices of the "net" object
    V(net) 
    ## + 17/17 vertices, named, from f72b98a:
    ##  [1] s01 s02 s03 s04 s05 s06 s07 s08 s09 s10 s11 s12 s13 s14 s15 s16 s17
    # Vertex attribute "media"
    V(net)$media 
    ##  [1] "NY Times"            "Washington Post"     "Wall Street Journal"
    ##  [4] "USA Today"           "LA Times"            "New York Post"      
    ##  [7] "CNN"                 "MSNBC"               "FOX News"           
    ## [10] "ABC"                 "BBC"                 "Yahoo News"         
    ## [13] "Google News"         "Reuters.com"         "NYTimes.com"        
    ## [16] "WashingtonPost.com"  "AOL.com"
    # Find nodes by attribute:
    # (that returns oblects of type vertex sequence)
    V(net)[media=="BBC"]
    ## + 1/17 vertex, named, from f72b98a:
    ## [1] s11
    # Find edges by attribute:
    # (that returns oblects of type edge sequence)
    E(net)[type=="mention"]
    ## + 20/49 edges from f72b98a (vertex names):
    ##  [1] s01->s15 s03->s10 s04->s06 s04->s11 s04->s17 s05->s01 s05->s15 s06->s17
    ##  [9] s07->s03 s07->s08 s07->s14 s08->s07 s08->s09 s09->s10 s12->s06 s12->s14
    ## [17] s13->s17 s14->s11 s14->s13 s16->s17
    # You can also examine the network matrix directly:
    net[1,]
    ## s01 s02 s03 s04 s05 s06 s07 s08 s09 s10 s11 s12 s13 s14 s15 s16 s17 
    ##   0  22  22  21   0   0   0   0   0   0   0   0   0   0  20   0   0
    net[5,7]
    ## [1] 0
    # Get an edge list or a matrix:
    igraph::as_edgelist(net, names=T)
    ##       [,1]  [,2] 
    ##  [1,] "s01" "s02"
    ##  [2,] "s01" "s03"
    ##  [3,] "s01" "s04"
    ##  [4,] "s01" "s15"
    ##  [5,] "s02" "s01"
    ##  [6,] "s02" "s03"
    ##  [7,] "s02" "s09"
    ##  [8,] "s02" "s10"
    ##  [9,] "s03" "s01"
    ## [10,] "s03" "s04"
    ## [11,] "s03" "s05"
    ## [12,] "s03" "s08"
    ## [13,] "s03" "s10"
    ## [14,] "s03" "s11"
    ## [15,] "s03" "s12"
    ## [16,] "s04" "s03"
    ## [17,] "s04" "s06"
    ## [18,] "s04" "s11"
    ## [19,] "s04" "s12"
    ## [20,] "s04" "s17"
    ## [21,] "s05" "s01"
    ## [22,] "s05" "s02"
    ## [23,] "s05" "s09"
    ## [24,] "s05" "s15"
    ## [25,] "s06" "s06"
    ## [26,] "s06" "s16"
    ## [27,] "s06" "s17"
    ## [28,] "s07" "s03"
    ## [29,] "s07" "s08"
    ## [30,] "s07" "s10"
    ## [31,] "s07" "s14"
    ## [32,] "s08" "s03"
    ## [33,] "s08" "s07"
    ## [34,] "s08" "s09"
    ## [35,] "s09" "s10"
    ## [36,] "s10" "s03"
    ## [37,] "s12" "s06"
    ## [38,] "s12" "s13"
    ## [39,] "s12" "s14"
    ## [40,] "s13" "s12"
    ## [41,] "s13" "s17"
    ## [42,] "s14" "s11"
    ## [43,] "s14" "s13"
    ## [44,] "s15" "s01"
    ## [45,] "s15" "s04"
    ## [46,] "s15" "s06"
    ## [47,] "s16" "s06"
    ## [48,] "s16" "s17"
    ## [49,] "s17" "s04"
    igraph::as_adjacency_matrix(net, attr="weight")
    ## 17 x 17 sparse Matrix of class "dgCMatrix"
    ##    [[ suppressing 17 column names 's01', 's02', 's03' ... ]]
    ##                                                      
    ## s01  . 22 22 21 .  .  .  .  .  .  .  .  .  . 20  .  .
    ## s02 23  . 21  . .  .  .  .  1  5  .  .  .  .  .  .  .
    ## s03 21  .  . 22 1  .  .  4  .  2  1  1  .  .  .  .  .
    ## s04  .  . 23  . .  1  .  .  .  . 22  3  .  .  .  .  2
    ## s05  1 21  .  . .  .  .  .  2  .  .  .  .  . 21  .  .
    ## s06  .  .  .  . .  1  .  .  .  .  .  .  .  .  . 21 21
    ## s07  .  .  1  . .  .  . 22  . 21  .  .  .  4  .  .  .
    ## s08  .  .  2  . .  . 21  . 23  .  .  .  .  .  .  .  .
    ## s09  .  .  .  . .  .  .  .  . 21  .  .  .  .  .  .  .
    ## s10  .  .  2  . .  .  .  .  .  .  .  .  .  .  .  .  .
    ## s11  .  .  .  . .  .  .  .  .  .  .  .  .  .  .  .  .
    ## s12  .  .  .  . .  2  .  .  .  .  .  . 22 22  .  .  .
    ## s13  .  .  .  . .  .  .  .  .  .  . 21  .  .  .  .  1
    ## s14  .  .  .  . .  .  .  .  .  .  1  . 21  .  .  .  .
    ## s15 22  .  .  1 .  4  .  .  .  .  .  .  .  .  .  .  .
    ## s16  .  .  .  . . 23  .  .  .  .  .  .  .  .  .  . 21
    ## s17  .  .  .  4 .  .  .  .  .  .  .  .  .  .  .  .  .
    # Or data frames describing nodes and edges:
    igraph::as_data_frame(net, what="edges")
    ##    from  to      type weight
    ## 1   s01 s02 hyperlink     22
    ## 2   s01 s03 hyperlink     22
    ## 3   s01 s04 hyperlink     21
    ## 4   s01 s15   mention     20
    ## 5   s02 s01 hyperlink     23
    ## 6   s02 s03 hyperlink     21
    ## 7   s02 s09 hyperlink      1
    ## 8   s02 s10 hyperlink      5
    ## 9   s03 s01 hyperlink     21
    ## 10  s03 s04 hyperlink     22
    ## 11  s03 s05 hyperlink      1
    ## 12  s03 s08 hyperlink      4
    ## 13  s03 s10   mention      2
    ## 14  s03 s11 hyperlink      1
    ## 15  s03 s12 hyperlink      1
    ## 16  s04 s03 hyperlink     23
    ## 17  s04 s06   mention      1
    ## 18  s04 s11   mention     22
    ## 19  s04 s12 hyperlink      3
    ## 20  s04 s17   mention      2
    ## 21  s05 s01   mention      1
    ## 22  s05 s02 hyperlink     21
    ## 23  s05 s09 hyperlink      2
    ## 24  s05 s15   mention     21
    ## 25  s06 s06 hyperlink      1
    ## 26  s06 s16 hyperlink     21
    ## 27  s06 s17   mention     21
    ## 28  s07 s03   mention      1
    ## 29  s07 s08   mention     22
    ## 30  s07 s10 hyperlink     21
    ## 31  s07 s14   mention      4
    ## 32  s08 s03 hyperlink      2
    ## 33  s08 s07   mention     21
    ## 34  s08 s09   mention     23
    ## 35  s09 s10   mention     21
    ## 36  s10 s03 hyperlink      2
    ## 37  s12 s06   mention      2
    ## 38  s12 s13 hyperlink     22
    ## 39  s12 s14   mention     22
    ## 40  s13 s12 hyperlink     21
    ## 41  s13 s17   mention      1
    ## 42  s14 s11   mention      1
    ## 43  s14 s13   mention     21
    ## 44  s15 s01 hyperlink     22
    ## 45  s15 s04 hyperlink      1
    ## 46  s15 s06 hyperlink      4
    ## 47  s16 s06 hyperlink     23
    ## 48  s16 s17   mention     21
    ## 49  s17 s04 hyperlink      4
    igraph::as_data_frame(net, what="vertices")
    ##     name               media media.type type.label audience.size
    ## s01  s01            NY Times          1  Newspaper            20
    ## s02  s02     Washington Post          1  Newspaper            25
    ## s03  s03 Wall Street Journal          1  Newspaper            30
    ## s04  s04           USA Today          1  Newspaper            32
    ## s05  s05            LA Times          1  Newspaper            20
    ## s06  s06       New York Post          1  Newspaper            50
    ## s07  s07                 CNN          2         TV            56
    ## s08  s08               MSNBC          2         TV            34
    ## s09  s09            FOX News          2         TV            60
    ## s10  s10                 ABC          2         TV            23
    ## s11  s11                 BBC          2         TV            34
    ## s12  s12          Yahoo News          3     Online            33
    ## s13  s13         Google News          3     Online            23
    ## s14  s14         Reuters.com          3     Online            12
    ## s15  s15         NYTimes.com          3     Online            24
    ## s16  s16  WashingtonPost.com          3     Online            28
    ## s17  s17             AOL.com          3     Online            33
    plot(net)

    Graf tersebut tidak cukup mudah untuk diinterpretasi, sehingga perlu dilakukan beberapa pengaturan:

    • menghilangkan loops
    • menghilangkan label
    net <- simplify(net, remove.multiple = F, remove.loops = T)
    plot(net, edge.arrow.size=.4,vertex.label=NA)

    Pelabelan bedasarkan nama node

    plot(net, edge.arrow.size=.2, edge.color="orange",
    vertex.color="orange", vertex.frame.color="#ffffff",
    vertex.label=V(net)$media, vertex.label.color="black")

    Melakukan beberapa pengaturan dalam membuat visualisasi network

    # Generate colors based on media type:
    colrs <- c("gray50", "tomato", "gold")
    V(net)$color <- colrs[V(net)$media.type]
    # Compute node degrees (#links) and use that to set node size:
    deg <- degree(net, mode="all")
    V(net)$size <- deg*3
    # We could also use the audience size value:
    V(net)$size <- V(net)$audience.size*0.6
    # The labels are currently node IDs.
    # Setting them to NA will render no labels:
    V(net)$label <- NA
    # Set edge width based on weight:
    E(net)$width <- E(net)$weight/6
    #change arrow size and edge color:
    E(net)$arrow.size <- .2
    E(net)$edge.color <- "gray80"
    E(net)$width <- 1+E(net)$weight/12
    plot(net)
    legend(x=-1.5, y=-1.1, c("Newspaper","Television", "Online News"), pch=21,
    col="#777777", pt.bg=colrs, pt.cex=2, cex=.8, bty="n", ncol=1)

    Beberapa layout yang disediakan pada paket igraph

    layouts <- grep("^layout_", ls("package:igraph"), value=TRUE)[-1]
    # Remove layouts that do not apply to our graph.
    layouts <- layouts[!grepl("bipartite|merge|norm|sugiyama|tree", layouts)]
    
    
    par(mfrow=c(3,3), mar=c(1,1,1,1))
    for (layout in layouts) {
      print(layout)
      l <- do.call(layout, list(net))
      plot(net, edge.arrow.mode=0, layout=l, main=layout) 
    }
    ## [1] "layout_as_star"
    ## [1] "layout_components"
    ## [1] "layout_in_circle"
    ## [1] "layout_nicely"
    ## [1] "layout_on_grid"
    ## [1] "layout_on_sphere"
    ## [1] "layout_randomly"
    ## [1] "layout_with_dh"
    ## [1] "layout_with_drl"

    ## [1] "layout_with_fr"
    ## [1] "layout_with_gem"
    ## [1] "layout_with_graphopt"
    ## [1] "layout_with_kk"
    ## [1] "layout_with_lgl"
    ## [1] "layout_with_mds"

    Ukuran sentralitas

    cen_deg <- sort(igraph::degree(net, loops = FALSE)/(vcount(net)-1), decreasing = TRUE)[1:3]
    cen_clo <- sort(igraph::closeness(net), decreasing = TRUE)[1:3]
    cen_bet <- sort(2*igraph::betweenness(net)/((vcount(net) - 1)*(vcount(net)-2)), decreasing = TRUE)[1:3]
    cen_evc <- sort(igraph::evcent(net)[[1]], decreasing = TRUE)[1:3]
    cen_pgr <- sort(page.rank(net)[[1]], decreasing = TRUE)[1:3]

    Jenis media yang menjadi node sentral berdasarkan masing-masing ukuran sentralitas dapat dilihat pada tabel berikut

    rank degree closeness betweenness eigenvector pagerank
    1 Wall Street Journal CNN Wall Street Journal NY Times Wall Street Journal
    2 USA Today Wall Street Journal USA Today Wall Street Journal USA Today
    3 NY Times MSNBC AOL.com Washington Post NY Times

    Media Wall Street Jurnal memiliki nilai yang tinggi pada ukuran degree, betweenness dan PageRank, sedangkan perhitungan closeness dan eigenvector memberikan hasil yang berbeda dimana CNN dan NY Times dianggap sebagai media yang berpengaruh dengan skor yang paling tinggi.

    Deteksi komunitas

    # berdasarkan edge betweenness
    comm_detect_eb <- cluster_edge_betweenness(net) 
    ## Warning in cluster_edge_betweenness(net): At
    ## core/community/edge_betweenness.c:492 : Membership vector will be selected based
    ## on the highest modularity score.
    dendPlot(comm_detect_eb, mode="hclust")

    # berdasarkan propagasi label
    comm_detect_lp <- cluster_label_prop(net)
    # berdasarkan optimisasi greedy
    comm_detect_fg <- cluster_fast_greedy(as.undirected(net))
    par(mfrow=c(1,3))
    plot(comm_detect_eb, 
         net, 
         vertex.size = 0.5*V(net)$audience.size, 
         asp=0
    )
    plot(comm_detect_lp,
         net, 
         vertex.size = 0.5*V(net)$audience.size, 
         asp=0
    )
    plot(comm_detect_fg,
         as.undirected(net),
         vertex.size = 0.5*V(net)$audience.size, 
         asp=0
    )

    Visualisasi Jejaring Interaktif

    dengan visNetwork

    visNetwork membuat visualisasi jejaring secara interaktif menggunakan library javascript vis.js

    install.packages('visNetwork')
    visNetwork(
      nodes = NULL, 
      edges = NULL, 
      dot = NULL, 
      gephi = NULL,
      width = NULL, 
      height = NULL, 
      main = NULL, 
      submain = NULL, 
      footer = NULL, 
      background = "rgba(0, 0, 0, 0)",
      ...
    )
    nod <- data.frame(
      id = nodes$id,
      label = nodes$media,
      group = nodes$media.type,
      shape = "circle",
      title = nodes$media,
      color = nodes$media.type,
      shadow = TRUE
    )
    kable(head(nod))
    id label group shape title color shadow
    s01 NY Times 1 circle NY Times 1 TRUE
    s02 Washington Post 1 circle Washington Post 1 TRUE
    s03 Wall Street Journal 1 circle Wall Street Journal 1 TRUE
    s04 USA Today 1 circle USA Today 1 TRUE
    s05 LA Times 1 circle LA Times 1 TRUE
    s06 New York Post 1 circle New York Post 1 TRUE
    edg <- data.frame(
      from = links$from,
      to = links$to,
      label = paste("Edge", 1:length(links$from)), # labels
      length = 100,
      arrows = "to",
      dashes = TRUE,
      title = paste("Edge", 1:length(links$from)),
      smooth = TRUE, # smooth
      shadow = TRUE
    )
    kable(head(edg))
    from to label length arrows dashes title smooth shadow
    s01 s02 Edge 1 100 to TRUE Edge 1 TRUE TRUE
    s01 s02 Edge 2 100 to TRUE Edge 2 TRUE TRUE
    s01 s03 Edge 3 100 to TRUE Edge 3 TRUE TRUE
    s01 s04 Edge 4 100 to TRUE Edge 4 TRUE TRUE
    s04 s11 Edge 5 100 to TRUE Edge 5 TRUE TRUE
    s05 s15 Edge 6 100 to TRUE Edge 6 TRUE TRUE
    # We'll start by adding new node and edge attributes to our dataframes. 
    vis.nodes <- nodes
    vis.links <- links
    
    vis.nodes$shape  <- "dot"  
    vis.nodes$shadow <- TRUE # Nodes will drop shadow
    vis.nodes$title  <- vis.nodes$media # Text on click
    vis.nodes$label  <- vis.nodes$type.label # Node label
    vis.nodes$size   <- vis.nodes$audience.size # Node size
    vis.nodes$borderWidth <- 2 # Node border width
    
    vis.nodes$color.background <- c("slategrey", "tomato", "gold")[nodes$media.type]
    vis.nodes$color.border <- "black"
    vis.nodes$color.highlight.background <- "orange"
    vis.nodes$color.highlight.border <- "darkred"
    
    visNetwork(vis.nodes, vis.links)

    Berikutnya ubah beberapa properti visual pada edge

    vis.links$width <- 1+links$weight/8 # line width
    vis.links$color <- "gray"    # line color  
    vis.links$arrows <- "middle" # arrows: 'from', 'to', or 'middle'
    vis.links$smooth <- FALSE    # should the edges be curved?
    vis.links$shadow <- FALSE    # edge shadow
    
    visnet <- visNetwork(vis.nodes, vis.links)
    visnet
    visOptions(visnet, highlightNearest = TRUE, selectedBy = "type.label")

    dengan networkD3

    links.d3 <- data.frame(
      from=as.numeric(factor(links$from))-1, 
      to=as.numeric(factor(links$to))-1
    )
    
    nodes.d3 <- cbind(idn=factor(nodes$media, levels=nodes$media), nodes) 
    
    forceNetwork(Links = links.d3, Nodes = nodes.d3, Source="from", Target="to",
                   NodeID = "idn", Group = "type.label",linkWidth = 1,
                   linkColour = "#afafaf", fontSize=12, zoom=T, legend=T,
                   Nodesize=6, opacity = 0.8, charge=-300, 
                   width = 600, height = 400)