python实现用户好友推荐

如果能获取通讯录权限,可通过用户通讯录推荐

这里仅简单得根据与用户的共同好友数推荐

代码如下:

python
import pymongo
import random


class Mongodb(object):
    def __init__(self, host, port, db):
        try:
            my_client = pymongo.MongoClient(host + ':' + port)
        except Exception:
            raise Exception('Cannot connect to server')
        else:
            self.db_ais = my_client[db]


class UsersRecommend:
    def __init__(self, uuid):
        self.uuid = uuid
        self.my_db = Mongodb('mongodb://localhost', 'xxxxx', 'xxx')  # 连接数据库,可用mysql
        self.res_data = list(self.my_db.db_ais['friends'].find({'status': {'$in': [2, -1]}}, {'toUserId': 1, 'userId': 1}))  # 查询所有用户好友关系表
        self.direct_f = self.get_friends(uuid)  # 用户好友
        if len(self.direct_f) > 50:  # 好友过多时取随机50个
            self.direct_f = random.sample(self.direct_f, 50)

    def recommend_f(self, pageno, pagesize):
        if len(self.direct_f) > 0:
            indirect_f = [{'indirect_id': x, 'relations': []} for x in self.direct_f]  # 间接好友初始化
            for x in self.res_data:  # 遍历res_data, 统计间接好友的好友列表
                if x['userId'] in self.direct_f and x['toUserId'] not in self.direct_f and x['toUserId'] != self.uuid:
                    indirect_f[self.direct_f.index(x['userId'])]['relations'].append(x['toUserId'])
            recommends, recommends_idx = [], []
            for x in indirect_f:
                if len(x['relations']) > 50:  # 跳过直接好友中好友过多的
                    continue
                for y in x['relations']:
                    if y not in recommends_idx:
                        recommends_idx.append(y)
                        recommends.append({'uid': y, 'num': 0, 'score': 0})
                    recommends[recommends_idx.index(y)]['score'] += 1  # 可惩罚‘过热’用户
                    recommends[recommends_idx.index(y)]['num'] += 1
            recommends.sort(key=lambda x: x['score'], reverse=True)  # 按共同好友数排序
            return [{'uid': x['uid'], 'common_friends': x['num']} for x in recommends][(pageno - 1) * pagesize:pageno * pagesize]  # 分页
        else:  # 用户尚未添加一个好友
            return []

    # 获取指定用户的好友列表
    def get_friends(self, usr_id):
        return [x['toUserId'] for x in self.res_data if x['userId'] == usr_id]


# 调试
# res = UserRecommend(10073926).recommend_f(1, 10)
# print(res)

demo里相似度计算用共同好友数代替了。

对与共同好友,可根据其好友数计算其score,然后得到相似度,根据相似度排序。具体可参考这篇博文:好友推荐算法-基于关系的推荐

Last updated: