0043-機械学習-Kmeansクラスタリングを使用して外れ値の検出を実現

個人のWeChatパブリックアカウント

ここに画像の説明を挿入

kmeans原理の概要

kmeansアルゴリズムの考え方は非常に単純です。収束するまで、各サンプルポイントとクラスターの中心点の間の距離を継続的に計算します。具体的な手順は次のとおりです
。1。データからK個のサンプルポイントを元のサンプルとしてランダムに選択します。クラスター中心;
2。残りのサンプルとクラスター中心の間の距離を計算し、各サンプルをKクラスター中心に最も近いカテゴリとしてマークします;
3.各クラスターのサンプルポイントの平均値を再計算し、平均値を使用します新しいKクラスターセンターとして。
4.クラスター中心の変化が安定し、最終的なKクラスターが形成されるまで、2と3を繰り返します。
おそらく、上記の4つのステップでは、読者がKmeansの実行プロセスを理解するには不十分であり、次の図と組み合わせることで、その背後にある考え方をさらに理解することができます。
ここに画像の説明を挿入
上の図に示すように、Kmeansクラスタリングプロセスは9つのサブグラフで説明されています。図1は、元のサンプルから2つのデータポイントを最初のクラスター中心としてランダムに選択します。つまり、サブグラフ内の2つの5点星です。距離を計算します。残りのサンプルポイントと2つの五芒星の間(距離測定はユークリッド距離、マンハッタン距離など)、次に各サンプルポイントを五芒星に最も近いクラスター、つまりサブに分割します。 -画像は点線で区切られています2つの部分;図3、2つのクラスターのサンプルポイントの平均値を計算し、新しいクラスターの中心、つまりサブグラフの5つの尖った星を取得します。新しいクラスター中心は、各サンプルと五芒星の間の距離を計算し続けます。図5の分割結果を取得し、図6の新しいクラスター中心は、各サンプルと5つの星の間の距離を計算し続けます。先の尖った星、図5の分割結果、図6のクラスター内のサンプルの新しい平均を取得します。以下同様に、最終結果は次のようになります。理想的なクラスタリング効果を図9に示します。五芒星途中で、クラスターの最終的な中心点になります。

K値の決定方法

実際のアプリケーションでは、多くのデータを視覚化することも、クラスターの数を直感的に判断することもできません。しかし、これは最良のK値を決定する方法がないという意味ではありません。主に「変曲点法」、「輪郭係数法」、「間隔統計法」があります。簡単な例を見て、SSEと輪郭係数法に基づいた最良のK値を見てみましょう。

import pandas as pd
import numpy as np
#创造数据
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt

x,y=make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)

fig,ax1=plt.subplots(1)
ax1.scatter(x[:,0],x[:,1],
            marker='o',
            s=8)
plt.show()

color=['red','pink','orange','gray']
fig,ax1=plt.subplots(1)
for i in range(4):
    ax1.scatter(x[y==i,0],x[y==i,1],
                marker='o',
                s=8,
                c=color[i])
plt.show()


#对数据进行了解

from sklearn.cluster import KMeans
#使用SSE进行模型评估,
import matplotlib.pyplot as plt
sse=[]
for i in range(1,10):
    cluster=KMeans(n_clusters=i,random_state=0).fit(x)
    inertia=cluster.inertia_
    sse.append(inertia)
plt.figure(figsize=(8,6))
plt.plot(range(1,10),sse,color='red',linewidth=2.0,linestyle='--',marker='o',label='sse')
plt.grid(True)
plt.show()


#使用轮廓系数sc
from sklearn.metrics import silhouette_samples, silhouette_score
import matplotlib.pyplot as plt
sc=[]
for i in range(2,10):#为什么要从2开始,1的话会出错
    cluster_=KMeans(n_clusters=i,random_state=0).fit(x)
    y_pre=cluster_.labels_
    sc_=silhouette_score(x,y_pre)
    sc.append(sc_)
plt.figure(figsize=(8,6))
plt.plot(range(1,10),sse,color='red',linewidth=2.0,linestyle='--',marker='o',label='sse')
plt.show()

ケース実際の戦闘

# 导入第三方包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.cluster import KMeans
from sklearn.preprocessing import scale

# 随机生成两组二元正态分布随机数
np.random.seed(1234)
mean1 = [0.5, 0.5]
cov1 = [[0.3, 0], [0, 0.1]]
x1, y1 = np.random.multivariate_normal(mean1, cov1, 5000).T

mean2 = [0, 8]
cov2 = [[0.8, 0], [0, 2]]
x2, y2 = np.random.multivariate_normal(mean2, cov2, 5000).T

# 绘制两组数据的散点图
plt.rcParams['axes.unicode_minus'] = False


plt.scatter(x1, y1)
plt.scatter(x2, y2)
# 显示图形
plt.show()

# 将两组数据集汇总到数据框中
X = pd.DataFrame(np.concatenate([np.array([x1, y1]), np.array([x2, y2])], axis=1).T)
X.rename(columns={0: 'x1', 1: 'x2'}, inplace=True)
# 自定义函数的调用
# k_SSE(X, 10)


def kmeans_outliers(data, clusters, is_scale=True):
    # 指定聚类个数,准备进行数据聚类
    kmeans = KMeans(n_clusters=clusters)
    # 用于存储聚类相关的结果
    cluster_res = []

    # 判断是否需要对数据做标准化处理
    if is_scale:
        std_data = scale(data)  # 标准化
        kmeans.fit(std_data)  # 聚类拟合
        # 返回簇标签
        labels = kmeans.labels_
        # 返回簇中心
        centers = kmeans.cluster_centers_

        for label in set(labels):
            # 计算簇内样本点与簇中心的距离
            diff = std_data[np.array(labels) == label,] - \
                   - np.array(centers[label])
            dist = np.sum(np.square(diff), axis=1)
            # 计算判断异常的阈值
            UL = dist.mean() + 3 * dist.std()
            # 识别异常值,1表示异常,0表示正常
            OutLine = np.where(dist > UL, 1, 0)
            raw_data = data.loc[np.array(labels) == label,]
            new_data = pd.DataFrame({'Label': label, 'Dist': dist, 'OutLier': OutLine})
            # 重新修正两个数据框的行编号
            raw_data.index = new_data.index = range(raw_data.shape[0])
            # 数据的列合并
            cluster_res.append(pd.concat([raw_data, new_data], axis=1))
    else:
        kmeans.fit(data)  # 聚类拟合
        # 返回簇标签
        labels = kmeans.labels_
        # 返回簇中心
        centers = kmeans.cluster_centers_

        for label in set(labels):
            # 计算簇内样本点与簇中心的距离
            diff = np.array(data.loc[np.array(labels) == label,]) - \
                   - np.array(centers[label])

            dist = np.sum(np.square(diff), axis=1)
            UL = dist.mean() + 3 * dist.std()
            OutLine = np.where(dist > UL, 1, 0)
            raw_data = data.loc[np.array(labels) == label,]
            new_data = pd.DataFrame({'Label': label, 'Dist': dist, 'OutLier': OutLine})
            raw_data.index = new_data.index = range(raw_data.shape[0])
            cluster_res.append(pd.concat([raw_data, new_data], axis=1))
    # 返回数据的行合并结果
    return pd.concat(cluster_res)


# 调用函数,返回异常检测的结果
res = kmeans_outliers(X, 2, False)
# res
# 绘图
sns.lmplot(x="x1", y="x2", hue='OutLier', data=res,
           fit_reg=False, legend=False)
plt.legend(loc='best')
plt.show()

おすすめ

転載: blog.csdn.net/zhonglongshen/article/details/113282875