用Python创建一个简单的推荐系统

时间:2017-07-18 04:27:48

标签: python graph

我正在尝试创建一个简单的推荐系统,向用户推荐他们的朋友正在阅读的书籍。我创建了一个名为“推荐”的类,它捕获用户的详细信息,如姓名,用户的朋友,用户的书籍和推荐的书籍(朋友的书)。现在问题是当用户'A'的实例被创建时,'A的推荐书籍列表是空的,因为它的朋友'B'还没有被实例化。当'B'确实被实例化时,'A'仍然没有关于B的书的线索,因为'A'已经在'B'之前被实例化。有办法解决这个问题吗?

from collections import defaultdict


class recommendation: 
    friendsgraph =  defaultdict(set)  # key: user, value: friends of users
    booksgraph =  defaultdict(set)    # key: user, value: books of user       

    def __init__(self, user, books, friends):
        self.name = user
        self.books  = books
        self.friends = friends
        self.recommended_books = friendsbooks(friends)

        recommendation.friendsgraph[user] = friends
        recommendation.friendsgraph[user] = books

    def friendsbooks(friends):
        recommendation_list = set()
        for friend in friends:
            rec_books = recommendation.booksgraph[friend]
            if rec_books:
                recommendation_list.add(rec_books)
            else:
                recommendation_list = ()
        return recommendation_list


A = recommendation('A',('Harry Potter'),('B'))
B = recommendation('B',('Harry Potter', 'Master Algo'),('A','C'))

解决此问题的一种方法是将朋友和书籍的词典作为属性传递,并编写一个单独的方法来推荐书籍。这样,每个用户在实例化时都会知道它的朋友和他们的书。但是,此策略会将属性与各个用户(例如A.recommended_books)关联起来。

class recommendation:            

    def __init__(self):
        self.friendsgraph = defaultdict(set)
        self.booksgraph  = defaultdict(set)

2 个答案:

答案 0 :(得分:0)

快速5分钟的模型显示替代方案:

class User:
    def __init__(self, name, books=[], friends=[]):
        self.name = name
        self.books = books
        self.friends = friends

    def friendsbooks(self):
        books = set()
        for friend in self.friends:
            books.update(friend.books)
        return books

class Book:
    def __init__(self, name):
        self.name = name
        # Possibility of extending ..

    def __repr__(self):
        return self.name

books = [Book('Harry Potter'), Book('Master Algo')]
users = [
    User('A', books=[books[1]]),
    User('B', books=[books[0], books[1]]),
    User('C', books=[books[0]]),
]
users[0].friends = [users[1]]
users[1].friends = [users[0], users[2]]
users[2].friends = [users[0]]

print(users[2].friendsbooks())

输出:

{Master Algo, Harry Potter}
{Master Algo, Harry Potter}
{Master Algo}

添加初始数据确实有点复杂,但你会弄明白。肯定有一些改进。

答案 1 :(得分:0)

以下修改解决了该问题:

from collections import defaultdict

class recommendation:            
    friendsgraph =  defaultdict(set)
    booksgraph =  defaultdict(set)

    def __init__(self, user, books, friends):
        self.name = user
        self.books  = books
        self.friends = friends

        recommendation.friendsgraph[user] =  friends
        recommendation.booksgraph[user] = books


    def friendsbooks(self):
        recommendation_list = set()
        for friend in self.friends:
           rec_books = recommendation.booksgraph[friend]
           if rec_books:
              recommendation_list.add(rec_books)
        return recommendation_list

A = recommendation('A',('Neverland Land'),('B'))
B = recommendation('B',('Harry Potter', 'Master Algo'),('A'))

print A.friendsbooks()
print B.friendsbooks()

输出:

{('Harry Potter', 'Master Algo')}
{'Neverland Land'}