Kmeans

1. 语法

class sklearn.cluster.KMeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=None, algorithm='auto')

参数说明:
- n_clusters=8 : K的值,我们想要将数据聚类成几类

- init='k-means++': 帮助你选择初始中心点的算法.

- n_init = 10: 有可能一次聚类效果不好(因为随机选择初始中心点,所以效果不稳定),重复用不同的随机数种子,聚类10次,从中找出效果最好的.

- max_iter=300 : 最大迭代次数.

- tol=0.0001 : 阈值,算法停止的阈值. 在迭代的过程当中, 组内距离平方和评估聚类效果,如果这个值在某次迭代过程中,下载不到这个tol的大小,那么就提前停止算法.

- random_state=None: 随机数种子

- verbose=0 : 模型的算法日志,数字越大代表日志越详细

- n_jobs=None: 使用cpu处理器个数,-1代表适用所有核心.
属性说明:
- cluster_centers_: 聚类最终的簇中心点.

- labels_: 每个样本被分到了哪一个簇中.

- inertia_: 评估指标,组内距离平方和.所有点到聚类中心点的距离平方和

- n_iter_ : 算法迭代次数

2. 算法实现

基本流程:导包 --> 导数据 --> 实例化 --> fit --> 画轮廓系数学习曲线 --> 找到最好K重新建模 --> 得到结果并加入源数据 --> 分析

2.1 生成聚类模拟数据

sklearn.datasets.make_blobs

参数说明:
- n_samples: 生成的数据样本个数

- n_features: 有多少个特征

- centers: 生成数据的中心点

- cluster_std: 聚类分布的标准差

- random_state : 随机数种子
函数返回值returns:
- X : 就是输入数据

- y : 标签
import numpy as np
import pandas as pd
import matplotlib.pylab as plt
from sklearn.datasets import make_blobs

# 生成四堆数据,所以四个中心点,四个标准差
X,y = make_blobs (n_samples = 1000,
                  n_features = 2,
                  centers = [ [-1,-1],[0,0],[1,1],[2,2] ],
                  cluster_std = [0.4,0.2,0.2,0.2],
                  random_state = 666)

plt.scatter(X[:,0] ,X[:,1], c=y);# 使用y标签进行颜色的映射
模拟数据

2.2 sklearn 实现Kmeans

from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters = 2,random_state=666)  #k = 2
kmeans.fit(X,y)

#查看属性
print("中心点:\n{}".format(kmeans.cluster_centers_))
print("组内平方和:\n{}".format(kmeans.inertia_))
print("迭代次数:\n{}".format(kmeans.n_iter_))

# 结果绘图
plt.scatter(X[:,0],X[:,1],c=kmeans.labels_)
plt.scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],c = 'red',s = 100)

单K
### 观察K变化之后,聚类的结果有什么不同,分别绘制出k取3,4,5,6的图形
plt.figure()

for k in range(3,7):
    kmeans = KMeans(n_clusters = k,random_state=666)
    kmeans.fit(X,y)
    
    #绘图,子图模式需先建画板
    plt.subplot(2,2,k-2)
    plt.scatter(X[:,0],X[:,1],c=kmeans.labels_,label = "k = "+str(k))
    plt.scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],c = 'red',s = 100)
    plt.legend()
多K

2.3 通过学习曲线寻找最优K值

# 族值增加时,组内距离平方和必下降

scores = []

for k in range(2,10):
    kmeans = KMeans(n_clusters = k,random_state=666)
    kmeans.fit(X,y)
    
    #将不同K的组内距离平方和保存
    scores.append(kmeans.inertia_)
    
plt.plot(range(2,10),scores) # 4为最优参数,计算量和效果的妥协
# 再用K=4去重新建模fit就行了
学习曲线

3. 轮廓系数:评价聚类效果

SCi = (Bi - Ai)/max(Bi,AI)

- Ai:衡量一个点到 本 簇内其他点所有距离的 均值
 
- Bi:衡量一个点到 离他最近的其他 簇内所有点距离的 均值
- 一般来说,这个值如果超过0.1 ,聚类效果已经算是非常好了。

三种情况:

- 1.聚类效果很好,组内距离近,组外远,即:Bi>>Ai 则SCi = Bi/Bi 约等于1
- 2.聚类效果非常不好,组内距离远,组外近,还不如不聚类,即:Ai>>Bi 则SCi = -Ai/Ai 约等于 -1
- 3.SCi = 0 ,Ai = Bi 聚类无效果

3.1 代码实现流程

from sklearn.metrics import silhouette_score
from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters = 3,random_state=666)  #k = 3
kmeans.fit(X,y)

# 轮廓系数:
silhouette_score(X,kmeans.labels_)

3.2 用轮廓系数进行学习曲线调参

# 初级版
scores = []

for k in range(2,10):
    kmeans = KMeans(n_clusters = k,random_state=666)
    kmeans.fit(X,y)
    
    #将不同K的组内距离平方和保存
    scores.append(silhouette_score(X,kmeans.labels_))
    
plt.plot(range(2,10),scores) # 4为最优参数,计算量和效果的妥协
初级版
# 高级版
# 解决坐标轴刻度负号乱码
plt.rcParams['axes.unicode_minus'] = False

plt.rcParams["font.family"] = 'Arial Unicode MS'

# 生成画布,设置大小
plt.figure(figsize = (10,12))

for k in range(2,8):
    kmeans = KMeans(n_clusters = k,random_state=666)
    kmeans.fit(X,y)
    
    #将不同K的组内距离平方和保存
    scores = silhouette_score(X,kmeans.labels_)
    # 6次循环,6张子图,参数(i,j,k) i行j列的图,K为第K个
    plt.subplot(3,2,k-1)
    plt.scatter(X[:,0],X[:,1],c=kmeans.labels_)
    plt.scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],c = 'red',s = 100,label = "k = "+str(k)+"\n"+"轮廓系数 = "+str(round(scores,3)))
    plt.text(0,-2,"轮廓系数 = "+str(round(scores,3))) #参数x,y,文字
    plt.legend(loc="upper left",shadow=True,fancybox=True,fontsize=10 )
高级版

4. 真实数据集流程

基本流程:导包 --> 导数据 --> 实例化 --> fit --> 画轮廓系数学习曲线 --> 找到最好K重新建模 --> 得到结果并加入源数据 --> 分析

4.1 读入数据

mall_customer = pd.read_csv("Mall_Customers.csv")
mall_customer.head()

4.2 格式化并描述数据

# 把特征名称换成中文
d = {'CustomerID':'用户ID',
    'Gender':'性别',
    'Age':'年龄',
    'Annual Income (k$)':'年收入',
    'Spending Score (1-100)':'花销分数'}
mall_customer = mall_customer.rename(columns=d)
数据
# 画图描述数据
import seaborn as sns
# 改变画图风格
plt.style.use('seaborn')
#mac电脑正常显示中文
plt.rcParams['font.family'] = ['Arial Unicode MS']

# 直方图
sns.distplot(mall_customer['年龄'],bins = 20)
sns.distplot(mall_customer['花销分数'] , bins= 20)
sns.distplot(mall_customer['年收入'] , bins= 20)

# 性别的分布
sns.countplot(x = '性别',data = mall_customer)
直方图

性别

4.3 探索数据特征的性关系

# 自动帮你统计所有两两变量之间的关系,参数:数据[多列],reg是话回归线,看线性关系
sns.pairplot(mall_customer[['年龄','年收入','花销分数']],kind = 'reg')

plt.scatter(mall_customer['年收入'],mall_customer['花销分数'])
plt.xlabel('年收入')
plt.ylabel('花销分数')

4.4 用Kmeans聚类

from sklearn.metrics import silhouette_score
from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters = 5,random_state=666)  #k = 3

# 分隔X,mall_customer['年收入']是一维数据,转成二维才能输入
X1 = mall_customer[['年收入','花销分数']]
kmeans.fit(X1)

# 画图
plt.scatter(X1['年收入'],X1['花销分数'],c = kmeans.labels_,cmap='rainbow')
plt.scatter(kmeans.cluster_centers_[:,0], kmeans.cluster_centers_[:,1],
            c = 'black',s = 100)
plt.title('k=3')
K = 3
# 结果
kmeans.cluster_centers_ # 中心点

# 轮廓系数学习曲线
scores = []

for i in range(2,8): # 2-9
    # 实例化
    kmeans = KMeans(n_clusters=i , random_state=666)
    kmeans.fit(X1)
    
    scores.append(silhouette_score(X1 , kmeans.labels_) )

#  将曲线绘制出来
plt.plot(range(2,8) , scores); # 5对应的点最大
轮廓系数学习曲线

4.5 用三个特征聚类

# 非标准化数据情况:
X2 = mall_customer[['年收入','花销分数','年龄']]
scores = []

for i in range(2,10): # 2-9
    # 实例化
    kmeans = KMeans(n_clusters=i , random_state=666)
    kmeans.fit(X2)
    
    # 将轮廓系数和保存下来
    scores.append(silhouette_score(X2 , kmeans.labels_) )
    
plt.plot(range(2,10) , scores); # 6对应的点,我们叫做拐点
非标准化数据情况
# 标准化数据情况
from sklearn.preprocessing import MinMaxScaler

minmax = MinMaxScaler()
minmax.fit(X2)
X2_minmax = minmax.transform(X2)

scores = []
for i in range(2,15): 
    # 实例化
    kmeans = KMeans(n_clusters=i , random_state=666)
    kmeans.fit(X2_minmax)
    
    # 将轮廓系数和保存下来
    scores.append(silhouette_score(X2_minmax , kmeans.labels_) )
    
plt.plot(range(2,15) , scores); # 9最大,但对不标准化不明显,所以用不标准化的
标准化数据情况

4.6 确定聚合的6个簇,并添加到表

# 实例化
kmeans = KMeans(n_clusters=6 , random_state=666)
kmeans.fit(X2)

mall_customer['聚类结果'] = kmeans.labels_ #在此用的没标准化的数据
mall_customer.聚类结果.value_counts()
image.png
mall_customer[mall_customer['聚类结果'] == 3].describe()
image.png

你可能感兴趣的:(Kmeans)