百姓大小事,一呼百应!

百姓网 | 百姓知道

音乐舞蹈

人人网最近巨火的应用「好友档案」的算法是什么?

最近满屏都是这个应用——好友档案。其中,最关心你的人,最自恋的人……这两个的算法是什么? 以及为什么有时候会出现不相容的现象——为什么有的时候在某个人的里面,一个人(A)的自恋排名比B的高,而在另一个人的显示中,B却比A高?

2 个回答

  • 谢梦非 | 2017-09-10 09:40:41

    转载自百度知道http://zhidao.baidu.com/question/274886249.html?pn=75
    好友档案是中国几个在校大学生研发的,一款针对人人网的第三方应用软件,针对人人网用户的好友,进行一系列的统计调查:男女比例,人脉地图,大学分布,最关心你的人,谁最自恋。
    算法分析
    男女比例:添加好友档案应用,调用friends.getFriends API,得到当前登录用户(你)的好友列表,然后就是统计了,不赘述。
    人脉地图:同上
    大学分布:同上
    最关心你的人:这主要是基于你的状态的别人,日志,照片的数量,取前六名。
    谁最自恋:得到当前登录用户(你)的好友列表,调用photos.getAlbums API,获取用户的相册列表,查看头像相册内照片数量,排序,取前5名。
    技术分析(个人猜想)
    以“最关心你的人”为例
    1) 添加“好友档案”,同意免责条款,进入应用
    2) 调用friends.getFriends,得到当前登录用户(你)的好友列表
    3) 调用status.gets,获取用户的状态列表。
    4) 调用status.getComment,获取一条状态中的所有回复内容。
    5) 遍历状态回复中出现的用户ID,将ID加入表A,并添加属性值ɑ。
    6) 每出现一个新用户ID,就加入表A,重复出现则属性值ɑ+1.
    7) 同理,调用照片photos.getComments 及日志blog.getComments的API,获取回复情况
    8) 统计表A,按ɑ排序,取前6位,即是最关心你的人
    有人说曾出现过已注销的人及非好友出现在列表中,估计是没有调用friends.areFriends API判断两者是否好友。
    但是人人的开放还是不够给力啊,好像每个API都有默认的数量限制,比如获取日志评论,默认50条。因此这个好友档案只能说明最近一段时期的情况,而且人人没有开放最近来访、留言板API,不过这几位大学生真是牛人,佩服佩服。
    为什么会这么火?
    该应用上线不足10天,参与人数保守已逾 1121116人,并曾数度服务器过载。我觉得可能是以下这些原因:
    基于好友信息的统计,不是一个人玩,可互动。
    把虚拟的人际关系用客观的数据图表形式生动的展现出来,很新鲜很有趣。
    可以了解好友的一些信息,更可以了解自己自己的人脉。
    当然,还有一条,缺爱的孩纸们很想知道谁最关心自己……
    PS:开发这个应用的那几位大学生、玩这应用的孩纸们包括回答问题的我,都好无聊啊好无聊

    本问答由谢梦非提供

  • 谢梦非 | 2017-09-10 09:33:53

    def getFriendsInfo():
    global mapData,universityData,sexData
    try:
    res=rr.call(method='friends.get',page="1",count="2000")
    res=rr.call(method='users.getInfo',uids=",".join(map(str,res)),fields="sex,hometown_location,university_history")
    except:
    sys.exit(-1)
    male,female=0,0
    prov,univ={},{}
    male=len(filter(lambda p:p['sex']==1,res))
    female=len(res)-male
    sexData={'sex':sex,'manN':male,'womanN':female}
    for p in filter(lambda p:'hometown_location' in p,res):
    loc=p['hometown_location']
    if 'province' in loc and loc['province']!='':
    t=loc['province']
    if t in prov:
    prov[t]+=1
    else:
    prov[t]=1
    for p in filter(lambda p:'university_history' in p,res):
    for info in p['university_history']:
    u=info['name']
    if u in univ:
    univ[u]+=1
    else:
    univ[u]=1
    prov=sorted(prov.items(),key=lambda x:-x[1])
    t={}
    i=0
    for name,num in prov:
    t[i]={'name':name.encode('utf-8'),'number':num}
    i+=1
    if i==5:break
    mapData=t
    mapData['totalN']=male+female
    univ=sorted(univ.items(),key=lambda x:-x[1])
    t={}
    i=0
    for name,num in univ:
    t[i]={'name':name.encode('utf-8'),'number':num}
    i+=1
    if i==10:break
    universityData=t
    pickle.dump(sexData,file(getDataPath(uid,'sex'),"wb"))
    pickle.dump(universityData,file(getDataPath(uid,'university'),"wb"))
    pickle.dump(mapData,file(getDataPath(uid,'map'),"wb"))
    def getCareInfo():
    global careData
    res=rr.call(method="status.gets",uid=uid,count=30,page=1)
    care={}
    class A:
    def __init__(self,id,care):
    self.id=id
    self.care=care
    def doWork(self): #store reply userid
    id=self.id
    care=self.care
    res=rr.call(method="status.getComment",owner_id=uid,status_id=id)
    counted={}
    for cmt in res:
    t=cmt['uid']
    if str(t)==str(uid):continue
    if t in counted:continue
    counted[t]=1
    if t in care:
    care[t]+=1
    else:
    care[t]=1
    ct=len(res)
    for i in range(ct):
    Q.put(A(res[i]['status_id'],care))
    Q.join()
    ids=map(str,care.keys())
    try:
    res=rr.call(method="users.getInfo",uids=",".join(ids),fields="uid,name,sex,headurl,mainurl")
    except:
    writeLog("Error when getting friends info")
    sys.exit(-1)
    info=[]
    for t in res:
    p={}
    p['name']=t['name'].encode('utf-8')
    p['uid']=t['uid']
    p['sex']=t['sex']
    p['number']=care[t['uid']]
    if 'mainurl' in t:
    p['url']=t['mainurl']
    elif 'headurl' in t:
    p['url']=t['headurl']
    else:
    p['url']="NA"
    info.append(p)
    info=sorted(info,key=lambda x:-x['number'])
    careData={}
    for i in range(len(info)):
    careData[i+1]=info[i]
    pickle.dump(careData,file(getDataPath(uid,'care'),"wb"))
    def getHeadInfo():
    global headData
    class A:
    def __init__(self,p,uid):
    self.p=p
    self.uid=uid
    def doWork(self):
    p=self.p
    uid=self.uid
    res=rr.call(method="photos.getAlbums",uid=uid,\
    count=1)
    if res==None or len(res)==0 or isErrorMsg(res):
    p['number']=0
    else:
    p['number']=res[-1]['size']
    p={'name':name,'url':headurl,'sex':sex,'uid':uid,'number':0}
    lst=[p] # get self data
    Q.put(A(p,uid))
    headData={}
    for t in careData.values():
    p={}
    p['name']=t['name']
    p['url']=t['url']
    p['sex']=t['sex']
    p['number']=0
    Q.put(A(p,t['uid']))
    lst.append(p)
    writeLog("%d threads for head" % len(lst))
    Q.join()
    lst.sort(key=lambda x:-x['number'])
    for p in lst:
    if 'uid' in p:
    headData[0]=p #only user himself has uid field
    for p in lst[:5]:
    headData[len(headData)]=p
    pickle.dump(headData,file(getDataPath(uid,'head'),"wb"))
    def getStarInfo():
    global starData
    def getConstellation(month, date):
    dates = (21, 20, 21, 21, 22, 22, 23, 24, 24, 24, 23, 22)
    constellations = ("摩羯", "水瓶", "双鱼", "白羊", "金牛", "双子",
    "巨蟹", "狮子", "处女", "天秤", "天蝎", "射手", "摩羯")
    starid={"摩羯":1, "水瓶":2, "双鱼":3, "白羊":4, "金牛":5, "双子":6,
    "巨蟹":7, "狮子":8, "处女":9, "天秤":10, "天蝎":11, "射手":12}
    if date < dates[month-1]:
    res=constellations[month-1]
    else:
    res=constellations[month]
    return starid[res]
    ids=map(lambda x:str(x['uid']),careData.values())
    urlNameDict={}
    for t in careData.values():
    urlNameDict[t['uid']]={'name':t['name'],'url':t['url']}
    res=rr.call(method="users.getInfo",uids=",".join(ids),fields="birthday")
    pri={}
    for t in careData.values():
    pri[t['uid']]=t['number']
    info={}
    for i in range(1,13):
    info[i]={'name':'-','number':0,'url':'NA','star':i}
    for t in res:
    if 'birthday' not in t:continue
    if "0000-00-00" == t['birthday']:continue
    bd=t['birthday'].split('-')
    if len(bd)==3:
    idx=getConstellation(int(bd[1]),int(bd[2]))
    if info[idx]['number']==0 or pri[info[idx]['uid']] < pri[t['uid']]:
    info[idx]['name']=urlNameDict[t['uid']]['name']
    info[idx]['url']=urlNameDict[t['uid']]['url']
    info[idx]['uid']=t['uid']
    info[idx]['number']+=1
    starData={}
    for t in sorted(info.values(),key=lambda x:-x['number']):
    i=len(starData)+1
    starData[i]=t
    if i==3:break
    pickle.dump(starData,file(getDataPath(uid,'star'),"wb"))
    def getInfo():
    getFriendsInfo()
    getCareInfo()
    getHeadInfo()
    def worker():
    global Q
    while 1:
    item=Q.get()
    try:
    item.doWork()
    except :
    writeLog("Catch exception in Thread")
    Q.task_done()

    本问答由谢梦非提供

* 本站部分内容来源自网络,仅作分享之用,侵删。