05-按长度聚类迈克尔·杰克逊的专辑
6.4 按长度聚类迈克尔·杰克逊的专辑
迈克尔·杰克逊发行过10张个人专辑。以下示例将通过两个维度对这些专辑进行聚类辑长度(以分钟为单位)和曲目数量。此示例与上面的州长示例形成鲜明对比,因为即使不运行k均值聚类算法也很容易在原始数据集中看出聚类簇。此类示例可以用作调试实现聚类算法代码的好方案。
注意 本章的两个示例都采用了两维的数据点,但k均值聚类算法对任意维度的数据点都能胜任。
本示例代码将在代码清单6-15中完整给出。如果在运行本示例代码之前查看一下代码清单6-15中的专辑数据,很明显就能看出迈克尔·杰克逊越临近职业生涯结束制作的专辑就越长。因此,专辑的两个聚类簇可能应该划分为早期专辑和晚期专辑。专辑HIStory: Past, Present, and Future, Book I则是一个野值(outlier),在逻辑上也可以归属于其自己单独的聚类簇中。所谓野值,是指位于数据集正常限值之外的数据点。
代码清单6-15 mj.py
from __future__ import annotations
from typing import List
from data_point import DataPoint
from kmeans import KMeans
class Album(DataPoint):
def __init__(self, name: str, year: int, length: float, tracks: float) -> None:
super().__init__([length, tracks])
self.name = name
self.year = year
self.length = length
self.tracks = tracks
def __repr__(self) -> str:
return f"{self.name}, {self.year}"
if __name__ == "__main__":
albums: List[Album] = [Album("Got to Be There", 1972, 35.45, 10), Album("Ben",
1972, 31.31, 10), Album("Music & Me", 1973, 32.09, 10), Album("Forever, Michael",
1975, 33.36, 10), Album("Off the Wall", 1979, 42.28, 10), Album("Thriller",
1982, 42.19, 9), Album("Bad", 1987, 48.16, 10), Album("Dangerous", 1991, 77.03,
14), Album("HIStory: Past, Present and Future, Book I", 1995, 148.58, 30),
Album("Invincible", 2001, 77.05, 16)]
kmeans: KMeans[Album] = KMeans(2, albums)
clusters: List[KMeans.Cluster] = kmeans.run()
for index, cluster in enumerate(clusters):
print(f"Cluster {index} Avg Length {cluster.centroid.dimensions[0]} Avg Tracks
{cluster.centroid.dimensions[1]}: {cluster.points}\n")
注意,属性 name 和 year 只是用于标记的记录项,在实际的聚类中并不会涉及。下面给出的是一个输出示例:
Converged after 1 iterations
Cluster 0 Avg Length –0.5458820039179509 Avg Tracks –0.5009878988684237:[Got to Be There,
1972, Ben, 1972, Music & Me, 1973, Forever, Michael, 1975,off the Wall,1979,
Thriller, 1982, Bad, 1987]
Cluster 1 Avg Length 1.2737246758085523 Avg Tracks 1.169717640263217:[Dangerous, 1991,
HIStory:Past, Present and Future, Book I,1995,Invincible,2001]
打印出来的聚类簇平均值很有意思。注意,这里的平均值是z分数。聚类簇1的3张专辑,也就是迈克尔·杰克逊的最后3张专辑,要比他全部的10张个人专辑的平均值长约一个标准差。