밈코인 성공 예측 분석1
데이터
train.csv
졸업여부가 라벨링된 학습용 데이터셋
| mint | 토큰의 민트 주소(고유 ID) |
| slot_min | 토큰이 생성된 솔라나 슬롯번호 |
| slot_graduated | 85 SOL 유동성을 달성한 슬롯 번호(if applicable) |
| has_graduated | 졸업 여부 True / False |
test_unlabeled.csv
train.csv와 같은 형식이지만, 정답이 없는 데이터셋
- 여기에 있는 각 토큰에 대해 졸업할 확률을 예측
chunk*.csv
실제 분석의 중심이 되는 행동 데이터셋(behavior dataset)
각 파일은 토큰이 민트된 직후 100개의 블록 내에서 발생한 거래 데이터를 담고 있음
| block_time | 거래 발생 시각(UTC 기준 타임스탬프) |
| slot | 해당 거래가 발생한 솔라나 슬롯 번호 |
| tx_idx | 블록 내에서의 트랜잭션 순번 |
| signing_wallet | 거래를 서명한 지갑 주소 |
| direction | 거래 방향( buy / sell ) |
| base_coin | token involved in the swap(= 토큰 교환) 사거나 판 코인의 이름 |
| base_coin_amount | ㅤ |
| quote_coin_amount | 해당 거래에서 교환된 SOL 수량 |
| virtual_token_balance_after | 거래 후, 유동성 풀에 남아 있는 토큰의 가상 잔고 높을수록 → 사람들이 토큰을 덜 샀거나, 매도서 토큰이 다시 풀로 들어왔다는 뜻 |
| virtual_sol_balance_after | 거래 후, 유동성 풀에 남아 있는 SOL의 가상 잔고 높을수록 → 많은 사람들이 이 토큰을 샀다는 뜻 |
| signature | 트랜잭션 서명 트랜잭션의 고유 ID 같은 역할 (지갑 주소가 실제로 서명했는지 인증) |
| provided_gas_fee | 사용자가 제시한 총 gas 비용 트랜잭션을 보낼 때 “이 정도까지는 수수료로 지불하겠다”는 상한선 |
| provided_gas_limit | 최대 사용 가능 gas 양 트랜잭션 실행에 허요된 최대 계산량 (계산 복잡도 제한치) |
| fee | 실제로 지불된 수수료 트랜잭션 처리 후 실제로 빠져나간 SOL 수수료 (보통 provided_gas_fee보다 작음) |
| consumed_gas | 실제로 사용된 gas 양 이 트랜잭션을 실행하는 데 소모된 계산량 (실제 연산량) |
dune_token_info.csv
Dune Analytics에서 수집된 토큰 메타데이터
| token_mint_address | 토큰의 민트 주소 (고유 ID) |
| decimals | 토큰이 소수점 이하로 몇 자리까지 표현 가능한지 같은 숫자라도 실제 양은 다를 수 있음 amount / (10^decimals) 로 정상화해서 다뤄야 함 |
| name, symbol | 토큰의 이름과 심볼(브랜딩 정보) |
| token_uri | IPFS에 저장된 메타데이터 링크 |
| created_at | 해당 토큰이 민트된 시각 |
| init_tx | 초기 민팅 트랜잭션 해시값 (트랜잭션 고유 ID) - 블록체인에서는 모든 거래가 고유한 해시 값을 가짐 - 이 컬럼은 그 중에서도 이 토큰을 생성한 최초의 거래를 가리킴 - solscan 같은 사이트에서 검색하면, 토큰 생성 시점에 무슨 일이 있었는지 볼 수 있음 - httsp://solscan.io/tx/[init_tx] 로 검색하면 생성 내역 조회 가능 |
token_info_onchain_divers.csv
토큰 메타데이터 + 배포 관련 통계
| block_time, slot, tx_idx | 해당 토큰이 민트된 시점의 시간/슬록/트랜잭션 인덱스 |
| creator | 이 토큰을 만든 지갑 주소(배포자) |
| mint | 토큰 민트 주소 |
| bundle_size | 민트 트랜잭션 안에 한 번에 생성된 토큰 수 |
| gas_used | 토큰 생성시 사용된 가스량 |
| name, symbol, url | 토큰의 이름, 심볼, 메타데이터 URI |
| amount_of_instructions | ㅤ |
| curve_address | 유동성 풀의 특정 커브(곡선) 로직을 정의한 스마트 컨트랙트 주소 - 유동성 풀이 어떤 가격 결정 로직을 따르는지를 지정한 스마트 컨트랙트 주소 - 곡선이 다르면 가격 반응성, 슬리피지, 수익 모델이 다름 |
‼ 데이터 row 수가 많아서 모두 merge 하면 csv 가 제대로 저장이 안되는 문제
parquet으로 저장
베이스라인
- 수치형 데이터 통곗값(mean, std, min, max, sum)으로 모델 학습
실패 logloss: 0.007679
성공 logloss: 2.778895
제외 컬럼
- chunk_slot_min
- 첫 거래의 slot은 코인이 생성된 slot 과 같음
- dune_decimals
성능 향상 전략
베이스라인 train 데이터 예측 확률로 그룹화
실패 코인은 대부분 예측 확률이 0.0 근처(거의 확신)
성공 코인은 두 극단(0.0 근처 / 1.0 근처) 모두 존재- → 혼동되는 성공 코인이 분명히 있음
→ 예측 확률 기반으로 3개 그룹으로 나눠서 접근
| 그룹 | 조건 | 설명 |
| 성공 확신 코인(TP) | 실제로 성공 & 예측 확률 > 0.9 | 모델이 “성공이라고 본” 실패 코인 |
| 성공 혼동 코인(FN) ⭐️ | 실제로 성공 & 예측 확률 ≤ 0.1 | 모델이 “거의 실패라고 본” 성공 코인 |
| 실패 코인(TN) | 실제로 실패 & 예측 확률 < 0.1 | 모델이 “실패라고 본” 실패 코인 |
예측 확률 기반으로 3개 그룹 나누는 코드
성공 혼동 코인(FN)을 위한 미니 모델 학습
성공 혼동 코인(FN) 과 실패 코인(TN) 만 모델을 돌리면 잘 예측할까?
→ 구분을 거의 못 함.
TN 언더샘플링 미니 모델
tn 언더샘플링 후, fn tn으로만 학습했을 때 feature importance
- 베이스라인의 Logloss가 낮은 이유는 코인 실패 데이터의 수가 워낙 많고 실패를 잘 예측하기 때문.
- TN을 언더샘플링 해버리면 TN의 개수가 많이 없어져서 logloss가 커질 수 밖에 없음
class weights 적용 미니 모델
undersampling vs class_weights 모델의 feature importances
어떤 모델의 feature importances가 더 의미 있을까?
tn 언더샘플링 후, fn tn으로만 학습했을 때 feature importance
class_weights 적용 후 fn tn 학습
| undersampling | class_weights |
| 데이터가 균형이기 때문에 FN을 잘 맞추는 특징이 무엇인지에만 집중된 모델 - 단점: TN 쪽 정보는 대부분 버려짐 | FN을 잘 맞추는 특성과 전체 예측에 도움이 되는 변수가 혼합됨 TN 예측 성능을 유지하면서도 FN도 어느정도 고려하는 균형 잡힌 모델 |
두 모델에서 Top 20 중요 변수 교집합 → 모델 학습
- 공통적으로 중요한 변수는 FN 예측에 유효할 가능성 있음
변수 목록
→ 성공 logloss, 실패 logloss 모두 악화됨
Top20 중요 변수 합집합 → 모델 학습
- 각 모델에서 중요하게 생각하는 변수를 좀 더 추가
변수 목록
→ 성공 logloss, 실패 logloss 모두 악화됨
이중 기반의 하이브리드 모델 설계
- class_weights 기반으로 전체 모델 구성 후, FN 예측만 별도 모델로 언더샘플링 기반 보조 모델 사용
실패 logloss: 0.170811
성공 logloss: 1.009139
- 성공 코인은 개선됨. FN(성공 혼동 코인)을 개선한 대신, TN을 희생함
class_weights 사용하면 안 될 듯
class_weights를 사용하면 소수 클래스(FN, 성공)에 집중하도록 유도
하지만, 데이터에서 실패(0)의 개수가 지나치게 많고, 실패를 성공으로 잘못 예측하면 logloss에 큰 패널티가 있기 때문에, 실패를 조금이라도 성공으로 예측하면 성능이 심각하게 악화됨
거래 수 비교
실패 코인이 거래 수가 확실히 적은 편
100개 블록 동안 거래 수가 총 1개인 코인의 개수
거래 수가 1개인 코인들을 어떻게 성공이라고 판단했을까?
- 잔고 관련 지표
- 성공으로 확신한 코인들은 토큰 잔액이 적고, 솔라나 잔액이 많음
거래 수가 1개인 코인들은 대부분 creator가 구매한 것
creator가 안 산 경우를 파보다가, 특정 사람이 여러 코인을 사는 경우를 확인
- niggerd597QYedtvjQDVHZTCCGyJrwHNm2i49dkm5zS
→ 이 사람이 산 코인은 대부분 성공
- wallet_success_rate
wallet_success_rate
각 거래 내역에서 거래를 한 지갑(사람)이 투자한 코인의 성공률을 계산하여 wallet_success_rate 라는 feature를 만들고, 각 코인 별로 갖고 있는 wallet_success_rate 값을 mean, std, min, max, sum 으로 집계를 내려서 최종 feature 로 추가
실패 logloss: 0.001683
성공 logloss: 0.610846
😱 문제점
train set에 없는 wallet이 test set에 등장하는 경우가 많아 test logloss는 더 안 좋아짐
test 에 있는 코인 478832개 중 56988개에서 wallet_success_rate 가 결측치
- test prediction 기반 wallet success rate 보강한다면?
- train 기반
wallet_success_rate계산(기존 방식) - test 에서 predicted_probability ≥ threshold(e.g 0.95)인 코인에서 참여한 wallet을 success로 간주
- 이 wallet들을 포함해 전체 wallet_success_rate를 재계산
- 그걸 다시 test에 집계 특성(mean, std, min, max, sum)으로 넣기
test prediction 기반 wallet success rate 보강하기 전
test logloss: 0.2399
보강 후
test logloss: 0.1684
→ 보강 후로 0근처로 확률이 늘어나면서 negative 예측이 확신을 가지게 된 것으로 보임
→ FP(실패인데 성공으로 예측)이 줄어들은 것 같음.
wallet 정보를 보강하기 위한 API 들을 알아봄 → 내용 정리하기
creator_success_rate
토큰 발행자가 발행한 코인 중 성공한 코인의 비율
실패 logloss: 0.001566
성공 logloss: 0.473295
wallet_success_rate 과 마찬가지로 testset 에는 학습 시킬 때는 몰랐던, test 데이터에서 처음 등장하는 토큰 발행자가 있다는 문제점이 있다.. 처음 등장하는 지갑(거래자)보다 처음 등장하는 토큰 발행자가 더 많다 🥲
creator 가 몇 번째로 발행한 코인인지?
- 코인 발행자들은 대부분 1-2개 정도 발행했다. (대부분의 토큰이 각 크리에이터의 첫 번째 토큰임)
- 평균적인 순서는 TP > FN > TN
- 표준편차도 TP가 가장 높음 → TP 그룹은 경험이 적은 크리에이터부터 많은 크리에이터까지 다양하게 분포
- 최댓값을 봤을 때는, 실패 코인이라도 토큰을 많이 발행한 사람은 존재하지만 평균은 낮은 편
거래가 1건이면서 성공한 코인들은 경력자인 크리에이터가 발행한 코인일까?
거래가 1건밖에 없는 코인이라 정보가 적지만,
성공 확신 코인일수록 초기에 성공한 케이스가 많음
일관된 성공 전략을 가진 크리에이터는 일부 존재하지만, 대부분은 한두 번 성공한 후 다시 실패하거나, 초기 실패 후 성공한 뒤 다시 실패하는 등, 성공/실패가 반복되는 양상
→ 성공 경험이 반복적인 성공으로 이어지는 보장은 없음
거래 수에 따른 예측 그룹 분포
- 실패 코인 중에서 총 거래수가 490인 코인을 살펴보면
- 거래 내역
- unique wallet 수 221개
매수 488건, 매도 2건
한 지갑이 최대로 많이 참여한 거래는 3건
wallet_tx_ratio
계산식
거래한 지갑이 해당 토큰의 거래에 얼마나 비중을 차지하는지 나타내는 변수
→ 이와 비슷하게 거래량 편중도 지수(거래 편중도, transaction concentration index)를 만들 수 있음
최초 거래를 누가 했는지
크리에이터가 아닌 외부인이 최초로 거래를 시작했을 때, 실패할 확률이 높음
code
| 예측 그룹 | 구성 비율 |
| 실패 코인(TN) | 61.52% |
| 성공 혼동 코인(FN) | 20.07% |
| 성공 확신 코인(TP) | 18.40% |
솔라나 비율
유동성 풀에서 솔라나가 차지하는 비율
TP
- SOL 비율이 높음
TN
- 낮은 초기 SOL 비율 가짐
• cretor_success_rate가 높은 크리에이터들의 공통적인 토큰 설계 특성 비교
- 초기 거래 패턴 차이
- FN 코인은 초기에 빠르게 거래가 몰리는 구조?
- 예: 첫 10개 블록 내 거래 수, unique wallet 수 등
- 가격 정보가 있다면 가격 변화 속도
- FN은 가격 펌핑이 있고 TN은 그렇지 않은 패턴이 있을 수 있음
- 구매/판매 지표의 변형
- buy_minus_sell_ratio의 시계열 변화 (초기엔 매수 많고 이후 매도 몰리는 등)
- 지갑의 행위 유형 분석
- 같은 지갑이 여러 코인에서 반복적으로 활동 → rug 가능성?
- 반복해서 실패한 지갑이 포함된 경우
- 시간 기반 집중도
- FN은 특정 시간대에 거래가 몰려있는지, TN은 흩어져 있는지
펌핑 속도 - 얼마나 빨리 사람들을 모았는가?
code
time_to_first_10_tx : 첫 거래 ~ 10번째 거래까지 걸린 시간
- 계산식: chunk_block_time 기준 정렬 후 상위 10개 간 시간 차
slot_to_first_10_SOL: 10 SOL 채우는 데 걸린 slot 차
- 계산식: chunk_slot 정렬 후 누적 매수 거래량이 10 SOL 넘는 시점까지의 솔롯 차(chunk_direction = buy일 때, chunk_quote_coin_amount 의 합)
avg_time_per_tx_early: 초기 10건의 평균 거래 간격
- 계산식: 첫 10개 chunk_block_time 간격 평균
initial_burst_ratio: 처음 10건이 전체 거래에서 차지하는 비중
- 계산식: mint별 총 거래 수 대비 상위 10개 비중
참여의 다양성 - 다양한 지갑들이 참여했는가?
unique_wallet_per_10_tx: 처음 10건에 참여한 지갑 수
creator_tx_ratio: crator가 거래한 비중(지갑 하나가 다 사면 사기 가능성)
wallet_entropy: 지갑별 거래 비율의 Shannon entropy(높을수록 다양함)
구매/판매 균형
buy_sell_ratio: 매수 수 / 매도 수
quote_coin_growth_rate: 시간에 따른 구매량 증가 속도
sell_delay_avg: 처음 매수한 지갑이 처음 파는 데까지 걸린 평균 시간
본딩 커브 진척도 추정 - 실제 졸업 기준 접근 여부
est_total_SOL_input: 현재까지 들어온 SOL의 누적합
curve_coverage_ratio: est_SOL_input / expected_total_SOL
시도해봤던 것들
데이터 불균형 해소
SMOTE
- 전
실패 logloss: 0.007515
성공 logloss: 2.685945
- 후
실패 logloss: 0.016788
성공 logloss: 2.533374
TN, FN, TP 모두 줄었음
- FN을 줄이고 싶은데, 오버샘플링을 사용하면 FP가 늘어나면서 실패 logloss가 급상승함
- 특히 실패 클래스가 훨씬 많아, 실패 예측의 정확도가 logloss에 더 큰 영향을 줌