DBscan算法实战

目录

前言

在密度聚类算法的实战部分,我们将使用国内31个省份的人口出生率和死亡率数据作为分析对象。

实战

首先,将数据读入到Python中,并绘制出生率和死亡率数据的散点图,代码如下:

# 读取外部数据
Province = pd.read_excel(r'Province.xlsx')
Province.head()
# 绘制出生率与死亡率散点图
plt.scatter(Province.Birth_Rate, Province.Death_Rate, c = 'steelblue')
# 添加轴标签
plt.xlabel('Birth_Rate')
plt.ylabel('Death_Rate')
# 显示图形
plt.show()

在这里插入图片描述

上图所示,31个点分别代表了各省份人口的出生率和死亡率,通过肉眼,就能够快速地发现三个簇,即图中的虚线框,其他不在圈内的点可能就是异常点了。接下来利用密度聚类对该数据集进行验证,代码如下:

# 读取外部数据
Province = pd.read_excel(r'Province.xlsx')
# 选取建模的变量
predictors = ['Birth_Rate','Death_Rate']
# 变量的标准化处理
X = preprocessing.scale(Province[predictors])
X = pd.DataFrame(X)


# 构建空列表,用于保存不同参数组合下的结果
res = []
# 迭代不同的eps值
for eps in np.arange(0.001,1,0.05):
    # 迭代不同的min_samples值
    for min_samples in range(2,10):
        dbscan = cluster.DBSCAN(eps = eps, min_samples = min_samples)
        # 模型拟合
        dbscan.fit(X)
        # 统计各参数组合下的聚类个数(-1表示异常点)
        n_clusters = len([i for i in set(dbscan.labels_) if i != -1])
        # 异常点的个数
        outliners = np.sum(np.where(dbscan.labels_ == -1, 1,0))
        # 统计每个簇的样本个数
        stats = str(pd.Series([i for i in dbscan.labels_ if i != -1]).value_counts().values)
        res.append({'eps':eps,'min_samples':min_samples,'n_clusters':n_clusters,'outliners':outliners,'stats':stats})
# 将迭代后的结果存储到数据框中        
df = pd.DataFrame(res)
df =df.loc[df.n_clusters == 3, :]
print(df)

在这里插入图片描述
如上表所示,如果需要将数据聚为3类,则得到如上几种参数组合,这里不妨选择eps为0.801,min_samples为3的参数值(因为该参数组合下的异常点个数比较合理)。接下来,利用如上所得的参数组合,构造密度聚类模型,实现原始数据集的聚类,代码如下:

# 中文乱码和坐标轴负号的处理
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

# 利用上述的参数组合值,重建密度聚类算法
dbscan = cluster.DBSCAN(eps = 0.801, min_samples = 3)
# 模型拟合
dbscan.fit(X)
Province['dbscan_label'] = dbscan.labels_
# 绘制聚类聚类的效果散点图
sns.lmplot(x = 'Birth_Rate', y = 'Death_Rate', hue = 'dbscan_label', data = Province,
           markers = ['*','d','^','o'], fit_reg = False, legend = False)
# 添加省份标签
for x,y,text in zip(Province.Birth_Rate,Province.Death_Rate, Province.Province):
    plt.text(x+0.1,y-0.1,text, size = 8)
# 添加参考线
plt.hlines(y = 5.8, xmin = Province.Birth_Rate.min(), xmax = Province.Birth_Rate.max(), 
           linestyles = '--', colors = 'red')
plt.vlines(x = 10, ymin = Province.Death_Rate.min(), ymax = Province.Death_Rate.max(), 
           linestyles = '--', colors = 'red')
# 添加轴标签
plt.xlabel('Birth_Rate')
plt.ylabel('Death_Rate')
# 显示图形
plt.show()

在这里插入图片描述
如上图所示,三角形、菱形和圆形所代表的点即为三个不同的簇,五角星所代表的点即为异常点,这个聚类效果还是非常不错的,对比建模之前的结论非常吻合。从上图可知,以北京、天津、上海为代表的省份,属于低出生率和低死亡率类型;广东、宁夏和新疆三个省份属于高出生率和低死亡率类型;江苏、四川、湖北为代表的省份属于高出生率和高死亡率类型。四个异常点中,黑龙江与辽宁比较相似,属于低出生率和高死亡率类型;山东省属于极高出生率和高死亡率的省份;西藏属于高出生率和低死亡率的省份,但它与广东、宁夏和新疆更为相似。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值