Akhir-akhir ini sering sekali mendengar istilah NFT yaitu Non Fungible Token. NFT adalah salah satu aset investasi yang termasuk ke dalam hal mata uang kripto. NFT sendiri adalah aset digital yang bisa digunakan sebagai bukti kepemilikan barang yang dapat dibeli dengan mata uang kripto. NFT meliputi berbagai bidang seperti karya seni, video klip, musik, game dan lain sebagainya.
NFT mulai dikenal pada tahun 2017 saat game NFT, yakni Crypto Kitties diluncurkan. Di situ, pengguna bisa bermain game dengan basis blockchain Ethereum. Mereka bisa mengadopsi, memelihara hingga memperdagangkan kucing peliharaan secara virtual. Belakangan dunia maya di Indonesia juga dihebohkan oleh sosok Ghozali yang berhasil meraup keuntungan hingga miliaran rupiah melalui penjualan foto selfienya di marketplace NFT.
Kali ini saya akan melakukan Social Network Analysis melalui perbincangan di Twitter mengenai NFT, siapa-siapa saja yang menjadi pusat pembicaraannya dan apa yang dibicarakan.
Untuk dapat menajalankan analisis ini, berikut ini adalah beberapa packages yang diperlukan sebagai alat bantu:
library(tidyverse)
# graph
library(tidygraph)
library(ggraph)
library(igraph)
Setelah memanggil package yang diperlukan saya akan memanggil data bernama nft.RDS
yang kemudian akan disimpan (assign) ke data bernama tweets:
tweets <- read_rds("nft.RDS")
head(tweets)
Dari data dapat diketahui bahwa melalui kolom is_retweet
kita dapat melakukan filter mana yang retweet mana yang bukan, kemudian menghitung jumlah baris dari semua data yang retweet saja dengan syntax berikut:
tweets %>%
filter(is_retweet == TRUE) %>%
do(data.frame(retweet_count=nrow(.)))
Dapat diketahui bahwa ada 13,058 retweet.
Kemudian dapat diketahui juga akun (screen_name) dengan jumlah retweet berbanyak dengan syntax berikut:
tweets %>%
filter(retweet_count == max(retweet_count)) %>%
select(screen_name, retweet_count)
Dapat diketahui bahwa akun b1nary_eth memiliki jumlah retweet terbanyak yaitu 49,552 retweet.
Pada social network analysis setiap node direpresentasikan dengan user_name (screen_name
) sedangkan edge bisa direpresentasikan dengan hubungan yang ada mention, retweet, maupun quote. Pada proses analisis kali ini saya akan melihat keterhubungan antar user berdasarkan mention yang ada pada tweet.
Tujuan dari proses cleansing ini untuk membuat raw data yang ada siap digunakan dalam proses pembuatan graph. Tahapan awal dari proses cleansing yaitu mengambil kolom screen_name
, dan mentions_screen_name
menggunakan select()
, kemudian membersihkan string pada kolom mention_screen_name
.
tweets %>%
select(screen_name,mentions_screen_name)
Dari tabel diketahui bahwa mentions_screen_name
berisi kode-kode aneh, ternyata karena tipe datanya adalah list. Dengan demikian kita harus mengubah tipe datanya terlebih dahulu menjadi character.
tweets %>%
mutate(mentions_screen_name = as.character(mentions_screen_name)) %>%
select(screen_name,mentions_screen_name)
Sekarang data di kolom mentions_screen_name
dapat terlihat, namun masih terdiri dari beberapa nama dalam satu baris, berikut tahapan pembersihannya:
mentions_screen_name
. Proses penghapusan string dengan pattern tertentu dapat dilakukan dengan fungsi str_remove_all()
kemudian masukkan pattern yang ingin di remove dan menggantinya dengan spasi (replacement = ""
).-Data di kolom mentions_screen_name
perlu dipisah menjadi beberapa baris dengan fungsi separate_rows()
.
Membuang semua data yang mengandung NA
(kosong) dengan fungsi na.omit()
.
Membuang tanda petik (“) yang tertinggal pada kolom mentions_screen_name
.
Mengubah nama kolom screen_name
menjadi from
dan mentions_screen_name
dengan to
.
Menyimpannya menjadi data baru meenjadi Data Edges bernama edge_df
.
edge_df <-
tweets %>%
select(screen_name,mentions_screen_name) %>%
mutate(mentions_screen_name = as.character(mentions_screen_name),
mentions_screen_name = str_replace_all(string =mentions_screen_name,
pattern = "^c\\(|\\)$",
replacement = "")) %>%
separate_rows(mentions_screen_name, sep = ",") %>%
na.omit() %>%
mutate(mentions_screen_name = str_replace_all(string =mentions_screen_name,
pattern = "[[:punct:] ]+",
replacement = "")) %>%
rename(from = screen_name,
to = mentions_screen_name)
head(edge_df)
Setelah melakukan data cleansing untuk membuat data edges, satu lagi data yang dibutuhkan yaitu data nodes. Data nodes bisa didapatkan dari semua user name yang ada pada data edges.
nodes_df <- data.frame(name = unique(c(edge_df$from,edge_df$to)))
tail(nodes_df)
Setelah mendapatkan semua data, sekarang graph bisa dibentuk dengan menggunakan fungsi tbl_graph()
. Pada parameter directed kita menggunakan FALSE yang berarti graph ini merupakan undirected graph, dengan membuatnya menjadi undirected hubungan antar node dapat dilihat dari 2 arah.
graph_tweets <- tbl_graph(nodes = nodes_df,
edges = edge_df,
directed = F)
Setelah membuat graph selanjutnya menghitung nilai centrality untuk tiap node. Ukuran centrality yang digunakan disini ada 4 yaitu degree, betweenness, closeness dan eigen.
graph_tweets <- graph_tweets %>%
activate(nodes) %>%
mutate(degree = centrality_degree(),
between = centrality_betweenness(normalized = T),
closeness = centrality_closeness(),
eigen = centrality_eigen())
Untuk melihat hasil dari perhitungan centrality diatas, data nodes dapat diambil dalam bentuk dataframe agar lebih mudah dianalisa lebih lanjut.
network_act_df <- graph_tweets %>%
activate(nodes) %>%
as.data.frame()
head(network_act_df)
Dari data diatas bisa dilihat tiap node memiliki nilai centrality yang berbeda beda, untuk mengetahui user name yang memiliki nilai tertinggi untuk masing-masing ukuran centrality kita dapat mengubahnya menjadi format dibawah.
network_act_df %>%
arrange(-eigen) %>%
select(name) %>%
slice(1:6)
kp_activity <- data.frame(
network_act_df %>% arrange(-degree) %>% select(name) %>% slice(1:6),
network_act_df %>% arrange(-between) %>% select(name) %>% slice(1:6),
network_act_df %>% arrange(-closeness) %>% select(name) %>% slice(1:6),
network_act_df %>% arrange(-eigen) %>% select(name) %>% slice(1:6)
) %>% setNames(c("degree","betweenness","closeness","eigen"))
kp_activity
Dari data diatas kita bisa melihat bahwa akun nftspartan merupakan akun dengan degree tertinggi. Sedangkan, akun mandytn98 merupakan akun dengan eigen tertinggi. Setelah dicek nftspartan sebelum dibersihkan datanya tertulis nft_spartan merupakan salah satu NFT collector & investor dengan follower lebih dari 23k. Sebaliknya, mandytn98 ketika dicek akun ini nampaknya sudah mengganti handle name (nama akun) menjadi hanna99eth, dan followernya ternyata cukup sedikit.
Kemudian muncul juga akun opensea yang mana dikenal sebagai NFT Marketplace
Kepopuleran dua akun ini nampaknya lebih ke konteks pembicaraan di twitter, mungkin keduanya sumber dari pembicaraan tersebut. Mari kita lihat apa yang dibicarakan
tweets %>%
filter(mentions_screen_name == "nft_spartan") %>%
arrange(desc(retweet_count)) %>%
distinct(text) %>%
pull(text)
## [1] "NFT GUIDE FOR BEGINNERS : A TREAD 🧵\n\nI will give 100$ to a random RT of this thread! \nNow lets go."
## [2] "SUMMARY:\n \n1 - How to find good projects\n\n2 - How to analyze each project from A to Z and find the redflags at first sight\n\n3 - Mint an NFT : Mint from the contract and from the site\n\n4 - Scams : different scams to avoid and how to avoid them\n\n5 - Tools"
## [3] "@nft_spartan Praying"
## [4] "@nft_spartan https://t.co/z03WGTn0Aa"
## [5] "@nft_spartan https://t.co/GYpCrs2lAH"
## [6] "@nft_spartan i’m grateful 🤍 https://t.co/RfZ2a7TsiV"
## [7] "@nft_spartan Done... https://t.co/hbrD27f8xL"
## [8] "@nft_spartan Done"
## [9] "@nft_spartan Done https://t.co/e2wMKgkAfM"
## [10] "@nft_spartan https://t.co/EBf8jKpYPc"
## [11] "@nft_spartan https://t.co/vAleGS8ir5"
## [12] "@nft_spartan Done... Hope to win please... Tysm 😘😘😘 https://t.co/j5q2JU4OGw"
## [13] "@nft_spartan Done po https://t.co/ReA2WB8EJA"
## [14] "@nft_spartan https://t.co/8hj3VbFCAJ"
## [15] "@nft_spartan Done following with notifs on https://t.co/eN4IdmqYkl"
## [16] "@nft_spartan https://t.co/z2mSynMnCo"
## [17] "@nft_spartan https://t.co/QDLmxLmyAo"
## [18] "@nft_spartan Bigwin 😇 https://t.co/D8pVOBNXhd"
## [19] "@nft_spartan https://t.co/cHkd2jZTqQ"
## [20] "@nft_spartan https://t.co/AEPKdA5nl1"
## [21] "@nft_spartan https://t.co/4CYzpURSlU"
## [22] "@nft_spartan https://t.co/NqlThho1oy"
## [23] "@nft_spartan Done https://t.co/V6hTr3L0qn"
## [24] "@nft_spartan https://t.co/VGn8KXMPwp"
## [25] "@nft_spartan https://t.co/CPFK4nhFbt"
## [26] "@nft_spartan On 👉🔔 https://t.co/ducVGjCHQc"
## [27] "@nft_spartan https://t.co/tpHGLhTpH6"
## [28] "@nft_spartan D588 https://t.co/hX53O0EUAZ"
## [29] "@nft_spartan https://t.co/NVY5q1vSeP"
## [30] "@nft_spartan Done ✅✅✅✅ https://t.co/je4V4iYDE1"
## [31] "@nft_spartan Awesome giveaway, Thanks for the generosity!!🎉"
## [32] "@nft_spartan https://t.co/DfYF3ax6HR"
## [33] "@nft_spartan Done 🎊🎉 wml 🤲😷♉ gbu all https://t.co/TiBehXbirC"
## [34] "@nft_spartan I've done everything, I hope the gift is mine❤"
## [35] "@nft_spartan https://t.co/tkE7yhbEem"
## [36] "@nft_spartan done https://t.co/au6ajRlgLV"
## [37] "@nft_spartan https://t.co/47i7aKSKlx"
## [38] "@nft_spartan Done https://t.co/ymzqLw1dOj"
## [39] "@nft_spartan Done https://t.co/JMDWPHWJ5h"
## [40] "@nft_spartan done"
## [41] "@nft_spartan Thanks for this chance 🥰 done ✅ hoping to win 🙏🙂 wish me luck 🤞🍀🤞 https://t.co/ASZGMfJRQD"
## [42] "@nft_spartan https://t.co/WBuJQPQqXW"
## [43] "@nft_spartan https://t.co/qi5B0hPvfb"
## [44] "@nft_spartan https://t.co/KOeGHTU2gQ"
## [45] "@nft_spartan https://t.co/CsLRM9jRoA"
## [46] "@nft_spartan https://t.co/XYHoS4nEiG"
## [47] "@nft_spartan https://t.co/cnJCwqAwvW"
## [48] "@nft_spartan Done🌿🌿🌿\nmy proof below👇 https://t.co/UMA6kMi6e7"
## [49] "@nft_spartan https://t.co/NUfOMELs6V"
## [50] "@nft_spartan https://t.co/UB3uqtMd1E"
## [51] "@nft_spartan https://t.co/cOzSoWYHHz"
## [52] "@nft_spartan Thank you for this great opportunity https://t.co/YTDTSVIRLq"
## [53] "@nft_spartan https://t.co/61TYF8GP6N"
## [54] "@nft_spartan Done rulles https://t.co/12Dv7V33IU"
## [55] "@nft_spartan https://t.co/sSfyxQspnA"
## [56] "@nft_spartan Done https://t.co/womyEsGea5"
## [57] "@nft_spartan https://t.co/syMJGLyFMJ"
## [58] "@nft_spartan Done https://t.co/M2qAZEdCJ0"
## [59] "@nft_spartan Prof https://t.co/mGT9UJNVDI"
## [60] "@nft_spartan https://t.co/V4f6gCXkbC"
## [61] "@nft_spartan https://t.co/RZNQOdlTxA"
Setelah dicek nftspartan awal mulanya membuka sebuah Thread “NFT GUIDE FOR BEGINNERS” kemudian menjanjikan uang senilai $100 kepada siapapun yang melakukan retweet. Hal ini tentu saja menyebabkan orang-orang yang meretweetnya juga ikut melakukan mention supaya namanya terpilih untuk diberikan uang tersebut.
Dari hasil pembuatan graph dan perhitungan nilai centrality kita dapat memvisualisasikan graph tersebut. Untuk mempermudah interpretasi dari plot nantinya kita perlu mengelompokkan nodes kedalam beberapa cluster. Oleh sebab itu kita akan melakukan proses clustering pada graph terlebih dahulu.
Metode clustering yang digunakan pada graph ini adalah metode Louvain, dimana metode ini melihat kerapatan (density) dari network yang ada.
set.seed(123)
graph_tweets <- graph_tweets %>%
activate(nodes) %>%
mutate(community = group_louvain()) %>%
activate(edges) %>%
filter(!edge_is_loop())
Fungsigroup_louvain()
bertujuan membuat cluster dengan metode louvain serta melakukan pelabelan secara langsung untuk tiap nodes.
graph_tweets %>%
activate(nodes) %>%
as.data.frame() %>%
count(community)
Bila dilihat dari rangkuman cluster yang terbentuk terdapat 1320 yang terbentuk, namun kita hanya akan fokus pada 3 cluster pertama saja karena cluster tersebut merupakan cluster terbesar.
Orang-orang penting di tiap cluster merupakan orang-orang dengan nilai centrality terbesar.
# fungsi untuk mendapatkan orang orang penting di tiap cluster
important_user <- function(data) {
name_person <- data %>%
as.data.frame() %>%
filter(community %in% 1:3) %>%
select(-community) %>%
pivot_longer(-name, names_to = "measures", values_to = "values") %>%
group_by(measures) %>%
arrange(desc(values)) %>%
slice(1:6) %>%
ungroup() %>%
distinct(name) %>%
pull(name)
return(name_person)
}
Agar visualisasi yang ditampilkan tidak berantakan, maka label user_name yang ditampilkan hanyalah akun-akun dengan nilai centrality tertinggi di tiap-tiap clusternya. Berikut ini merupakan orang-orang dengan nilai centrality terbesar:
important_person <-
graph_tweets %>%
activate(nodes) %>%
important_user()
important_person
## [1] "GenWealth0" "nftspartan" "TastyBonesNFT" "misscryptolog"
## [5] "bgrathod6" "REALSWAK" "smolrunnersNFT" "CryptoKing1st"
## [9] "snowcorp" "SolApeYachtClub" "mandytn98" "Arizona998"
## [13] "mandyyyNFT" "meganXONFT" "veejayart" "Gabby_NFT"
set.seed(13)
graph_tweets %>%
activate(nodes) %>%
mutate(ids = row_number(),
community = as.character(community)) %>%
filter(community %in% 1:3) %>% # 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.1 ) +
geom_node_point(aes(size = degree, fill = community), shape = 21, alpha = 1, color = "grey30") +
geom_node_label(aes(label = node_label), repel = T, alpha = 1, color = "black" ) +
guides(size = "none") +
labs(title = "Top 3 Community of #NFT", # judul plot
color = "Interaction",
fill = "Community") + # legend warna
theme_void() +
theme(legend.position = "top")
set.seed(13)
graph_tweets %>%
activate(nodes) %>%
mutate(ids = row_number(),
community = as.character(community)) %>%
filter(community %in% 1:3) %>% # 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.1 ) + # alpha edge/garis dibuat tipis supaya lebih terlihat nodesnya
geom_node_point(aes(size = eigen, fill = community), shape = 21, alpha = 1, color = "grey30") + #alpha node dibuat besar supaya lebih terlihat
geom_node_label(aes(label = node_label), repel = T, alpha = 1, color = "black" ) +
#alpha label dibuat besar supaya lebih terlihat teksnya
guides(size = "none") +
labs(title = "Top 3 Community of #NFT", # judul plot
color = "Interaction",
fill = "Community") + # legend warna
theme_void() +
theme(legend.position = "top")
Dari dua visualisasi graph di atas kita bisa melihat 3 cluster community. Masing masing cluster memiliki beberapa akun penting berdasarkan nilai centralitynya, semakin besar ukuran node menandakan semakin “populer” node tersebut (eigen/degree centrality yang tinggi).
Melalui visualisasi berdasarkan nilai degree, akun nftspartan tampak sangat jelas memiliki node terbesar, karena memang nilai degreenya paling tinggi (posisi degree 1, cek centrality rank), bersama dengan misscryptolog (posisi degree 2) ada di grup yang sama di komunitas nodes hijau. Namun demikian, komunitas nodes hijau ini terpecah menjadi dua yang didalamnya ada CryptoKing1st (posisi degree 4) dan snowcorp (posisi degree 5). Sedangkan REALSWAK (posisi degree 3) berada di komunitas nodes merah. Seperti dijelaskan sebelumnya (di bagian Centrality Rank) bahwa akun nftspartan merupakan salah satu NFT collector & investor dengan follower lebih dari 23k. Akun nftspartan pula yang membuka sebuah Thread “NFT GUIDE FOR BEGINNERS” kemudian dan membuat GIVEAWAY dengan menjanjikan uang senilai $100 kepada siapapun yang melakukan retweet. Hal ini membuatnya memiliki nodes dengan nilai degree tertinggi karena merupakan individu populer serta individu yang cenderung menyimpan sebagian besar informasi dan cepat terhubung dengan jaringan yang lebih luas.
Melalui visualisasi berdasarkan nilai eigen akun mandytn98 terlihat cukup jelas memiliki nodes cukup besar dibanding nodes lain di antaranya. Akun ini diketahui memiliki follower cukup sedikit. Melalui profilnya (cek @hanna99eth) akun ini sering mengikuti kuis/giveaway, mungkin juga memiliki komunitas (kuis) yang cukup kuat. Atau bisa dikatakan seorang kuis hunter dengan komunitas kuis hunter. Ini bisa dilihat juga di dalam komunitas nodes biru bahwa nodesnya tidak terlalu rapat namun jangkauannya cukup luas. Keterhubungannya dengan akun lain yang masuk di komunitas yang sama (komunitas nodes biru) seperti mandyyyNFT, Arizona998, dan meganXONFT ini cukup jelas. Semuanya sama-sama kuis hunter khususnya NFT. Hubungan di eigen ini menunjukkan tidak hanya karena banyaknya follower namun juga saling terkait satu sama lain (ada engagement / mungkin saling follow / saling mention) dengan jangkaun luas.
Kemudian akun GenWealth0 diketahui sebagai akun dengan nilai betweenness dan closeness tertinggi. Tampak terlihat di visualisasi akun ini ada sebagai jembatan di antara kelompok-kelompok komunitas (betweenness). Akun ini juga yang paling efektif dalam persebaran informasi “broadcaster” (closeness). Diketahui bahwa akun ini adalah bot yang sering mempromosikan berita ataupun GIVEAWAY terkait NFT.