文章
江湖

(已废除)内容发表频率上限与社会信用分挂钩(附代码)

thphd  ·  2021年8月15日 2047前站长

测试中,遇到任何问题请即反馈。


根据社会信用分计算发帖限制(8月22更新):

def daily_limit_posts(uid):
    user = get_user_by_id_cached(uid)
    trust_score = trust_score_format(user)
    return min(60, max(2, int(trust_score*0.025*2)))

def daily_limit_threads(uid):
    user = get_user_by_id_cached(uid)
    trust_score = trust_score_format(user)
    return min(8, max(1, int(trust_score*0.003*2)))

如果一个人信用分是100,那么他48小时内可以发5个回复

如果是200,48小时内可以发10个回复


声望,近期声望以及信用分的计算方式:

def update_user_pagerank_batch():
    qr = QueryString('''

//let now = date_iso8601(date_now())
//let t_now = date_timestamp(now)
let t_now = date_now()

let now_iso = @now_iso

for t in users

let uid = t.uid
let time_factor = 0.99999985

filter t.t_next_pr_update < t_now - 180*1000 // update interval
sort t.t_next_pr_update asc
limit 30

//nlikes: received
//nliked: gave

let target_user = t

// all-time pagerank
let newscore = sum(
    for v in votes filter v.to_uid==target_user.uid and v.vote==1

    let voter = (for u in users filter u.uid==v.uid return u)[0]
    let voterrank = voter.pagerank or 0
    let voterbonus = (voter.uid==5108?1:0) + voterrank
    let score = (voter.nliked?voterbonus / voter.nliked:0) * .95

    return score
)

let last_recent_update_time = t.last_recent_update_time or '1971-01-01'

//let mrl = max([@recent_timestamp, last_recent_update_time])
let mrl = last_recent_update_time
let dtni = date_timestamp(@now_iso)
let dtlru = date_timestamp(last_recent_update_time)
let dt_since_last = (dtni - dtlru)/1000

// exp-falloff pagerank
let newscore_recent = sum(
    for v in votes filter v.to_uid==target_user.uid and v.vote==1
    //and v.t_c > @recent_timestamp

    let voter = (for u in users filter u.uid==v.uid return u)[0]
    let voterrank = voter.pagerank_recent or 0
    let voterbonus = (voter.uid==5108?1:0) + voterrank
    let score = (voter.recent_votes_gave?voterbonus/voter.recent_votes_gave:0)*.95

    let td = (dtni - date_timestamp(v.t_cc))/1000
    let coef = pow(time_factor, td)

    return score * coef
)

let total_activities = (t.recent_threads or 0) + (t.recent_posts or 0)
let total_activities_w_votes = total_activities + (t.recent_votes or 0)
let total_activities_plain = (t.nthreads or 0)+(t.nposts or 0)+(t.nlikes or 0)
let tawvp = total_activities_plain*.5 + total_activities_w_votes * 2

let trust_factor = 1 - pow(0.85, tawvp)
let unit_pr = total_activities?newscore_recent / total_activities:0

let trust_score = unit_pr*trust_factor + (1-trust_factor)*(100/1000000)
// in the beginning everyone have 100 points

//----

let recent_threads = sum(
    for i in threads filter i.uid==uid and i.t_c >= mrl

    let coef = pow(time_factor, (dtni - date_timestamp(i.t_c))/1000)
    return coef
) + (t.recent_threads or 0) * pow(time_factor, dt_since_last)

let recent_posts = sum(
    for i in posts filter i.uid==uid and i.t_c >= mrl

    let coef = pow(time_factor, (dtni - date_timestamp(i.t_c))/1000)
    return coef
) + (t.recent_posts or 0) * pow(time_factor, dt_since_last)

let recent_votes = sum(
    for i in votes filter i.to_uid==uid and i.vote==1 and i.t_cc >= mrl

    let coef = pow(time_factor, (dtni - date_timestamp(i.t_cc))/1000)
    return coef
) + (t.recent_votes or 0) * pow(time_factor, dt_since_last)

let recent_votes_gave = sum(
    for i in votes filter i.uid==uid and i.vote==1 and i.t_cc >= mrl

    let coef = pow(time_factor, (dtni - date_timestamp(i.t_cc))/1000)
    return coef
) + (t.recent_votes_gave or 0) * pow(time_factor, dt_since_last)


//----

update t with {
    t_next_pr_update:t_now,
    pagerank:newscore,
    pagerank_recent:newscore_recent,
    trust_score:trust_score,

    trust_factor:trust_factor,

    last_recent_update_time:@now_iso,

    recent_threads,
    recent_posts,
    recent_votes,
    recent_votes_gave,

    total_activities,
    total_activities_w_votes,
    total_activities_plain,
    tawvp,

} in users

return {name:NEW.name, pr:NEW.pagerank}
    ''')
    res = aql(qr, silent=True, raise_error=False,
        # recent_timestamp=time_iso_now(-86400*365),
        now_iso=time_iso_now(),
    )
    return len(res)
菜单
  1. thphd   2047前站长

    2047现在有三种积分,点赞数,声望,社会信用分。这些积分的目的是量化一个用户对网站的贡献,因为不量化就没办法鼓励、惩罚。

    点赞数可以刷,声望不能刷(参见/t/12587),但是声望对新人不友好(高质量新人的声望低于低质量老人),所以现在推出了社会信用分。社会信用分对新人是友好的,那些发帖不多但质量高的人,信用分也会高。

    社会信用分本质上是 声望 per 活动。积累同样的声望,活动越少的人,社会信用分越高。这样一来,反共左派、派克笔这种人不管待多久、发多少内容,信用分都会一直非常低。

    然后我们再以社会信用分来设置每个用户发表内容频率的上限,高分的人可以多发,低分的人少发。这样谁也不得罪,你帖子发不出来是因为你信用分低,你信用分低是因为你发言质量低,只能怪自己文化水平不够。

  2. 佐藤琴子  

    @thphd #152864

    站长好厉害,现实的社会信用只能知道你手机是否欠费,47的社会信用积分能知道你智商是否欠费。

  3. thphd   2047前站长

    @清华博士豆沙馅 #153355 社会信用分实施初期发现了一些问题,包括

    • 缺少提示,导致部分用户超quota,很不爽
    • 限制发言数量的具体数值不合理,需要打磨
    • 计算社会信用分所用的声望值,是与总声望值分开统计的,统计口径为1y,应调整为随时间指数falloff
    • 管理员有特权也不是,无特权也不是

    前两项已纠正;管理员特权将来再慢慢调整

  4. 国家主席习近平   有些人曾经回来过,又回去了。

    @thphd #153359 我随便说几句

    1.想多发帖可以从他人那儿购买配额,至于是用bitcoin还是用赞还是用社会信用分随便。这样比如士杰想多发帖,则需要找还有配额的人(如natasha)那么这样的好处呢,就是你想多发帖则会受到观众的限制,观众觉得你发帖质量高就送配额,觉得质量低就定高价20信用分一个配额。

    2.对于特权呢,建议采取申请+审批制,我们这些衣逼需要主动申请,由汝或者管理员集体决定是否该对他放宽发言限制。但是对于高端人口呢,毕竟管理员的委任都是海量专精确算的结果,所以管理员可以采取否决制,即除非集体决定他不能拥有特权,否则都视为拥有特权。

  5. 邹韬奋 外逃贪官CA
    邹韬奋   虽然韬光养晦,亦当奋起而争(拜登永不为奴:h.2047.one)

    @国家主席习近平 #153361 我反对管理员在此问题上有特权。没有必要嘛。管理员的特权应该是管理层面的。发帖要有特权岂不是管理员可以直接水贴喷死非管理员?要以德服人。

  6. thphd   2047前站长

    刚刚再次调整了声望和信用分的计算方式

    • 原始声望:/t/12587,统计口径是all-time
    • 近期声望:同原始声望,但统计口径为半年,且每次点赞有权重,权重 = pow(0.99999985, td), td = 点赞的发生时间 - 当前时间(单位秒),也就是越古老的点赞权重越低
    • 近期发言数量:每次发言有权重,刚刚发言为1,越古老的发言权重越低,计算方式同上
    • 社会信用分:近期声望 / 近期发言数量

    确实比较复杂,等分数慢慢稳定之后再看吧。


    备注:

    0.99999985 ** (86400*365) = 0.0088 # 一年前
    0.99999985 ** (86400*365/2) = 0.09
    0.99999985 ** (86400*365/4) = 0.30
    0.99999985 ** (86400*365/12) = 0.67 # 一个月前
    0.99999985 ** (86400*7) = 0.91 # 一周前
    

    换言之,即便之前是龙王,只要从现在开始坚持高质量发帖,很快你的信用分就会回升。

  7. 欢迎回到膜乎 汉帝国签证官
    欢迎回到膜乎   膜乎新网址https://www.reddit.com/r/mohu/

    @thphd #153367 本人对站长积极探索治站理政方略表示赞赏。但是这个计算方式会造成,如果不发帖,信用分随时间衰减。对我这种喜欢退站的人还是不太友好

  8. 邹韬奋 外逃贪官CA
    邹韬奋   虽然韬光养晦,亦当奋起而争(拜登永不为奴:h.2047.one)