摘要:最近,O'Reilly出版了Toby Segaran著的《Programming Collective Intelligence - Building Smart Web 2.0 Applications》(据说该书将由博文视点翻译出版),讨论如何从数据(譬如用户生成的数据)里挖掘信息的各种算法和技术,非常实用,对正在建造Web 2.0网站的开发人员尤其有用。跟大多数数据挖掘和机器学习的书不一样,书里包含了大量Python代码,使用网上现有的数据集或可以轻易采集的数据(譬如blog)或公开的API(譬如Digg,eBay的),助你理解各种算法,解释如何从大量的数据中获取关于用户体验,营销性,个人趣味,和人类行为的认识。该书得到了首创“Web 2.0”一词的O'Reilly公司CEO Tim O'Reilly的大力推荐。
其中的第二章《Making Recommendations》讨论了协作性过滤技术(Collaborative Filtering),通过搜寻一个很大的群体,从中找出与你趣味相似的人,然后把这些人喜爱的其他东西,聚合起来,创建一个推荐的排行榜(譬如电影推荐,产品推荐等等)。书中使用了del.icio.us的数据和API,可惜他们最近更改了API,所以无法使用书中的代码做练习。但想起了CSDN的网摘功能,花了点时间把大部分的网摘记录爬了下来(感谢CSDN的曾登高提供其中几个人的数据)。我把记录都放在一个名叫Post的表里了,它包含URL(用户保存的文章的地址),Title(用户保存使用的标题),UserName(用户名),PostDate(保存网址的日期)这些字段。
得到的数据集中包括3753个用户,不同的链接数为68304,最多的一个人保存了7519个链接,平均每个人保存了23个链接。保存人数最多的是这篇贴子,
40种网站设计常用技巧
链接的来源是这样的,
网站
链接数
community.csdn.net
21770
blog.csdn.net
12260
blog.donews.com
1865
topic.csdn.net
1836
news.csdn.net
1526
www.cnblogs.com
1237
book.csdn.net
831
dev.csdn.net
810
download.csdn.net
773
spaces.msn.com
758
tech.sina.com.cn
719
www.donews.net
491
blog.sina.com.cn
438
club.book.csdn.net
378
www.infoq.com
336
前十位CSDN网站占了7个,好像不是很健康啊,。
言归正传,那么针对CSDN网摘记录怎么来定义用户间的相似性?作者在这一章里讨论了欧几里德距离和Pearson相似性公式,其他的公式可以参考《数据挖掘导论》一书2.4节中的讨论(CSDN免费提供了几个章节)。在这个练习中,我将采用Tanimoto系数来定义相似性(图片来自原书网站),
在这里Na代表用户a保存的所有链接数,Nb代表用户b保存的所有链接数,Nc则代表用户Na和Nb间共同拥有的链接数。譬如,如果我保存了10个链接,你保存了20个链接,我们共有的链接为5个,那么我们间的相似性为5/(10+20-5)=0.2。
使用Tanimoto系数的的原因是对链接这样要么有,要么无的二元性的数据感觉很直观,而且容易计算(用数据库操作即可)。
先生成一个表,
create table RelatedUser (username1 nvarchar(50), username2 nvarchar(50), urlcount1 int, urlcount2 int, commoncount int, coeff decimal(18,16))
然后填充其中的数据,针对用户做个cross product,然后更新共有的链接数以及各自的链接数,
insert into relateduser (username1, username2, commoncount)select username1, username2, count(url) from(select p1.username as username1, p2.username as username2, p1.urlfrom post p1, post p2where p1.url=p2.urland p1.username <> p2.username) tgroup by username1, username2
go
update relateduser set urlcount1 = ps.urlcount from relateduser uinner join (select count(*) urlcount, username from post group by username) pson u.username1 = ps.username
go
update relateduser set urlcount2 = ps.urlcount from relateduser uinner join (select count(*) urlcount, username......[
阅读全文]