目录
项目相关链接
参与工作
数据流图绘制
类图绘制
顺序图绘制
后端开发
1. 点赞模块
点赞模块中包含三个功能,分别是判断用户是否对某个内容点赞
、点赞该内容
、取消点赞该内容
功能模块
query_like(user_id, item_type, item_id)
判断用户是否对某个内容点赞
:param user_id: 用户id
:param item_type: 内容种类
:param item_id: 内容对象id
:return:
返回值为True表示存在点赞记录
返回值为False表示不存在点赞记录like(user_id, item_type, item_id)
点赞
:param user_id: 点赞的用户id
:param item_type: 点赞的内容种类(歌曲等)
:param item_id: 点赞的对象id
:return: jsonifydislike(user_id, item_type, item_id)
取消赞
:param user_id: 取消赞的用户id
:param item_type: 取消赞的内容种类(歌曲等)
:param item_id: 取消赞的对象id
:return:jsonify
模块接口
@web.route('/v1/thumbs/like', methods=['POST'])
@web.route('/v1/thumbs/dislike', methods=['POST'])
2. 评论模块
评论模块中包含四个功能,分别是加载评论
、发送评论
、删除评论
、修改评论
功能模块
load_comment(user_id, item_type, item_id)
获取评论--->最新的评论最先
:param user_id: 用户id
:param item_type: 评论所属的种类(歌曲、歌单等)
:param item_id: 评论的具体对象id
:return: 返回一个列表与一个int
列表长度为0则表示无评论。列表的每一项为一个字典类型,作为一条评论记录add_comment(user_id, item_type, item_id, content)
发送一条评论
:param user_id: 发送评论的用户id
:param item_type: 评论的对象(歌曲等)
:param item_id: 评论对象的id
:param content: 评论的内容
:return: jsonifydelete_comment(user_id, comment_id)
删除一条评论
:param user_id: 用户id
:param comment_id: 评论id
:return: jsonifymodify_comment(user_id, comment_id, content)
修改评论内容
:param comment_id: 要修改的评论id
:param content: 修改后的评论内容
:return: jsonify
模块接口
@web.route('/v1/comment/load_comment', methods=['POST'])
@web.route('/v1/comment/add_comment', methods=['POST'])
@web.route('/v1/comment/delete_comment', methods=['POST'])
@web.route('/v1/comment/modify_comment', methods=['POST'])
3. 动态模块
动态模块包含四个功能,分别是加载动态
、发布动态
、删除动态
、修改动态内容
功能模块
load_zone(user_id)
获取用户动态列表--->最新的动态最先
SQL嵌套关系:获取当前用户所关注的用户->获取关注的用户所发的动态 *注:用户默认关注自己,由此获取自身所发的动态
:param user_id: 获取动态的用户id
:return: 返回一个列表,列表长度为0则表示无动态。列表的每一项为一个字典类型,作为一条动态记录。add_zone(user_id, content, item_type, item_id)
发一条新的动态
:param user_id: 发动态的用户id
:param content: 发动态的内容
:param item_type: 动态所分享的内容,为0表示无内容
:param item_id: 动态所分享内容的id
:return: jsonifydelete_zone(user_id, zone_id)
删除一条动态(保证动态属于用户本身)
:param user_id: 用户id
:param zone_id: 要删除的动态id
:return: jsonifymodify_zone(user_id, zone_id, content)
修改动态内容
:param user_id: 用户id
:param zone_id: 要修改的动态id
:param content: 修改后的动态内容
:return: jsonify
模块接口
@web.route('/v1/zone/load_zone', methods=['POST'])
@web.route('/v1/zone/add_zone', methods=['POST'])
@web.route('/v1/zone/delete_zone', methods=['POST'])
@web.route('/v1/zone/modify_zone', methods=['POST'])
4. 根据用户喜好推荐具有相似兴趣的用户
通过查找目标用户的点赞记录来描绘用户的兴趣画像,通过设定权重β
来实现结合user-based
与item-based
两种推荐方法的协同过滤推荐。
数据库实际存储的为用户的点赞记录,并用0、1进行标识,因此实际上为一个二分类。
关键方法
load_liked_items()
根据数据库查找每一个用户所点赞的内容
:return: 返回一个字典,包含用户id与item复合键的键值对compute_common_num(row1, row2)
计算两个用户点赞记录中共有项目的个数(均为1)
:param row1: 记录1
:param row2: 记录2
:return: 共有项目个数
注:由于是使用二分类属性进行计算,故采用cosine相似度
Eucclidean距离适用于衡量两者之间的差异度,故不适宜
Pearson系数使用于计算分值/等级的相似度计算,不适用于二分类
compute_cosine_similarity(row1, row2)
计算两个用户的cosine相似度
:param row1: 记录1
:param row2: 记录2
:return: 相似度generate_user_item_matrix(user_items)
生成 用户-物品 矩阵
:param user_items: 一个字点,包含user_id与list(items)的键值对
:return: 用户-物品 矩阵cold_start(user_id, matrix, indexes)
冷启动 -> 应对用户没有任何点赞记录的情况
此处采用从众原则,若某个项目若喜欢人数过半则默认新用户喜欢user_based_recommend(self, user_id, indexes, user_item_matrix, max_recommend_num=10)
基于用户的推荐算法
计算推荐目标用户与其余用户的相似度,根据相似度给出推荐
:param user_id: 用户id
:param indexes: 实际id与矩阵编号的转换关系
:param user_item_matrix: 用户-物品 矩阵
:param max_recommend_num: 最大推荐数量限制 默认为10
:return: 根据相似度降序排列的推荐用户idgenerate_item_sim_matrix(self, user_item_matrix)
生成 物品相似度 矩阵
:param user_item_matrix: 用户-物品 矩阵
:return: 物品相似度 矩阵item_based_recommend(user_id, indexes, item_similarity, user_item_matrix, max_recommend_num=10)
基于物品的推荐算法
先计算出物品与物品之间的相似度,
再根据目标用户以前的行为偏好计算对不同物品的兴趣度,
最终根据物品兴趣度计算对其他用户的兴趣度
:param user_id: 用户id
:param indexes: 实际id与矩阵编号的转换关系
:param item_similarity: 物品相似度 矩阵
:param user_item_matrix: 用户-物品 矩阵
:param max_recommend_num: 最大推荐数量限制 默认为10
:return: 根据兴趣度降序排列的推荐用户idmerge_recommend(user_based, item_based, beta=0.6)
根据一定权重将 user-based与item-based推荐结果结合
:param user_based: user-based推荐结果
:param item_based: item-based推荐结果
:param beta: 权重 默认为0.6 -> item-based结果占比 -> 计算方法为β* item-based + (1-β)* user-based
:return: 根据得分降序的最终推荐结果
模块接口
@web.route('/v1/recommend/user', methods=['POST'])
项目总结
项目概念产生
我们团队所实现的工程是一个音乐社区,这个想法并不是一拍脑袋就产生的,这个想法的本质来源在于我们团队中每一个成员对于音乐的由衷热爱。目前市场上所存在的网络社交平台比比皆是,微博、知乎、豆瓣等平台都拥有大量的活跃用户与流量。无论是哪一个平台,都拥有五花八门的版块和各种为了吸引用户而推出的眼花缭乱的功能。单纯地为了音乐本身、音乐交流而存在的社交平台却少之又少。尽管豆瓣拥有音乐版块,但它本身关注于电影点评的特性使得它的音乐社区没有那么纯粹。因此为了音乐本质交流而服务的Violet社区的想法应运而生。至于为什么叫Violet社区,这个名称的由来在于a shrinking violet这个短语,意为“羞怯的人”。旨希望为在现实生活中不善于表达自己的人能够在社区里面拥有畅所欲言表达对音乐感想的自由天地。
同类产品比较
为了避免由于闭门造车而作出偏离于实际的产品,我们对现有的社交平台进行了一定的比较与借鉴。与微博的超级话题、豆瓣的圈子动能相似,交流的社区必然要满足用户多样化与个性化的讨论需求。一个圈子或一个话题是为了某一特定的主题或用户受众而存在,并且这些话题会随时时代与网络趋势不断变迁,因此事先一个让用户自由创建、自主管理的版块是非常重要的。因此我们对豆瓣的圈子模块与百度贴吧的帖子进行了融合,即可以由用户自主创建圈子,同时能在圈子内自由发帖并带有跟帖回帖功能。为了更加凸显用户本身的个性,借鉴了微博本身的博文与微信的朋友圈,实现了用户管理自身动态,同时可以浏览关注用户的动态的功能。
团队协作
在实际的实践过程中,团队协作是最为重要的一个方面。一个工程的完成必然伴随着功能的细化与具体落实,每一个步骤都不可能由一个人完成。一个具有凝聚力且高效的团队,信任感是至关重要的。这意味着一个有凝聚力的、高效的团队成员学需要迅速且心平气和地承认自己的错误与弱点。同时还要乐于认可别人的长处。这样才有利于工程的每一个模块都由最适合完成的人负责,并且如果产生了错误与问题能够迅速进行纠正。除此之外,要成为一个具有凝聚力的团队,管理者扮演着一个至关重要的角色,他需要在没有完善的信息、没有统一的意见时做出决策,并付诸行动。因为完善的信息和绝对的一致往往是非常罕见的,坚定的行动力就成为一个团队最为关键的行为之一。在长期的合作与磨合之下我对团队的每一个成员都有了更为深入的了解,并且都或多或少发现了他们身上的闪光点,成为我今后值得学习的地方。
知识获取
在项目的实际开发工程中,丰富了我的知识层面。了解到了MVC(模型(model)-视图(view)-控制器(controller))这一软件设计典范并予以实践。在前后端交互方面学习了JSON的具体应用,同时对Ajax技术有了初步的认知。除此之外,实际开发过程中可能会遇到技术储备中所没有的需求,这就需要在开发的工程中进行相关领域知识的学习,例如基于协同过滤的推荐系统,在尝试实现的过程中令我受益颇多。良好的代码风格也十分重要,具象且符合实际的变量命名、勤写注释的习惯都能够易于代码的阅读与维护,也能益于不同工作的交接。
意见和建议
课堂讲授
老师在对软件工程知识的讲授过程中往往会穿插许多实际生活中的案例,这些案例往往非常翔实,这说明老师的社会经验与个人阅历非常丰富,并且乐于和学生分享这些经验从而让我们少走弯路。但是或许是由于老师的思维过于活跃,常常在分享案例时一发而不可收拾,越走越远,最终偏离讲授内容的主线。虽然内容听起来并不枯燥,但是此时再回到正式的教学内容中会非常影响听课质感,听课的连贯性受到影响,有时也会变得较难集中注意力。诚然,老师的授课风格是具有鲜明的个性的,但是希望在将来的教学中能够注重讲课的连贯性,或者是略微穿插若干案例,尽量控制不走太远,社会上的逸闻趣事与人生经验可以留待学生的实践过程中再去分享。
进度安排
最终的大作业的每一个阶段缺少明确的deadline。本学期自从大作业布置并正确开始后,我们几乎是每次上课时才知道这周的任务是什么,从而确定未来一周每个人将要完成的工作。如果有明确的安排例如:第X周时应当完成需求文档、第Y周时应当完成顺序图的绘制、第Z周应当完成原型设计等并且在一开始就直接公布,对于各组各自进度的把握与工作的开展会更加友好。在此前提下,学有余力的小组可以提前做好相关知识的预习,对上课内容提前做好铺垫,若进度大幅超前也可能实现一些有趣的功能拓展,达到更好的学习效果。