K-means算法原理
K-means聚类算法以k为参数,把n个对象分为k个簇,使簇内具有较高的相似度,而簇间的相似度较低。
- 随机选择k个点作为初始的聚类中心。
- 对于剩下的点,根据其与聚类中心的距离,将其归入最近的簇。
- 对每个簇,计算所有点的均值作为新的聚类中心。
- 重复2、3直到聚类中心不再改变。
K-means算法应用
需求
通过聚类,了解1999年各个省份的消费水平在国内的情况。
使用算法
K-means聚类算法
实现过程
- 建立工程,导入sklearn相关包
- 加载数据,创建K-means算法实例,并进行训练,获得标签
- 输出标签,查看结果
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| """ Created on Thu Apr 18 22:59:44 2019
@author: Jiaxi Wang """
import numpy as np from sklearn.cluster import KMeans def loadData(filePath): fr = open(filePath,'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))]) return retData,retCityName if __name__ == '__main__': data,cityName = loadData('city.txt') km = KMeans(n_clusters=4) label = km.fit_predict(data) expenses = np.sum(km.cluster_centers_,axis=1) CityCluster = [[],[],[],[]] for i in range(len(cityName)): CityCluster[label[i]].append(cityName[i]) for i in range(len(CityCluster)): print("Expenses:%.2f" % expenses[i]) print(CityCluster[i])
|
结果
聚成3类
聚成4类
拓展&改进
计算两条数据的相似性时,sklearn的K-means默认使用的时欧氏距离。该算法并没有设定更改距离计算方法的参数。
DBSCAN算法原理
DBSCAN算法是一种基于密度的聚类算法:
- 聚类的时候不需要预先指定簇的个数
- 最终的簇的个数不定
DBSCAN算法将数据点分为3类:
- 核心店:在半径Eps内含有超过MinPts数目的点。
- 边界点:在半径Eps内点的数量少于MinPts,但是落在核心点的邻域内。
- 噪音点:既不是核心点也不是边界点的点。
DBSCAN密度聚类算法流程
- 将所有点标记为核心点、边界点或噪声点
- 删除噪声点
- 为距离在Eps之内的所有核心点之间赋予一条边
- 每组连通的核心点形成一个簇
- 将每个边界点指派到一个与之关联的核心点的簇中(哪一个核心点的半径范围之内)
DBSCAN算法应用
背景
现有某大学校园网的日志数据,290条大学生的校园网使用情况数据,数据包括用户ID,设备MAC地址,IP地址,开始上网时间,停止上网时间,上网时长,校园网套餐等。利用已有数据,分析学生的上网模式。
需求
通过DBSCAN聚类,分析学生上网时间和上网时长的模式。
思路
- 建立工程,引入相关包
- 加载数据,预处理数据
- 上网时长的聚类分析、上网时间的聚类分析
- 分析结果
实现过程
- 建立工程,导入sklearn相关包
- 读入数据并进行处理
- 上网时间/上网时长聚类,创建DBSCAN算法实例,并进行训练,获得标签
- 输出标签,查看结果
- 画直方图,分析实验结果
- 数据分布 vs 聚类
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| """ Created on Thu Apr 18 23:35:39 2019
@author: Jiaxi Wang """
import numpy as np import sklearn.cluster as skc from sklearn import metrics import matplotlib.pyplot as plt mac2id=dict() onlinetimes=[] f=open('TestData.txt',encoding='utf-8') for line in f: mac=line.split(',')[2] 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) labels = db.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' % n_clusters_) print("Silhouette Coefficient: %0.3f"% metrics.silhouette_score(X, labels)) for i in range(n_clusters_): print('Cluster ',i,':') print(list(X[labels == i].flatten())) plt.hist(X,24)
|
结果展示