想要什么
数据已经足够多了,我现在想法就是单独维护一张歌曲相似度的表,每首歌曲有10首相似度歌曲,并且有相似度的程度,介于0到1之间。
首先来明确我有什么,我有3张表。
- user表:用户1.4万左右
- music表:10万首歌曲记录(只针对中文歌曲)
- favorites表:888153条,收藏记录。表内也就是一个用户ID和一个歌曲ID
理由有:
- 业界实例,豆瓣电台的中文歌曲才8000多首
- 大多数歌曲也许只被收藏了一次或者两次,看下图:
被收藏了一次的歌曲就有47991条。几乎快占到了一半了吧?还不说要2次、3次的,2次、3次的意义也不大(这句话貌似有问题哦,因为如果出现了2次的话,那么说明有两个用户收藏了这一首歌,如果这首歌是冷门的歌曲的话,这极大的说明了两个用户的相似,这可以用来应对,某一个用户听的歌曲都比较冷门,在我们预先算好的相似度歌单里面没有太多他收藏的歌曲信息,那么我们可以再利用他的冷门歌曲找到相似用户,产生推荐歌曲列表)。
ok,说了缘由之后,我打算建立的维护的歌曲相似度表的歌曲数量大约在1万首,所以最后是一个10个条目的表。1万首歌曲当然是被用户收藏最多的歌曲。当然这个也是可以商量的,被收藏的最多,一个方面也说明了歌曲的热门程度,另一方面也更容易计算出用户的相似度。
失败的思路
先确定用户
所以,最终,我决定使用收藏歌曲在100到300之间的用户(被这1789位用户),如下图所示:
由于我边写博客边抓数据,所以实际数字还在不断的增加。
利用这些用户收藏的歌曲,来计算收藏了的歌曲的相似度。我相信能被这1789用户收藏了的歌曲应该比较普遍的歌曲,不是冷门的。我现在被这1789位用户收藏了的歌曲总共有多少首,但是这条sql语句还比较难哦。由于favorites那张表的数据已经够多了,所以复制了一张字表,该表内的内容是:收藏歌曲在100到300之间的用户的收藏记录。
sql语句如下:
CREATE TABLE smallFavorites SELECT *
FROM (
SELECT *
FROM favorites, (
SELECT userid AS uid
FROM favorites
GROUP BY userid
HAVING COUNT( userid ) >100
AND COUNT( userid ) <300
)a
WHERE favorites.userid = a.uid
)b
最后一个b虽然没有用,但是根据语法规则必须要加。
再确定歌
我查看一下有多少歌,sql语言:
SELECT musicid, COUNT( musicid ) , music.name
FROM smallfavorites
INNER JOIN music ON musicid = music.id
GROUP BY musicid
ORDER BY COUNT( musicid ) DESC
如下图所示:
我发现居然有6万多少歌。而且可以得到一些有趣的结果:原来很多人都喜欢:我的歌声里
我们必须要淘汰歌曲,首当其冲的就是只被收藏了一次的歌曲,因为这些歌曲是否有意义值得探讨。我简单的想了一下,是否存在意义的关键在于,计算相似度的方式。
如下所示一个简单的例子,用户A、B,收藏歌曲的情况a、b
a b
A 0 1
B 1 0
计算相似度的方式:如果使用皮尔逊公式计算,肯定就有意义,因为两者兴趣完全相背离。会出现相似度为-1的情况,但是如果用Tanimoto来计算,必须为0,因为两者交集为0。
不过这一次,我决定还是不删除了。当然如果计算速度太慢了,删除了先得到结果。现在虽然有6万多首歌,但是最后我将会选出1万首保留在相似度的表内。
数据以字典形式存在
#一个字典,第一个key是人名,value是又是一个字典,字典里面是key歌曲名,value是否收藏,收藏了为1,没收藏为0
critics={'Lisa Rose': {'Lady in the Water': 0, 'Snakes on a Plane': 1,
'Just My Luck': 0, 'Superman Returns': 0, 'You, Me and Dupree': 1,
'The Night Listener': 1},
'Gene Seymour':{'Lady in the Water': 0, 'Snakes on a Plane': 1,
'Just My Luck': 1, 'Superman Returns': 0, 'You, Me and Dupree': 1,
'The Night Listener': 0},
'Michael Phillips': {'Lady in the Water': 0, 'Snakes on a Plane': 1,
'Just My Luck': 1, 'Superman Returns': 0, 'You, Me and Dupree': 1,
'The Night Listener': 0},
'Claudia Puig': {'Lady in the Water': 0, 'Snakes on a Plane': 1,
'