DBSCAN
本课属于 Coddy Machine Learning 学习旅程的“无监督学习”单元。第 20 课,共 51 课。
本章将找出各种形状的人群,以及不属于任何人群的点。学完后,你将绘制山谷中的灯光分布图:
首先,回顾一下“当 K-Means 失效”一课中让 k-means 失效的海豹沙洲。DBSCAN 则会跟随人群:
一个点在半径为 eps 的圆内有 min_samples 个点(包括它自己),就属于一个人群。人群会通过这样的点扩散。不需要选择 k:
from sklearn.cluster import DBSCAN
labels = DBSCAN(eps=0.2, min_samples=5).fit_predict(X)
print(labels.max() + 1)这会输出 2:人群从 0 开始编号,所以最大编号加 1 就是人群的数量。
挑战
中等在一座结冰的湖面上,滑冰者沿着一条蜿蜒穿过两座岛屿之间的路线竞速,观众则在观看一场冰球比赛。k-means 会把这条路线切成几段。程序会读取以米为单位的 eps。
- 用这个 eps 和
min_samples=5拟合 DBSCAN,并将人群标签保存在labels中。 - 打印找到的人群数量。
- 用
draw_crowds(ax, X, labels)绘制这些人群并显示图表。
换一座湖,eps 设为 3.5:
Crowds found: 3Coddy 会描述你的图表。然后用 eps 8 运行它:这些人群去哪儿了?
亲手试试
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
# 170 名滑冰者在冰封湖面上的位置,单位为米
skaters = pd.read_csv("skaters.csv")
X = np.column_stack([skaters["x_m"], skaters["y_m"]])
eps = float(input())
# 用不同颜色绘制每群人,并标出各群人数
def draw_crowds(ax, X, labels):
for crowd in range(labels.max() + 1):
rows = labels == crowd
ax.scatter(X[rows, 0], X[rows, 1], s=14, label=f"{rows.sum()} skaters")
ax.legend()
fig, ax = plt.subplots()
ax.set_title("Skaters on the Lake")
ax.set_xlabel("East (m)")
ax.set_ylabel("North (m)")
# 在下方编写你的代码
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
无监督学习中的所有课
自己练习: Python 在线编译器