Pendahuluan

Manusia merupakan makhlus sosial dimana interaksi sosial merupakan salah satu kebutuhan utamanya. Saat ini ada banyak cara untuk melakukan interaksi sosial diantaranya dengan memanfaatkan media sosial. Media sosial merupakan tools untuk mempermudah manusia dalam berinterkasi dan berbagai informasi.

Melalui media sosial, manusia dapat berinterkasi dengan mudah dan cepat tanpa dibatasi dengan kondisi geografis, kita bisa berinteraksi dengan orang yang sangat jauh secara geografis dengan cepat. Interkasi yang terjadi melalui media sosial menghasilkan data yang bisa dianalisa untuk mengetahui interkasi yang terjadi antar pengguna. Salah satu bentuk analisa yang bisa digunakan adalah social network analysis.

Social Network Analysis

Social Network Analysis (SNA) merupakan sebuah teknik analisa hubungan/interaksi yang terjadi antar manusia dengan memanfaatkan teori graf.Interaksi antar manusia pun jadi jauh lebih mudah dianalisa dengan adanya media sosial, hal ini dikarenakan data tersebut terekam dan tersimpan oleh pemegang aplikasi. Data yang tersimpan dapat dimanfaatikan untuk mencari tahu “key player” dalam persebaran informasi, selain itu kita juga bisa mengetahui cluster pengguna dari suatu topik yang dibahas.

Library

library(tidyverse)

# graph
library(tidygraph)
library(ggraph)
library(igraph)

Exploratory Data Analysis

Membaca data dan melihat sampel dari data.

tweets <- read_rds("nft.RDS")
head(tweets, 10)

Mengetahui jumlah yang merupakan retweet, quote dan bukan keduanya.

tweets %>% 
  count(is_retweet, is_quote)

Melihat ringkasan statistik data dan mengetahui pemilik retweet terbanyak.

tweets %>% 
  filter(is_retweet) %>% 
  select(retweet_count) %>% 
  summary()
##  retweet_count  
##  Min.   :    0  
##  1st Qu.:   88  
##  Median :  458  
##  Mean   : 1379  
##  3rd Qu.: 1395  
##  Max.   :49552

Melalui data ringkasan statistik di atas dapat diketahui terjadi perbedaan yang sangat besar antara nilai tengah (median) dan nilai kuartil 3 alias terjadi penyebaran jumlah retweet yang tidak merata. Ketidakmerataan ini juga didukung oleh range data yang sangat besar yakni 49552 tetapi median dan meannya hanya 1000-an.

tweets %>% 
  filter(retweet_count == max(retweet_count))

Dapat diketahui secreen_name yang memiliki retweet terbanyak adalah binary_et dengan 49552 retweet.Dalam retweetnya tersebut ia membahas tentang isu yang sedang populer yaitu NFT, mengenai ancaman dan usaha untuk menghindari ancaman mengenai NFT. Jadi dalam pembahannya cukup populer dan informatif.

Data cleansing

Pertama, kita perlu mengambil kolom ‘secreen_name’ dan ‘mentions_secreen_name’

tweets %>%
  select(screen_name,mentions_screen_name)

Kedua, membersihkan string di kolom mentions_secreen_name

tweets %>% 
  select(screen_name,mentions_screen_name) %>% 
  mutate(mentions_screen_name =str_remove_all(string = mentions_screen_name, 
                                               pattern = "^c\\(|\\)$")) # menghapus tanda c()

Ketiga, memisahkan beberapa nama dalam kolom mention_screen_name menjadi beberapa baris. Lalu menghapus missing value (NA) alias data yang kosong dengan fungsi na.omit(). Kemudian menghapus tanda baca. Selanjutnya mengubah nama kolom menjadi from dan to. Terakhir yaitu simpan semua proses ketiga ini dalam fungsi edge_df. Intinya sedang membuat garis (link/edge) yang menghubungkan setiap titik(nodes).

edge_df <- # simpan dalam fungsi edge_df
 tweets %>% 
  select(screen_name,mentions_screen_name) %>% 
  mutate(mentions_screen_name =str_replace_all(string = mentions_screen_name, 
                                               pattern =  "^c\\(|\\)$", 
                                               replacement = "")) %>% 
  separate_rows(mentions_screen_name,sep = ",") %>% # memisahkan data menjadi beberapa baris berdasarkan koma (,)
  na.omit() %>%  # menghapus NA pada data
  mutate(mentions_screen_name =str_replace_all(string = mentions_screen_name, # menghapus tanda baca pada kolom `mention_screen_name`
                                               pattern =  "[[:punct:] ]+", 
                                               replacement = "")) %>% 
  rename(from = screen_name, # mengubah nama kolom
         to = mentions_screen_name)
head(edge_df)

Membuat data frame yang bernama node_df yang mana ini berisi kumpulan secreen_name yang ada pada data edge_df. Intinya tahap ini sedang membuat nodes atau titiknya sehingga setiap titik cukup diwakili satu saja karena apabila lebih dari 1 menyebabkan kesulitan melihat pengaruh dari titik tersebut, dengan demikian menggunakan unique value.

# create nodes dataframe by unique value in both edges column
nodes_df <- data.frame(name = unique(c(edge_df$from,edge_df$to)))

tail(nodes_df)

Setelah memiliki edge dan nodes, kita akan membuat graph dengan menggunakan tbl_graph() dan menggunakan parameter directed adalah false alias hubungan nodesnya undirected.

graph_tweets <- tbl_graph(nodes = nodes_df,
                          edges = edge_df,
                          directed = FALSE)

Centrality Measurement

Kemudian kita akan menghitung nilai centrality dengan menggunakan 4 ukuran yakni degree, betweenness, closeness dan eigen.

graph_tweets <- graph_tweets %>%
  activate(nodes) %>% 
  mutate(degree = centrality_degree(), # Calculate degree centrality
         between = centrality_betweenness(normalized = T), # Calculate betweenness centrality
         closeness = centrality_closeness(), # Calculate closeness centrality
         eigen = centrality_eigen() # Calculate eigen centrality
         )

Mengambil nilai centrality tersebut kemudian ubah menjadi data frame agar lebih mudah dianalisa lebih lanjut.

network_act_df <- graph_tweets %>% 
  activate(nodes) %>% 
  as.data.frame()

head(network_act_df)

Melalui data di atas kita dapat melihat masing-masing node memiliki nilai centrality yang sangat beragam.

Mencari tau user name yang memiliki nilai tertinggi untuk masing-masing ukuran centrality dengan cara mengubahnya menjadi format dibawah. Kita akan menampilkan 5 teratas dari setiap ukuran.

kp_activity <- data.frame(
  #Degree
  network_act_df %>% 
    arrange(-degree) %>% 
    select(name) %>% 
    slice(1:5),
  #Betweenness
  network_act_df %>% 
    arrange(-between) %>% 
    select(name) %>% 
    slice(1:5),
  #Closeness
  network_act_df %>% 
    arrange(-closeness) %>% 
    select(name) %>%
    slice(1:5),
  # Eigenvector
  network_act_df %>%
    arrange(-eigen) %>%
    select(name) %>% 
    slice(1:5)
) %>% setNames(c("degree","betweenness","closeness","eigen")) # memberi nama data frame
kp_activity
  • Melalui data di atas dapat diketahui akun nftspartan memiliki ukuran degree(fokus ke banyaknya hubungan saja) tertinggi sehingga dapat disimpulkan akun ini yang paling populer secara lokal.
  • Berbeda dengan ukuran eigenvector yang dapat memberikan ukuran populer secara luas (global) karena mempertimbangkan banyaknya hubungan dan cenderung akun yang terhubung tersebut memiliki tetangga yang cukup besar (alias yang terhubung adalah orang yang cukup populer juga). Sehingga akun yang populer secara luas adalah mandytn98.
  • Selanjutnya akun yang paling dekat secara keselurahan dengan akun lainya (closeness) dan paling menjadi penghubung antar akun/kelompok (betweenness) adalah akun yang sama yakni GenWealth0.

Graph Visualization

Nodes yang dimiliki dalam proses ini cenderung sangat besar sehingga alangkah lebih baik apabila dikelompokkan (clustering) agar memudahkan kita dalam melakukan interpretasi.

set.seed(29)
graph_tweets <- graph_tweets %>% 
  activate(nodes) %>%  # aktivasi nodes
  mutate(community = group_louvain()) %>% # Melakukan clustering dengan louvain()
  activate(edges) %>%  # aktivasi edges
  filter(!edge_is_loop()) # Remove loop edges()
graph_tweets %>% 
  activate(nodes) %>% 
  as.data.frame() %>% 
  count(community)

Membuat fungsi agar mendapatkan orang-orang penting di tiap cluster.

important_user <- function(data) {
  
  name_person <- data %>%
  as.data.frame() %>%  # mengubah nodes menjadi dataframe
  filter(community %in% 1:5) %>% # Mengambil community yang bernilai 1 sampai 5
  select(-community) %>%  # Menghapus kolom community
  pivot_longer(-name, names_to = "measures", values_to = "values") %>% # mengubah format data wide menjadi long format
  group_by(measures) %>% # data diurutkan berdasarkan measures(nilai centrality
  arrange(desc(values)) %>% # diurutkan datanya berdasarkan nilai centrality
  slice(1:6) %>% # diambil 6 nilai terbesar dari masing-masing centrality
  ungroup() %>% # pengelompokan data dilepaskan
  distinct(name) %>% # mengambil nama-nama yang uniqe
  pull(name) # Mengambil kolom nama saja
  
  return(name_person)
}
important_person <- 
graph_tweets %>% 
  activate(nodes) %>% 
  important_user()

important_person
##  [1] "GenWealth0"     "opensea"        "nftspartan"     "TastyBonesNFT" 
##  [5] "misscryptolog"  "CryptoCluckz"   "smolrunnersNFT" "JAYNFTs"       
##  [9] "REALSWAK"       "CryptoKing1st"  "snowcorp"       "mandytn98"     
## [13] "Arizona998"     "mandyyyNFT"     "meganXONFT"     "veejayart"     
## [17] "Gabby_NFT"

Melakukan visualisasi data graph yang telah dibuat.

set.seed(17)
graph_tweets %>%
  activate(nodes) %>%
  mutate(ids = row_number(),
         community = as.character(community)) %>%
  filter(community %in% 1:5) %>%    # ubah berdasarkan jumlah cluster yang ingin di analisa 1:berapa?
  arrange(community,ids) %>%
  mutate(node_label = ifelse(name %in% important_person, name,NA)) %>%
  ggraph(layout = "fr") +
  geom_edge_link(alpha = 0.3 ) +
  geom_node_point(aes(size = degree, fill = community), shape = 21, alpha = 0.7, color = "grey30") +
  geom_node_label(aes(label = node_label), repel = T, alpha = 0.3 ) +
  guides(size = "none") +
  labs(title = "Top 5 Community of NFT", # judul plot
       color = "Interaction",
       fill = "Community") + # legend warna
  theme_void() +
  theme(legend.position = "top")

Kesimpulan

Melalui visualisasi graph di atas, kita dapat melihat terdapat 5 cluster. Setiap cluster memiliki beberapa akun penting berdasarkan nilai centralitynya. Semakin besar ukuran node menandakan semakin populer node tersebut. Selain itu, visualisasi ini juga menunjukan kerapatan masing-masing cluster yang berbeda, semakin rapat suatu cluster maka persebaran informasi semakin efisien.