机器学习之无监督学习:聚类

前置准备

推荐安装Python3.8及以上环境,选择一款适合的开发环境,下载案例所需的实验数据(提取码:BigG),安装必备的第三方库如下图:
机器学习之无监督学习:聚类_第1张图片

K-means方法及应用

实现机理

K-means算法以k为参数,将n个对象分为k个簇,使得簇内具有较高的相似度,簇间的相似度较低。
K-means的处理过程如下:
1.随机选择k个点作为初始的聚类中心
2.对于剩下的点,根据每个点与聚类中心的距离,将其归入最近的簇
3.对于每个簇,计算所有点的均值作为新的聚类中心
4.重复第2、3步骤,直到聚类中心不再发生改变
聚类算法如下图,有ABCDE共5个点,随机选择2个点(黄、红)作为初始的聚类中心,通过算法将其分为2个簇:
机器学习之无监督学习:聚类_第2张图片

K-means的应用

根据下载的数据(前文中已给链接)(1999年全国31省份城镇居民家庭平均每人全年消费支出的八个主要变量数据:食品、衣着、家庭设备用品及服务、医疗保健、交通和通讯、娱乐教育文化服务、居住、杂项商品和服务)应用K-means方法进行聚类

效果图

1.聚成2类:km = KMeans(n_clusters=2)
在这里插入图片描述

2.聚成3类:km = KMeans(n_clusters=3)
在这里插入图片描述
在这里插入图片描述

3.聚成4类:km = KMeans(n_clusters=4)

源代码

#31省市居民家庭消费调查
import numpy as np
from sklearn.cluster import KMeans

def loadData(filePath): #自定义loadData函数,用于读取txt文件的数据
    fr = open(filePath, 'r+') #r+读写打开文本文件
    lines = fr.readlines() #一次性读取文本内容,前提是文件不够大且内存充足
    retData = [] #存放城市的消费数据
    retCityName = [] #存放城市的名字
    for line in lines: #逐行遍历文件内容
        items = line.strip().split(",")
        retCityName.append(items[0])
        retData.append([float(items[i]) for i in range(1, len(items))]) #追加数据,范围是1~items的长度
    return retData, retCityName

def main():
    data, cityName = loadData('31省市居民家庭消费调查.txt')
    km = KMeans(n_clusters=4) #KMeans方法创建实例,n_clusters为用于指定聚类中心的个数
    label = km.fit_predict(data) #调用km实例的fit_predict()方法计算簇的中心并分配序号,获得label标签
    expenses = np.sum(km.cluster_centers_, axis=1) #km.cluster_centers为实例的聚类的中心,axis为按行求和
    #print(expenses)
    CityCluster = [[], [], [], []] #因为n_clusters的值为4,所以需要4个子列表
    for i in range(len(cityName)): #范围是城市的个数
        CityCluster[label[i]].append(cityName[i]) #将城市按label分成设定的簇
    for i in range(len(CityCluster)):
        #print("expense = {:.2f}".format(expenses[i]))
        print("平均消费:{:.2f}".format(expenses[i])) #输出每个簇的平均花费
        print(CityCluster[i]) #输出每个簇的城市

main()

DBSCAN方法及应用

实现机理

DBSCAN是一种基于密度的聚类算法,它不需要预先指定簇的个数,并且最终簇的个数也不定。
根据算法,将数据点分为三类:

  • 核心点:在半径Eps内含有超过MinPts数目的点
  • 边界点:在半径Eps内点的数量小于MinPts,但是落在核心点的领域内
  • 噪音点:既不是核心点也不是边界点的点
    DBSCAN密度聚类三种点如下图所示:
    机器学习之无监督学习:聚类_第3张图片
    DBSCAN算法流程如下:
    1.将所有点标记为核心点、边界点或噪声点
    2.删除噪声点
    3.将距离在Eps内的所有核心点之间赋予一条边
    4.每组联通的核心点形成一个簇
    5.将每个边界点指派到一个与之关联的核心点的簇中

DBSCAN的应用

现有大学校园网的日志数据(前文中已给链接),290条大学生的校园网使用情况数据,数据包括用户ID、设备的MAC地址、IP地址、开始上网时间、停止上网时间、上网时长、校园网套餐等。利用已有的数据,分析学生上网的模式。
单条数据格式如下图:
机器学习之无监督学习:聚类_第4张图片

效果图

1.控制台的聚类结果:
机器学习之无监督学习:聚类_第5张图片
2.使用matplotlib的可视化显示结果:
机器学习之无监督学习:聚类_第6张图片
分析结果,可得如下结论:学生在22-23点上网时间居多

源代码

#学生月上网时间分布.py
import numpy as np
import sklearn.cluster as skc
from sklearn import metrics
import matplotlib.pyplot as plt


mac2id = dict() #mac2id是一个字典,key为mac地址,value为对应的上网时长和开始上网时间
onlinetimes = []
f = open('学生月上网时间分布.txt', encoding='utf-8')
for line in f:
    mac = line.split(',')[2] #读取每条数据中的mac地址
    onlinetime = int(line.split(',')[6]) #读取每条数据中的开始上网时间
    starttime = int(line.split(',')[4].split(' ')[1].split(':')[0]) #读取每条数据中的上网时长
    if mac not in mac2id:
        mac2id[mac] = len(onlinetimes)
        onlinetimes.append((starttime, onlinetime))
    else:
        onlinetimes[mac2id[mac]] = [(starttime, onlinetime)]
real_X = np.array(onlinetimes).reshape((-1, 2))

X = real_X[:,0:1]

db = skc.DBSCAN(eps=0.01, min_samples=20).fit(X) #调用DBSCAN方法进行训练
labels = db.labels_ #labels为每个数据的标签

print('Labels:')
print(labels)
raito = len(labels[labels[:] == -1]) / len(labels) #计算噪声数据的比例
print('Noise raito:', format(raito, '.2%'))

n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0) #计算簇的个数

print("Estimated number of clusters: {:d}".format(n_clusters_))
print("Silhouette Coefficient: {:.3f}".format(metrics.silhouette_score(X, labels))) #打印聚类效果

for i in range(n_clusters_): #打印每个簇标号和簇内的数据
    print('Cluster ', i, ':')
    print(list(X[labels == i].flatten()))
    
plt.hist(X, 24)
plt.show()

注:本文是博主机器学习课程的心得总结,不支持任何商用且不支持转载!如果你也对机器学习有一定的兴趣和理解,欢迎随时找博主交流~

你可能感兴趣的:(我的机器学习之路,机器学习,聚类,python,数据挖掘,数据可视化)