闲话不多说,直接上代码
# 31省市居民家庭消费调查
# 1.建立工程,导入sklearn相关包
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import matplotlib
# 2.加载数据data,创建K-Means算法实例,并进行训练,获得标签label:
# a.利用loadData方法读取数据
# b.创建实例
# c.调用Kmeans()和fit_predict()方法进行计算
if __name__ == '__main__':
def loadData(filePath):
fr = open(filePath, 'r+') # r+读写打开一个文本文件
lines = fr.readlines() # 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
data, cityName = loadData('city.txt')
km = KMeans(n_clusters=4) # n_clusters用于指定聚类中心的个数,init初始聚类中心的初始化方法,max_iter最大的迭代次数,init默认是k-means++ max_iter默认300
# label = km.fit_predict(data) # 计算簇中心以及为簇分配序号
label=km.fit(data).labels_
labels=[]
for i in range(len(label)):
labels.append(label[i])
print("所有标签值")
print(labels)
allexpenses = np.sum(data,axis=1)
# print(allexpenses)
font = {"family": "FangSong", 'size': 12}
matplotlib.rc("font", **font)
plt.figure(figsize=(12, 6))
plt.xlabel('城市')
plt.ylabel('平均消费水平')
plt.bar(cityName,allexpenses)
plt.show()
# allexpenses_sort=np.sort(allexpenses)
# print(allexpenses_sort)
expenses = np.sum(km.cluster_centers_, axis=1) # 平均消费水平
expenses_list=[]
for i in range(len(expenses)):
expenses_list.append(expenses[i])
# print(expenses_list)
allexpenses = np.sum(data, axis=1) # 总消费水平
CityCluster = [[], [],[],[]] # 将城市按label分成设定的簇
drawlistx = []
drawlisty = []
for i in range(len(cityName)): # 将每个簇的城市输出
CityCluster[labels[i]].append(cityName[i])
# print(CityCluster)
for i in range(len(CityCluster)): # 将每个簇的平均花费输出
print("Expenses:%.2f" % expenses_list[i])
print(CityCluster[i])
for j in range(len(CityCluster[i])):
# print(len(CityCluster[i]))
cityName_temp=CityCluster[i][j];
# print(cityName_temp)
for z in range(len(cityName)):
if(cityName_temp==cityName[z]):
# print(cityName[z])
drawlistx.append(labels[i])
drawlisty.append(allexpenses[z])
font = {"family": "FangSong", 'size': 12}
matplotlib.rc("font", **font)
plt.figure(figsize=(12, 6))
plt.xlabel('标签分类值')
plt.ylabel('平均消费水平')
# print(drawlistx)
# print(drawlisty)
plt.scatter(labels, allexpenses)
plt.show()
# forexpenses=[]
# print(len(CityCluster[i]))
# for j in range(len(CityCluster[i])):
# forexpenses.append(expenses[i])
# print(forexpenses)
# font = {"family": "FangSong", 'size': 12}
# matplotlib.rc("font", **font)
# plt.figure(figsize=(12, 6))
# plt.plot(forexpenses,CityCluster[i])
# plt.show()
对31个省市的居民家庭消费进行聚类分析,并可视化结果。
首先,代码中的loadData函数用于从文件中加载数据,其中每一行包含一个城市的消费数据。数据加载完毕后,创建了一个KMeans的实例km,指定了聚类中心的个数为4。
接下来,通过km.fit(data)对数据进行聚类,得到每个样本点所属的聚类标签。将聚类标签存储在labels列表中,并打印出所有的标签值。
代码中还计算了每个城市的总消费水平allexpenses,并使用matplotlib库将每个城市和其总消费水平绘制成柱状图。
通过计算聚类中心的平均消费水平expenses,并将其存储在expenses_list列表中。 然后,根据聚类标签将城市按照簇进行分组,存储在CityCluster列表中。
接着,遍历每个簇,打印出平均消费水平和属于该簇的城市列表。
最后,根据聚类标签和每个城市的总消费水平,绘制散点图以展示聚类结果
聚类作为一种无监督学习方法,具有一些缺点和限制,包括:
1. 需要预先指定聚类数量:在使用许多聚类算法时,需要事先指定聚类的数量。然而,在实际应用中,确定最佳的聚类数量是一个挑战,因为它取决于数据的特性和领域知识。选择错误的聚类数量可能导致结果不准确或无意义。
2. 对初始聚类中心敏感:许多聚类算法对初始聚类中心的选择非常敏感。不同的初始值可能导致不同的聚类结果,因此需要进行多次运行以获取稳定的结果。这增加了算法的计算复杂性和时间成本。
3. 受异常值和噪音影响:聚类算法对异常值和噪音数据非常敏感。单个异常值或噪音点可能会对聚类结果产生显著影响,导致错误的簇划分。在处理包含异常值或噪音的数据时,需要采取特殊的处理方法或使用鲁棒性更强的聚类算法。
4. 难以处理高维数据:当数据具有大量特征或高维度时,聚类任务变得更加困难。高维数据中存在所谓的"维度灾难"问题,即数据点之间的距离变得非常稀疏,难以准确度量和比较。因此,在处理高维数据时,需要进行降维或采用特定的高维聚类算法。
5. 对初始假设的依赖性:聚类算法通常基于某种距离度量或相似性度量,因此对数据的分布和聚类结构做出了一定的假设。如果数据的分布不符合这些假设,聚类算法的效果可能会降低。因此,选择适合数据特征和分布的聚类算法是至关重要的。
6. 主观性和解释性:聚类结果通常是主观的,因为没有明确的标签或目标来评估聚类的正确性。不同的人可能会对相同数据集得出不同的聚类结果,这使得聚类的解释性和可重复性受到一定挑战。
以本案例为例进行说明,由于部分城市之间消费水平比较相近,所以label值可能在聚类中心的个数为4时跳到第一档次水平,但在聚类中心的个数为4时跳到第三档次水平,这是由于kmeans内部算法决定的。一般来说K-means算法是一种常用的聚类算法,其步骤如下:
|