我希望根据用户观看的节目的类别或标签对用户进行分组。什么是最简单/最好的算法呢?
假设我有大约20,000个标签和数百万个可用作信号的监视事件,我是否可以使用say pig / hadoop / mortar或者neo4j来实现算法?
在数据方面,我有用户,他们观看的节目以及节目所拥有的标签(通常每个节目大约10个标签)。
我想期待最后k个群集(可能是十几个?)或广泛的桶,我可以用它来分类和分组我的用户到桶中,并获得一些关于如何划分它们的见解 - 用代表每个集群的标签集。
我已经看到一些帖子提出了分层算法,但不确定如何计算"距离"在这种情况下。这是两个用户之间的距离,还是用户和一组标签之间的距离等。
答案 0 :(得分:2)
您基本上希望根据标签群集用户。
为了简单起见,假设您只有10个标签(而不是20,000个标签)。假设用户(例如user_34)具有第2和第7个标记。对于此群集任务,user_34可以在 10维空间中表示为点,其对应的坐标为:[0,1,0,0,0, 0,1,0,0,0]。
在您自己的情况下,每个用户可以类似地表示为20,000维空间中的一个点。 您可以使用包含许多有效聚类算法的Apache Mahout,例如K-means。
由于在数学坐标系中一切都很明确,因此计算任意两个用户之间的距离很容易!它可以使用任何距离函数计算,但欧几里德距离是事实上的标准。
注意: Mahout和许多其他数据挖掘程序支持许多适合SPARSE功能的格式,即您不需要插入 ...,0,0,0,0, ... 在文件中,但只需要指定选择哪些标签。 (见RandomAccessSparseVector in Mahout.)
注意:我假设您只想对用户进行群集。从集群中提取代表性信息有点棘手。例如,对于每个群集,您可以选择群集用户之间更常见的标记。或者,您可以使用信息理论中的概念,例如信息获取,以找出哪些标记包含有关群集的更多信息。
答案 1 :(得分:1)
您应该考虑使用neo4j
。您可以使用以下节点标签和关系类型对数据建模。
如果您不熟悉neo4j的Cypher语言表示法,(:Foo)
表示标签为Foo
的节点,[:BAR]
表示与该类型的关系BAR
。关系周围的箭头表示其方向性。 neo4j有效地遍历两个方向的关系。
(:Cluster) -[:INCLUDES_TAG]-> (:Tag) <-[:HAS_TAG]- (:Program) <-[:WATCHED]- (:User)
您拥有k
Cluster
个节点,20K Tag
个节点以及数百万WATCHED
个关系。
使用此模型,从任何给定的Cluster
节点开始,您可以有效地查找其所有相关标签,程序和用户。