일지/Proj4
데이터 약분류 시도(Archive, GEN 1 pipeline)
리나그(ReenAG)
2026. 2. 17. 22:16
728x90
반응형
데이터에서 가장 유의미한 연속형 정보들을 전처리하고, 우선 주성분 분석을 통해서 Tron 네트워크의 주요한 통념, 가설 등이 잘 맞아 떨어지는지를 살펴보고자 한다.
1. 데이터셋 전처리
1) parsing
일단 데이터셋은 tronsave에서 가져온 account(그러니까 tron 주소)의 상세정보에 대한 json파일들이다.
이를 다음과 같이 parsing하였다.
# 1. 핵심 파싱 함수 정의
parse_tron_data <- function(binary_blob) {
# A. Arrow Binary -> R Raw Vector 변환
raw_vec <- as.raw(binary_blob)
# B. Gzip 압축 해제
json_str <- rawToChar(memDecompress(raw_vec, type = "gzip"))
# C. JSON 파싱
data <- fromJSON(json_str, flatten = TRUE)
# D. token 총 가격 추출
tokens_df <- data$withPriceTokens
# 데이터가 존재하고 데이터 프레임 형태인지 확인
if (!is.null(tokens_df) && is.data.frame(tokens_df) && nrow(tokens_df) > 0) {
tokens_df <- tokens_df[tokens_df$tokenAbbr != "trx", ]
total_token_value <- sum(as.numeric(tokens_df$amount) * tokens_df$tokenPriceInTrx, na.rm = TRUE)
tokens_count <- nrow(tokens_df)
usdt_row <- tokens_df[tokens_df$tokenAbbr == "USDT", ]
usdt_balance <- if(nrow(usdt_row) > 0) as.numeric(usdt_row$amount[1]) else 0
} else {
total_token_value <- 0
tokens_count <- 0
usdt_balance <- 0
}
# D. 필요한 Feature만 추출 후 Return
tibble(
#1. Direct info
#1-1. Tags
is_red_tag = pluck(data, "redTag", .default = "") != "",
#grey_tag = pluck(data, "greyTag", .default = NA_character_),
#blue_tag = pluck(data, "blueTag", .default = NA_character_),
#feedback_risk = pluck(data, "feedbackRisk", .default = FALSE),
#1-2. Account Info
activated = pluck(data, "activated", .default = FALSE),
#is_verified = isTRUE(pluck(data, "vip", .default = FALSE)),
account_type = pluck(data, "accountType", .default = 0),
#has_announcement = nzchar(pluck(data, "announcement", .default = NA_character_)),
date_created = anytime(pluck(data, "date_created", .default = 0)),
#1-3. Permissions
active_permissions = NROW(pluck(data, "activePermissions", .default = list())),
#allowed_exchanges = NROW(pluck(data, "allowExchange", .default = list())),
owner_permissions = NROW(pluck(data, "ownerPermission", "keys", .default = list())),
#1-4. SR
#representative = pluck(data, "representative", "enabled", .default = FALSE),
#2. Balance info
#this only shows trx
balance = pluck(data, "balance", .default = 0) / 10^6,
usdt_balance = usdt_balance,
#2-1. Tokens
tokens = tokens_count,
total_token_value = total_token_value,
#2-2. Asset Delegation
#2-2-1. inward asset borrowing
in_bd_sho_v1 = pluck(data, "acquiredDelegateFrozenForBandWidth", .default = 0),
in_bd_val_v1 = pluck(data, "acquiredDelegatedFrozenBalanceForBandwidthValue", .default = 0),
in_en_sho_v1 = pluck(data, "acquiredDelegateFrozenForEnergy", .default = 0),
in_en_val_v1 = pluck(data, "acquiredDelegatedFrozenBalanceForEnergyValue", .default = 0),
in_bd_sho_v2 = pluck(data, "acquiredDelegatedFrozenV2BalanceForBandwidth", .default = 0),
in_bd_val_v2 = pluck(data, "acquiredDelegatedFrozenV2BalanceForBandwidthValue", .default = 0),
in_en_sho_v2 = pluck(data, "acquiredDelegatedFrozenV2BalanceForEnergy", .default = 0),
in_en_val_v2 = pluck(data, "acquiredDelegatedFrozenV2BalanceForEnergyValue", .default = 0),
#2-2-2. outward asset lending
out_bd_sho_v2 = pluck(data, "delegatedFrozenV2BalanceForBandwidth", .default = 0),
out_bd_val_v2 = pluck(data, "delegatedFrozenV2BalanceForBandwidthValue", .default = 0),
out_en_sho_v2 = pluck(data, "delegatedFrozenV2BalanceForEnergy", .default = 0),
out_en_val_v2 = pluck(data, "delegatedFrozenV2BalanceForEnergyValue", .default = 0),
out_bd_sho_v1 = pluck(data, "delegateFrozenForBandWidth", .default = 0),
out_en_sho_v1 = pluck(data, "delegateFrozenForEnergy", .default = 0),
#2-2-3. staking
stk_bd_sho_v1 = pluck(data, "frozenForBandWidth", .default = 0),
stk_bd_val_v1 = pluck(data, "frozenForBandwidthValue", .default = 0),
stk_bd_sho_v2 = pluck(data, "frozenForBandWidthV2", .default = 0),
stk_bd_val_v2 = pluck(data, "frozenForBandwidthV2Value", .default = 0),
stk_bd_vas_v2 = pluck(data, "frozenForBandwidthV2ValueSum", .default = 0),
stk_en_sho_v1 = pluck(data, "frozenForEnergy", .default = 0),
stk_en_val_v1 = pluck(data, "frozenForEnergyValue", .default = 0),
stk_en_sho_v2 = pluck(data, "frozenForEnergyV2", .default = 0),
stk_en_val_v2 = pluck(data, "frozenForEnergyV2Value", .default = 0),
stk_en_vas_v2 = pluck(data, "frozenForEnergyV2ValueSum", .default = 0),
#3.Activity
#3-1. Network usage
free_net_used = pluck(data, "bandwidth", "freeNetUsed", .default = 0) > 0,
net_used = (pluck(data, "totalNet", .default=600) -
pluck(data, "totalNetRemaining", .default=600)) > 0,
has_v2_widthdraw = pluck(data, "canWithdrawAmountV2", .default = 0) > 0,
last_op_days_ago = as.numeric(difftime(Sys.time(), anytime(pluck(data, "latest_operation_time", .default = 0)/1000), units="days")),
#3-2. Tx usage
tx_count_tot = pluck(data, "totalTransactionCount", .default = 0),
tx_count = pluck(data, "transactions", .default = 0),
tx_count_in = pluck(data, "transactions_in", .default = 0),
tx_count_out = pluck(data, "transactions_out", .default = 0),
#3-3. Reward Related
reward = pluck(data, "reward", .default = 0),
reward_num = pluck(data, "rewardNum", .default = 0),
vote_total = pluck(data, "voteTotal", .default = 0),
#4.Misc
#frozen_supply = NROW(pluck(data, "frozen_supply", .default = list())),
)
}
이 위에서 주석처리된 변수, blue_tag, representative, frozen_supply등은 약 91만개의 주소들 중 변화를 전혀 관찰할 수 없었고, 따라서 차원의 저주를 방지할 겸, 제외한 것이다.
결국 제일 구체적인 정보는 stake와 관련된 정보, balance, account_type과 red_tag유무, 등등이라고 생각할 수 있다.
2)



2026년 9월 edit*
일단 옛날 글 공개처리 할 겸 미리 덧붙이자면, tronscan에서 가져온 table data를 feature로 DBSCAN, 밀도 기반 클러스터링을 하려던 파이프라인의 결과이다. 몇 가지 문제점은 위와 같이 제대로 된 K를 짚기도 어렵고, 내가 만든 feature도 아니기 때문에 node를 제대로 분류하는 일도 한계가 있었다. 아무튼 이 이후에 내가 직접 block데이터를 가져오고 어떻게 transaction을 적재하는지, ETL에 관한 것들은 제대로 학습했으니 이것도 나름의 성장이라고 해야하나... 생각해보니 좋은 글감인 것 같긴하다. 한번 적어봐야할것 같다.
728x90
반응형