This content was deleted by the author. You can see it from Blockchain History logs.

[Q-Bot 아이디어 제안] 명성도를 활용한 PostingRank

@skan님이 작성하신 [Q-Bot] 화이트리스트 추천을 마감합니다. / 개선점 의견 받습니다를 보고, 어떻게 하면 포스팅에 적절한 가치를 매길 수 있을지 고민해봤습니다.

사람마다 좋은 글이라 판단하는 기준이 다르기 때문에 수치화하는 것이 부적절할 수 있겠지만, 이왕 보팅 봇을 사용할 것이라면 보팅 비율을 정하기 위한 기준을 만들어 보는 것도 괜찮겠다는 생각이 들었습니다.

제가 생각해 본 알고리즘은 구글의 페이지 랭크 알고리즘에 스팀의 명성도 시스템을 섞어 만든 Posting Rank 입니다.

pr.JPG
참고 : 조성문님의 ‘쉽게 설명한’ 구글의 페이지 랭크 알고리즘

페이지 랭크는 구글 검색 시 상위권에 노출되는 페이지의 랭킹을 정하기 위한 알고리즘 입니다.
PR(A) = (1-d)/N + d (PR(T1)/C(T1) + … + PR(Tn)/C(Tn))

PR =  
T = 
C(T1) =  T1     
d = Damping Factor 
N =   

스팀잇에서 생각해보면
각각의 페이지는 @yguhan 같은 계정,
링크는 리스팀,
우항에 가중치를 부과하는 페이지 랭크는 계정의 명성도로 치환해 볼 수 있습니다.

PR(A) = (1-d)/N + d (R(A1)/RS(A1) + ... + R(An)/RS(An))

PR = Posting Rank( )
A = Account()
RS(A1) = Resteem Count(A1  )
R = Reputation()
d = Damping Factor 
N =   

1.

리스팀을 인용 링크에 대응해 보았는데, 포스팅에서 보팅 << 댓글 << 리스팀 순으로 받기 어려워지기 때문에 나쁘지 않은 선택이라 생각합니다.

모든 글을 리스팀하는 사람보다 어쩌다 한번 리스팀하는 사람이 리스팀한 포스팅이 더 가치가 있다고 보기에, 분모를 리스팀 횟수로 나누어 줍니다. 하지만 오래 활동한 사람의 총 리스팀 횟수가 무조건 크게 나오기 때문에, 7일간 리스팀한 횟수로 보정해줍니다.

2.

무조건 명성도가 높은 유저일수록 좋은 글을 판별하는 안목이 높을 것이라 말하기는 어렵지만, 오랫동안 스팀잇 커뮤니티에서 활동해온 이들이 더 신뢰가 가는 것도 사실입니다. 부계정을 이용한 리스팀같은 어뷰징을 억제하는 효과도 있고, 유명무실했던 명성도의 가치를 실험해볼 좋은 기회라고 생각합니다.

@nand님이 자세히 설명해주신 [Steem Dictionary] 스팀잇에서 reputation (평판,명성)이란?을 읽어보면 명성도가 로그 스케일로 커진다는 것을 알 수 있습니다. 이미 스팀잇을 사용해 온 많은 분들은 명성도가 오를 수록 +1을 올리기가 점점 더 어려워진다는 것을 느끼셨을 겁니다. 점점 올리기 어려워지는 명성도의 난이도를 반영하기 위해 가중치를 reputation의 제곱으로 보정했습니다.

3.

명성도에 의한 영향력을 0~1사이의 수로 만들기 위해 10000을 나눠줍니다.
ex) 명성도 25 -> 25 * 25 / 10000 = 0.0625, 명성도 70 -> 70 * 70 / 10000 = 0.49

4.

리스팀 횟수가 0이여도 최소 2% 보팅을 보장하기 위해, (1-d)/N = 0.02로 고정합니다.

1, 2, 3, 4를 적용해 만든 PR은 다음과 같습니다.
PR(A) = 0.02 + 1/10000 * (R(A1)^2/RS(A1) + ... + R(An)^2/RS(An))

PR = Posting Rank( )
A = Account()
RS(A1) = Resteem Count(A1 7   )
R = Reputation()
0.02 =   (2%)

직접 테스트 해보기

@asbear님의 웹브라우저에서 SteemJS로 간단히 스팀파워 임대하기를 응용하여 웹브라우저에서 SteemJS로 간단하게 포스팅 랭크(PostingRank)를 구해봅시다.

0.

크롬에서 새창을 하나 엽니다.
우클릭, "검사" 클릭.
"Console" 클릭
console.JPG

1.

콘솔창에 SteemJS와 UnderscoreJS를 로딩합니다.
아래 코드를 콘솔창에 복사 붙여넣기 합니다.

document.write('');
document.write('');

cdn.JPG

2.

PostingRank를 구해보고 싶은 포스팅의 링크를 가져옵니다.
[암호화폐 시장의 마법사들-번외편] @twinbraid, 그가 전하는 예언 매매(https://steemit.com/kr/@yguhan/twinbraid)

포스팅 링크에서 저자 yguhan과 마지막 부분에 있는 twinbraid가 사용할 변수입니다.

var author = 'yguhan';
var permlink = 'twinbraid';

위의 코드를 이전과 같은 방식으로 복사해서 콘솔창에 붙여넣기 합니다.
실험해보고 싶은 포스팅의 링크를 가져와서 author와 permlink 부분에 다른 변수값을 넣어 테스트 해보셔도 좋습니다.

3.

위에서 만들어본 PostingRank를 계산하는 공식을 코드화했습니다.
콘솔에 복붙해서 출력값을 확인해봅시다.

var prPromise = new Promise(function(resolve, reject) {

    steem.api.getRebloggedBy(author, permlink, function(err, result){
        
        if (err) return reject(err);

        // 글 작성자를 제외한 리스팀 유저들의 Array
        var rebloggers = _.without(result, author);
        return resolve(rebloggers);
    });

})
.then(function(rebloggers) {

    return _.reduce(rebloggers, function(prPromise, reblogger) {

        return prPromise.then(function(pr) {

            // 명성도 계산
            var reputationPromise = new Promise(function(resolve, err) {
                steem.api.getAccounts([reblogger], function(err, result) {

                    if (err) return reject(err);

                    var reputation = steem.formatter.reputation(result[0].reputation);
                    return resolve(reputation);
                });

            });

            // RC(Resteem Count) 계산
            var rcPromise = new Promise(function(resolve, reject) {
                steem.api.getState("@" + reblogger, function(err, result) {

                    if (err) return reject(err);

                    contents = result.content
                    var resteemContents = _.pick(contents, function(value, key, object){
                        // 해당 글을 리스팀한 유저의 블로그에서 자신의 글이 아니고, 저자 보상을 받지 않은 포스팅의 개수
                        // 즉, 7일 간 리스팀한 포스팅의 총 개수를 계산   
                        return !new RegExp(reblogger).test(key) && value.author_rewards == 0;
                    });
                    rc = _.keys(resteemContents).length;
                    return resolve(rc);

                });
            });

            // PostingRank값 합산
            return Promise.all([reputationPromise, rcPromise]).then(function(results) {
                
                var [reputation, rc] = results;
                // 리스팀 횟수가 0이면 1로 처리
                rc = rc !== 0? rc : 1; 
                // 명성도에 의한 영향력을 0~1로 만들기 위해 10000를 나눔 
                return pr + reputation*reputation/(10000*rc);

            });

        });
    // 리스팀 횟수가 0일 때 2% 보팅
    }, Promise.resolve(0.02));

})
.then(function(pr) {
    // posting rank 출력
    console.log(pr);
})
.catch(function(err) {
    console.log(err);
});

posting_rank.JPG

최종적으로 0.67이 찍혔습니다.
이 값이 PostingRank 값이며, 알고리즘은 이 포스팅에 대해 67%의 보팅 비율을 제안했습니다.
예시로 사용한 [암호화폐 시장의 마법사들-번외편] @twinbraid, 그가 전하는 예언 매매법은 4일 전 작성한 글로 트렌딩(대세글)에 올랐었고, 8번의 리스팀 되었습니다.

PostingRank 값이 1 이상인 경우는 극히 드물고 대부분 트렌딩(대세글)에서 찾아볼 수 있었습니다. 하지만 모든 트렌딩의 글이 높은 PostingRank 값을 의미하지는 않습니다. 유료 보팅 봇을 사용하여 인위적으로 보상을 높인 경우 낮은 PostingRank를 기록했습니다.


@skan님이 계획중인 화이트 리스트 기반의 Q-Bot 외에도
@clayop님이 진행중인 소모임 태그 지원 봇
@virus707님이 진행중인 짱짱맨 태그 지원 봇
들이 무료로 KR 커뮤니티에서 활동하고 있습니다.

PostingRank는 하나의 아이디어일 뿐이고, 봇 운영에 도움이 된다면 좋겠네요.

SteemJS document가 불친절해서 고생했는데 @asbear님과 @morning님이 이전에 올려주신 SteemJS 관련 포스팅을 보고 많은 도움을 받았습니다.
두 분께 감사드립니다 :)