软工大作业·历物语(二)
文章来源:中国软工亚洲指挥中心
共同作者:纪神,爵爷,老板,小男孩(按首字拼音排序)
责任编辑:爵爷
进度汇总
先大致说一下这两周完成的内容:
- 登录界面
- 注册界面
- 新闻详情界面
- 用户偏好算法(初版)的设计与实现
- 通知系统
- 私信系统
- 部分实现了数据操作辅助类族
- 部分实现了推送系统
- 部分UI的优化
细节还有非常非常多,当然不是说要拘泥于细节而失去了整体意识,而是在细节的把控中了解整个项目的脉络。虽然功能远没有实现完,但是现在的项目结构已经略显臃肿了,所以下一周准备梳理一下整个项目,开始尝试自上而下地审视并重新设计一下整个结构。
本周做的工作值得细说的还是用户偏好算法的设计。用户偏好算法是我们项目的核心算法,目的是为推测出用户近期对于新闻类型的偏好,并记录在系统内,从而在之后可以让用户选择自己感兴趣的信息,并且每当发布了用户感兴趣的信息之后可以推送给用户。除此之外,最重要的一点是,系统可以根据用户的喜好向用户提供兴趣相投的好友,从而提升用户黏性,并可以隐形中推广应用。
作为一个用户偏好推测算法,可以划分到人工智能的领域,在这里我想谈一下对于算法起点的考虑。说到机器学习,普通水平的实现只要看了Coursera上吴恩达的Machine Learning就够用了(当然我是说非常简单的应用),再不然Github上一堆数千star的项目,甚至都不需要知道基本概念。但是在初版算法设计中我们并没有采用机器学习算法,这是由于以下几点考虑:
- 我们采集的数据特征值非常少
- 我们采集的数据量非常少
- 手机计算资源的限制
- 在对机器学习没有深入的研究的情况下,设计出的算法有时还不如最普通的迭代
在初版算法设计中,我们只是使用了简单的权值计算,目前先实现这版测试一下效果如何,具体设计如下:
算法目的
为推测出用户近期对于新闻类型的偏好,并记录在系统内,从而在之后可以让用户选择自己感兴趣的信息,并且每当发布了用户感兴趣的信息之后可以推送给用户。除此之外,最重要的一点是,系统可以根据用户的喜好向用户提供兴趣相投的好友,从而提升用户黏性,并可以隐形中推广应用。
算法原理
算法计算结果是用户对于某种类型的新闻的偏好程度,目的在于两部分,第一部分是推测近期趋势,第二部分是推测用户喜好。
为了体现这两部分,我们使用两个衡量指标:时间因子 $tf$ (time factor)和认真程度 $cd$ (conscientious degree)来表示。为了突出两方面的因素,我们使用高阶运算来提升权值,计算出的值为 $tpw$ (temporary preference weight)。
除此之外,由于偏好值的计算是不断迭代的,所以每次计算新的偏好值时应该考虑之前的计算结果,给定一个权值因子 $wf$ (weight factor),并设旧的用户偏好值为opw(old preference weight),则新的用户偏好值为 $npw = opw \times wf + (1 – wf) \times tpw$, 目前取 $wf$ 为0.3,并取 $opw$ 初值为0。
算法过程
把用户访问一篇新闻的时间以及在这篇新闻上的停留时间分别设为 $visitTime$ (单位:毫秒)和 $stayTime$ (单位:毫秒),考虑通过这两个因素来计算 $tf$ 和 $cd$。
- 对于 $tf$ 的计算,主要是体现用户的偏好有多“新”,考虑取看这篇新闻距离现在的时间间隔,即 $currentTime – visitTime$, 换算成天数设为 $dayInterval$, 那么可以取 $tf = \frac{30}{dayInterval + 1}$ (取30为了使 $tf$ 和 $cd$ 处于同一个数量级)
- 对于 $cd$ 的计算,取平均阅读每个字所用的时间,设新闻正文字数为 $newsLength$ ,则 $cd = \frac{stayTime}{newsLength}$
- 对于 $tpw$ 的计算,为了使越新、阅读越认真的新闻重要性越大且增长速度越来越快,可以取 $tf$ 和 $cd$ 和的平方,即 $tpw = (tf + cd) ^ 2$。而用户在某一种类的新闻浏览记录有 $n$ 条,设每条记录计算的 $tpw$ 值为 $tpwi$,综上所述可得 $tpwi = (\frac{30 \times 24 \times 3600 \times 1000}{currentTime – visitTime + 86400000} + \frac{stayTime}{newsLength}) ^ 2$
- 则 $tpw$ 最终计算结果为。最终计算所得的 $npw = wf \times opw + (1 – wf) \times tpw$。(注意:还可以考虑的一点是,如果我是信息学院计算机系的,你也是信息学院计算机系的,那么我们很可能就有共同语言,也就是同一学院、同一学系或者同一年级的用户也可能有共同的喜好,即使这一点没有体现在算法计算结果上,考虑把这一点也加在偏好算法计算中)
算法实施
我们在数据库中设置了一张用户偏好表用于记录用户偏好信息,表项有用户 $id$、新闻类型、偏好旧值和详细信息,在详细信息中记录了一个数组,数组中每一个元素都包含 $visitTime$ 和 $stayTime$ 两部分。
每当用户访问一篇新闻时,都会更新相应的表项。同时在用户表中添加一个喜好标签表项,记录用户最近最感兴趣的新闻类型,最多记录三个,太多的话匹配结果会过多,使得匹配系统没有了意义,而且用户也没有精力去关注那么多的新闻类型。当分别计算完一个用户对于各个新闻类型的喜好权值之后,将其排序,得到的前三名新闻类型放入喜好标签中。
当推送新闻时,直接根据标签过滤即可。推荐好友时,比对两人的喜好标签即可,只要有共同的标签就推荐,并且如果当前用户没有喜好标签,那么就随机从所有用户中抽取;如果当前用户有喜好标签,那么对于其他待匹配的没有喜好标签的用户而言,也采用随机抽取的办法。
关于用户喜好的计算时机,因为计算不是在服务器上完成的(用云引擎有点麻烦而且也没必要占用服务器资源),所以考虑只要用户登录了,就在后台计算用户偏好,每个登录周期偏好只计算一次。
目前为止只做了简单的试验,算法可以得到较为合理的偏好值,但是在真实的应用场景中效果如何还有待进一步的测试。