当前位置:   article > 正文

西瓜书第九章习题及答案_西瓜书第九章课后题答案

西瓜书第九章课后题答案

9.4

在这里插入图片描述

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
dataset=pd.read_csv('F:\\python\\dataset\\watermelon_4.csv', delimiter=",")
data=dataset.values
data
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

data:
在这里插入图片描述

Kmeans实现

import random
#距离
def distance(x1,x2):
    return sum((x1-x2)**2)
#Kmeans实现

def Kmeans(D,K,maxIter):#return K points and the belongings of every points
    m,n=np.shape(D)
    if K>=m:return D
    initSet=set()
    curK = K  #聚类簇数
    while(curK>0): #随机选择K个样本作为均值向量
        randomInt = random.randint(0,m-1) #随机一个[0,29]的整数
        if randomInt not in initSet:
            curK-=1
            initSet.add(randomInt)  #k个
    U=D[list(initSet),:]
    print('随机选择的{}个样本作为均值向量为:\n{}\n'.format(K,U))
    C=np.zeros(m)
    curIter = maxIter
    while curIter>0:  #迭代
        curIter -= 1
        """
        4: forj = 1, 2, . . . ,m do 
        5: 计算样本 xj 与各均值向量 μi (1<=i<=k) 的距离: dji = ||xj-ui||2;
        6: 根据距离最近的均值向量确定xj的簇标记:λj = argmi∈{1,2..., k} dji ; 
        7: 将样本xj划入相应的簇:Cλj =Cλj ∪{Xj};
        8: end for
        """
        for i in range(m):  #4
            p=0
            minDistance = distance(D[i],U[0])
            for j in range(1,K):  #5
                if distance(D[i],U[j]) < minDistance:  #6
                    minDistance = distance(D[i],U[j])
                    p=j
            C[i] = p  #  7
        newU = np.zeros((K,n))
        cnt = np.zeros(K)
        """
        9: for i = 1, 2,… ,k do 
        10:     计算新均值向量:μi'= 1/|Ci|∑x∈Ci X;
        11:     if ui' != μi then
        12:         将当前均值向量 μi更新为 μi';
        13:     else 
        14:         保持当前均值向量不变
        15:     end if
        16: end for
        17: until 当前均值向量均未更新
        """
        for i in range(m):
            newU[int(C[i])]+=D[i]
            cnt[int(C[i])]+=1
#         print('newU:{}'.format(newU))
#         print('cnt:{}'.format(cnt))
        changed=0  #标志符
        for i in range(K):
            newU[i]/=cnt[i]  #10
            for j in range(n): #11-12
                if U[i,j]!=newU[i,j]:
                    U[i,j]=newU[i,j]
                    changed=1
        if changed==0:
            return U,C,maxIter-curIter
    return U,C,maxIter-curIter

U,C,iter=Kmeans(data,2,100)
print('最终的类中心向量:\n{}\n'.format(U))
print('样本最终的分类:\n{}\n'.format(C))
print('完成此任务的迭代次数:{}'.format(iter))
  • 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
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

运行结果:

在这里插入图片描述

可视化展示:

f1 = plt.figure(1)
plt.title('watermelon_4')
plt.xlabel('density')
plt.ylabel('ratio')
plt.scatter(data[:,0], data[:,1], marker='o', color='g', s=50)
plt.scatter(U[:,0], U[:,1], marker='o', color='r', s=100)
# plt.xlim(0,1)
# plt.ylim(0,1)
m,n=np.shape(data)
for i in range(m):
    plt.plot([data[i,0],U[int(C[i]),0]],[data[i,1],U[int(C[i]),1]],"c--",linewidth=0.3)
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

K=3时的第一次运行结果:

在这里插入图片描述

K=3时的第二次运行结果:

在这里插入图片描述

K=3时的第三次运行结果:

在这里插入图片描述

结果分析:

k-means算法选的初始点离得越远越容易收敛,聚类效果也越好。
因此k-means算法的好坏与初始样本的选取有很大关系。

代码参考链接

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/748542
推荐阅读
相关标签
  

闽ICP备14008679号