Python 財務データ マイニング 第 11 章 復習質問 1 (クラスタリング) データ セット data_multivar.txt が指定されており、これには 200 点の座標が含まれています。その散布図は平面座標系で描画し、K 平均法アルゴリズムでクラスタリングしてモデルをトレーニングできます。 4つのカテゴリーに分かれています。

1. トピック

データセット data_multivar.txt があるとすると、その中には 200 個の点座標があり、図 11-12 に示すように、その散布図は平面座標系で描画できます。

data_multivar.txt

図 11-12 データセット data_multivar.txt の散布図

モデルのトレーニングにはK 平均法クラスタリング アルゴリズムが使用されデータ セットの 200 点が 4 つのカテゴリに分割されます注: 実行する前に、まず指定されたデータセット data_multivar.txt を対応するフォルダーにコピーします。読者は、プログラム内で k 値を 2、3、5 などに設定し、コードを実行して比較できます。

2. コード

11.2のコードに基づいてこれを変更するだけですか?私も知りません、ねえ

# K取值2
print("step2.1:聚类")
k=2
centroids,clusterAssment=kmeans(dataSetKNN1,k)
print('数据类型:',dataSetKNN1.dtype)
print("step3.1:结果输出:见'图2.png'")
showCluster(dataSetKNN1,k,centroids,clusterAssment)

# K取值3
print("step2.2:聚类")
k=3
centroids,clusterAssment=kmeans(dataSetKNN1,k)
print('数据类型:',dataSetKNN1.dtype)
print("step3.2:结果输出:见'图3.pag'")
showCluster(dataSetKNN1,k,centroids,clusterAssment)

# K取值5
print("step2.3:聚类")
k=5
centroids,clusterAssment=kmeans(dataSetKNN1,k)
print('数据类型:',dataSetKNN1.dtype)
print("step3.3:结果输出:见'图5.png'")
showCluster(dataSetKNN1,k,centroids,clusterAssment)

 3. 結果グラフ

1、

2、

 

 3、

4、 

4、 

4. 標準的な回答

(1)機能

import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# 计算欧式距离,即两点间的直线距离 
#参数:vector1-List列表,n维属性坐标值构成的向量
#      vector2-List列表,n维属性坐标值构成的向量
#返回值:浮点数,欧式距离

def euclDistance(vector1, vector2):  
    return np.sqrt(np.sum(np.power(vector2 - vector1, 2)))  

# 创建一个数据集,包含2个类别共8个样本
def createDataSet():
# 生成一个矩阵,每行表示一个样本
    group = np.array([[1.0,0.9], [1.0,1.0], [0.8,0.9], [0.6,0.65],
    [0.1, 0.2], [0.3,0.4], [0.2,0.3], [0.0, 0.1]])
# 监督学习,手工设置8个样本所属的类别标签
    labels = ['A', 'A','A', 'A', 'B', 'B','B', 'B']
    return group, labels

# KNN分类算法函数实现
#参数:newInput-List列表,待分类的数据点
#      dataSet-List列表,已分类点坐标
#      lables-List列表,分类标签
#      k-整数,近邻数量
#返回值:maxIndex-字符,分类结果
def kNNClassify(newInput, dataSet, labels, k):
    numSamples = dataSet.shape[0]   # shape[0]表示行数
    distance = []
#计算newInput与dataSet中个点的距离,放入distance列表内
    for vec in dataSet:
        distance.append(euclDistance(newInput,vec))        
#对距离排序
    sortedDistIndices = np.argsort(distance)
    classCount = {}
#选择k个最近邻
    for i in range(k):
        voteLabel = labels[sortedDistIndices[i]]
        classCount[voteLabel] = classCount.get(voteLabel, 0) + 1
    maxCount = 0
    for key, value in classCount.items():
        if value > maxCount:
            maxCount = value
            maxIndex = key
    return maxIndex


#随机生成K个候选聚类中心点
#参数:dataSet-List列表,已分类点坐标
#      k-整数,近邻数量
#返回值:centroids-2维列表,k个随机候选中心点坐标
def initCentroids(dataSet, k): 
    numSamples, dim = dataSet.shape
    centroids = np.zeros((k, dim))
    # 循环遍历每一列,在每一列(也就是每一维)的最小值和最大值之间产生K个随机数,作为候选中心点这一维的坐标
    for j in range(dim):
        # 计算每一列的最小值
        minJ = min(dataSet[:, j])
        # 计算每一列的范围值
        rangeJ = float(max(dataSet[:, j]) - minJ)
        # 计算每一列的质心,并将值赋给centroids
        centroids[:, j] = minJ + rangeJ * np.random.rand(k)
    return centroids

#在已有数据点中随机挑选K个作为聚类中心点
#这实际上是K中心点聚类算法的初始化方法
#参数:dataSet-List列表,已分类点坐标
#      k-整数,近邻数量
#返回值:centroids-2维列表,k个随机候选中心点坐标
def initCentroids1(dataSet, k):  
    numSamples, dim = dataSet.shape  
    centroids = np.zeros((k, dim))  
    for i in range(k):  
        index = int(np.random.uniform(0, numSamples))  
        centroids[i, :] = dataSet[index, :]  
    return centroids

# K均值聚类
#参数:dataSet-List列表,待聚类样本集
#      k-整数,近邻数量
#返回值:centroids-2维列表,k个随机中心点坐标
#        clusterAssment -列表,各个样本点的聚类结果
def kmeans(dataSet, k):  
    numSamples = dataSet.shape[0]
#第一列数据存放归属的点
#第二列存放样本与候选聚类中心点之间的误差  
    clusterAssment = np.mat(np.zeros((numSamples, 2)))  
    clusterChanged = True    
    centroids = initCentroids(dataSet, k)  
  
    while clusterChanged:  
        clusterChanged = False  
        for i in range(numSamples):  
            minDist  = 100000.0  
            minIndex = 0  
#依次找出最近候选聚类中心点
            for j in range(k):  
                distance = euclDistance(centroids[j, :], dataSet[i, :])  
                if distance < minDist:  
                    minDist  = distance  
                    minIndex = j  
#更新归属结果
            if clusterAssment[i, 0] != minIndex:  
                clusterChanged = True  
                clusterAssment[i, :] = minIndex, minDist**2  
#更新候选聚类中心点坐标
        for j in range(k):  
            pointsInCluster = dataSet[np.nonzero(clusterAssment[:, 0].A == j)[0]]  
            centroids[j, :] = np.mean(pointsInCluster, axis = 0)  
  
    print('KMN聚类完成!')  
    return centroids, clusterAssment  

# 2维平面显示聚类结果
#参数:dataSet-List列表,样本集
#      k-整数,近邻数量
#      centroids-List列表,聚类中心点坐标
#      clusterAssment-List列表,聚类结果
#返回值:无
def showCluster(dataSet, k, centroids, clusterAssment):  
    fig_2d_clustered=plt.figure()
    ax2d_clustered=fig_2d_clustered.add_subplot(111) 
    
    numSamples, dim = dataSet.shape  
    if dim != 2:  
        print("只能绘制2维图形")  
        return 1  
#创建数据点标记格式控制列表,实现数据点区别输出
    mark = ['.r', '+b', '*g', '1k', '^r', 'vr', 'sr', 'dr', '<r', 'pr']  
    if k > len(mark):  
        print("K值过大!")  
        return 1  
#绘制所有样本点
    for i in range(numSamples):  
        markIndex = int(clusterAssment[i, 0])  
        ax2d_clustered.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])  

#绘制聚类中心点  
    for i in range(k):
        ax2d_clustered.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 20)  
 
    fig_2d_clustered.savefig('clusterRes.png', dpi=300, bbox_inches='tight')
    fig_2d_clustered.show()


#计算代价TC
#参数:dataSet-List列表,样本集
#      k-整数,近邻数量
#      medoids_idx-List列表,候选中心点
#      clusterAssment-List列表,聚类结果
#返回值:total_cost-浮点数,TC代价
#        medoids-List2维列表,本次归属到各中心点的样本点
def totalcost(dataSet, medoids_idx) :
    distances_cache = {}
    size = len(dataSet)
    total_cost = 0.0
    medoids = {}
    for idx in medoids_idx :
        medoids[idx] = []
    for i in range(size) :
        choice = None
        min_cost = 100000
#计算各样本数据点到medoids_idx的距离,将其归属到距离最近的那个中心点
        for m in medoids :
            tmp = distances_cache.get((m,i),None)
            if tmp == None :
                tmp = euclDistance(dataSet[m],dataSet[i])
                distances_cache[(m,i)] = tmp
            if tmp < min_cost :
                choice = m
                min_cost = tmp
        medoids[choice].append(i)
        total_cost += min_cost
    return total_cost, medoids

# K中心点聚类
#参数:dataSet-List列表,待聚类样本集
#      k-整数,近邻数量
#返回值:centroids-2维列表,k个中心点坐标
#        clusterAssment -列表,各个样本点的聚类结果

import random

def kmedoids(dataSet, k) :
    size ,dim= dataSet.shape
    centroids = np.zeros((k,dim))
    clusterAssment = np.mat(np.zeros((size, 2)))    
    medoids_idx = random.sample([i for i in range(size)], k)
    pre_cost, medoids = totalcost(dataSet,medoids_idx)
    current_cost = 100000    
    best_choice = []
    best_res = {}
    iter_count = 0
#反复计算TC,进行聚类
    while 1 :
        for m in medoids :
            for item in medoids[m] :
                if item != m :
                    idx = medoids_idx.index(m)
                    swap_temp = medoids_idx[idx]
                    medoids_idx[idx] = item
                    tmp,medoids_ = totalcost(dataSet,medoids_idx)
                    if tmp < current_cost :
                        best_choice = list(medoids_idx)
                        best_res = dict(medoids_)
                        current_cost = tmp
                    medoids_idx[idx] = swap_temp
        iter_count += 1
        if best_choice == medoids_idx : break
        if current_cost <= pre_cost :
            pre_cost = current_cost
            medoids = best_res
            medoids_idx = best_choice
    
    centNum=0;
    for index in best_choice:
        centroids[centNum,:]=dataSet[index,:]
        centNum += 1
    
    classNumber = 0
    for key in best_res:
        for index in best_res[key]:
            clusterAssment[index,0]=classNumber
        classNumber += 1
      
    print('KMed聚类完成!')  
    return centroids, clusterAssment

(2) 使用

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

origData = pd.read_csv("data_multivar.txt",header=None)

dataSetKMNSize = len(origData)
dataSetKMN = np.mat(origData)
print("step1: 原始数据分布:") 
for i in range(dataSetKMNSize):
    plt.plot(dataSetKMN[i, 0], dataSetKMN[i, 1],'b*') 

print("step 2: 聚类")    
k = 4
centroids, clusterAssment = kmeans(dataSetKMN, k) 

print("step 3: 结果输出:")  
showCluster(dataSetKMN, k, centroids, clusterAssment)

おすすめ

転載: blog.csdn.net/xllzuibangla/article/details/124933865