보상 어뷰징 관련 통계를 구하는 코드를 직접 실행해봅시다

아래에 파이썬 원본코드가 있습니다. 이것을 실행하셔도 되지만 파이썬이 없으신 분들은 아래 링크에 가셔서 온라인 컴파일러를 통해 쉽게 실행해보실 수 있습니다.

기본은 "clayop"로 되어있는데 이 부분을 원하는 계정으로 바꾸시고 실행하시면 됩니다. (따옴표는 지우시면 안됩니다)
추가로 시작 날짜를 바꾸실 수도 있습니다 (기본값은 2018년 3월 26일입니다)

https://repl.it/@JaewooCho/AbuseStats

결과 예시입니다

07 days Stats  |  Average Full Voting Per Day: 6.91  |  Self Vote: 2.2%  |  Inverse Simpson: 25.81
14 days Stats  |  Average Full Voting Per Day: 5.19  |  Self Vote: 2.9%  |  Inverse Simpson: 28.33
30 days Stats  |  Average Full Voting Per Day: 5.21  |  Self Vote: 2.0%  |  Inverse Simpson: 52.28
60 days Stats  |  Average Full Voting Per Day: 4.69  |  Self Vote: 0.9%  |  Inverse Simpson: 48.69
90 days Stats  |  Average Full Voting Per Day: 6.17  |  Self Vote: 1.1%  |  Inverse Simpson: 70.16
Top Votee (90 days)
Account: noctisk (6.51%)   252953 rshares(Billion)
Account: granturismo (2.92%)   113565 rshares(Billion)
Account: dakfn (2.89%)   112431 rshares(Billion)
Account: kangdoha (2.66%)   103183 rshares(Billion)
Account: indend007 (2.05%)   79561 rshares(Billion)
Account: shiho (2.03%)   78689 rshares(Billion)
Account: akcho (1.93%)   75112 rshares(Billion)
Account: wony (1.91%)   74052 rshares(Billion)
Account: pius.pius (1.81%)   70202 rshares(Billion)
Account: asbear (1.65%)   64025 rshares(Billion)

아래는 코드 원본입니다

Source code

import requests
import json
import dateutil.parser
import datetime

def calc(acc_name ,res, last_day, numdays):
    all_vweight = 0
    all_rshares = 0
    self_rshares = 0
    sum_of_share_squared = 0
    vtarget = dict()
    min_day = last_day - datetime.timedelta(days = numdays)
    for v in reversed(res):
        ts = dateutil.parser.parse(v["time"])
        if ts > min_day:
            if ts <= last_day:
                name = v['authorperm'].split("/")[0]
                all_vweight += float(v['percent'])
                all_rshares += float(v['rshares'])
                if name == acc_name:
                    self_rshares += float(v['rshares'])
                if name not in vtarget:
                    vtarget[name] = 0
                vtarget[name] += float(v['rshares'])
        else:
            break
    for v in vtarget:
        sum_of_share_squared += (vtarget[v] / float(all_rshares)) ** 2
    Inverse_Simpson = 1.0 / float(sum_of_share_squared)
    print('%02d days Stats  |  Average Full Voting Per Day: %.2f  |  Self Vote: %.1f%%  |  Inverse Simpson: %.2f' % (numdays, all_vweight/10000/numdays, self_rshares/all_rshares*100, Inverse_Simpson))
    if numdays == 90:
        print("Top Votee (90 days)")
        for v in sorted(vtarget, key=vtarget.get, reverse=True)[0:10]:
            print('Account: ' + v + ' (%.2f%%)   %.0f rshares(Billion)' % (vtarget[v]/all_rshares*100, int(vtarget[v]/1000000000)))

def vote_stats(acc_name, last_day):
    sub = json.dumps({"jsonrpc": "2.0", "id": 0, "method": "call", "params": [0, "get_account_votes", [acc_name]]})
    res = requests.post("https://api.steemit.com", data=sub).json()["result"]
    calc(acc_name, res, last_day, 7)
    calc(acc_name, res, last_day, 14)
    calc(acc_name, res, last_day, 30)
    calc(acc_name, res, last_day, 60)
    calc(acc_name, res, last_day, 90)

start_date = datetime.datetime(2018, 3, 26)
vote_stats("계정명", start_date)

추가

부연설명이 필요한 것 같아서 덧붙입니다. (공유한 코드도 조금 수정했습니다)
일단 제 이전 글 보상 어뷰징을 판별할 수 있는 기준들에 기본적인 개념들에 대한 설명이 나와있습니다.

제가 주목해서 보는 부분은 Inverse Simpson 값의 변화와 일평균 보팅수입니다.
Inverse Simpson이 낮고 변화가 없이 거의 일정하다는 말은 보팅을 하는 대상이 한정되어 있을 가능성을 내포하며 이는 담합보팅에서 주로 나타나는 패턴입니다. 반면에 모든 컨텐츠에 대해 열린 큐레이션을 할 경우 IS 값은 시간이 지날수록 증가하는 경향이 있습니다.
어느 정도가 낮은지 높은지 딱 잘라 말할 수는 없겠지만 90일 기준으로 50 이하면 담합보팅 가능성이 큰 듯합니다. 이 부분에 있어서는 질적 연구가 더 필요합니다.

IS가 낮고 변화가 거의 없을지라도 일평균 보팅이 10보다 많이 작다면 어뷰징이라고 하기엔 무리가 있습니다. 이럴 경우에는 단순히 “게으른” 큐레이션이라고 말할 수 있겠습니다. 바빠서 생각날 때만 피드에 올라오는 글 위주로 보팅을 하는 것이죠.

하지만 "만약" IS가 낮고 변화가 거의 없는 경우, 일평균 보팅이 10.0에 가까울 때에는 어뷰징일 가능성이 더 큽니다. 다시한번 강조하지만, 일평균 보팅이 10이라고 해서 어뷰징이라고는 할 수 없고 IS 조건이 만족할 경우에만 일평균 보팅 조건이 성립합니다.

상위 저자는 혹시 모를 부계정이나, 추가적인 자료수집을 위해 출력했습니다. 추후 네트워크 분석을 통해 상관관계나 군집관계를 파악할 수 있을 것으로 보입니다.

궁금하신 점 있으시면 댓글로 남겨주세요.

추가2: 현 시세로 300십억 rshares가 약 1달러 보상입니다.

H2
H3
H4
3 columns
2 columns
1 column
34 Comments