我有一个类似潘多拉的软件,用户可以用一首歌或拇指向下翻歌。这个名为Chavah的软件是Silverlight + C#,但这是一个语言和平台无关的问题。
我的软件需要根据用户的偏好选择一首歌曲。我需要一个很好的算法。
我希望我的软件根据以下要求选择要播放的歌曲:
赞成歌曲应该受到青睐, 并经常玩。
未分级 歌曲(既没有翻阅也没有向下) 还是应该玩;毕竟, 用户可能只有2个 翻阅了歌曲。
很少播放歌曲。
无论算法是什么,歌曲都不应经常重复。
鉴于这些设计决策,这里有一些好的算法吗?
我有一些代码可以抓取所有歌曲,喜欢的歌曲和不喜欢的歌曲:
var allSongs = ...
var likedSongs = allSongs.Where(s => s.LikedByUser(...));
var dislikedSongs = allSongs.Where(s => s.DislikedByUser(...));
为用户选择好歌的任何简单想法?
答案 0 :(得分:2)
你可以加重歌曲;比如说每首歌的开头都是1.0分,如果大拇指缩小则是0.5分,如果是大拇指则分数是1.5分。然后你从所有得分的集合中挑选一个随机元素,然而它的概率除以它的重量。我在这里想到的快速而肮脏的方法是总结所有权重。选择一个小于该总和的随机数。循环播放所有歌曲,直到CurrentWeight + SongWeight> RandomNumber(否则为CurrentWeight + = SongWeight)
当然,通过引入协同过滤,你可以使这个任意变得更加复杂:)
想象一下五首歌。前两个翻阅,下一个翻阅,两个中立。
{1:1.5,2:1.5,3:0.5,4:1,5:1}
这个总和是5.5。现在我们选择一个随机数< 5.5并看:它是2.43789
现在让我们找一下这个随机数所属的歌曲。
从CurrentWeight = 0开始。第一首歌的重量= 1.5。 CurrentWeight + 1.5< 2.43789 - >我们继续,但通过这首歌的重量增加CurrentWeight。
所以CurrentWeight = 1.5现在。下一首歌的重量:再次1.5。但是现在,CurrentWeight + 1.5 == 3> 2.43789。这意味着我们选择了第二首歌!
你在这里做的是基本上在一条线上选择一个随机点,但是增加该线上的“区域”,如果该歌曲被翻阅,它将选择一首歌。
这是否会产生多次重复,这主要取决于你增加/减少歌曲重量的强度。
答案 1 :(得分:1)
我假设Pandora使用标记系统对他们的歌曲进行分类。通过这种方式,您可以通过对“拇指向上”的标签的最高频率进行采样来开发用户音乐品味的配置文件。不幸的是,他们从一个庞大的标记音乐数据库中提取给用户,这可能比选择它们的算法更难开发。
答案 2 :(得分:1)
您还可以为乐队/歌手和流派创建一个评级系统,并根据每个“拇指向上”,您可以为乐队/歌手和流派添加1(或您决定的任何值)。然后,当决定播放下一首歌曲时,您可以根据所述用户对乐队/歌手和/或流派的兴趣来加权决定。与“翻阅”歌曲相反。
答案 3 :(得分:1)
也许是这样的:
1)创建三个随机排序的歌曲流(或播放列表),例如你的代码片段,但要使它们互相排斥:喜欢,不喜欢,不评价。根据这些群体的规模,他们每个群体在重复之前都有一段时间。
2)创建一个函数,将流合并为单个流,同时遵守某些规则。主要规则是所需的混合流,例如60%喜欢,38%未评级,2%不喜欢或其他。只有当喜欢的流的持续时间太短而无法遵循“歌曲重复之间的最短时间”规则时,您才必须偏离所需的混音。
3)您可能还想定期重新计算所有流。这里棘手的部分可能是避免重新计算造成的重复。也许你在(1)中的随机排序也可以考虑到最近播放的歌曲附加的某种重量或偏移量。