python K-means 算法

1.数据文件形数据分析

python K-means 算法

# 提前准备数据

https://download.csdn.net/download/sd1_mc/85049785

这个代码有bug。。。

import numpy as np
from sklearn.datasets import load_iris
import numpy as np
import pandas as pd
import csv
#导入数据
data=pd.read_csv('iris.data')
np_t=np.array(data)
n=len(np_t)
#聚类分类数
k = 3
#第一次随机取3个中心点
cent=[np_t[1],np_t[80],np_t[100]]
cent_s=[]
#储存分类情况
fenlei=[[],[],[]]
#计数其余数据到中心点距离分类到最近中心点范围
def getDistance():
    for i in range(n):
        #存每个点到中心点最小值
        ds=0
        for j in range(3):
            m=0
            for l in range(4):
 # 计算与中心点距离
                m=m+(np_t[i][l]-cent[j][l])*(np_t[i][l]-cent[j][l])     
                
  # 比较与上个中心距离,将节点分到相应范围
            if(j==0):
                ds=m
                np_t[i][4]=j
            if(m<ds):
                ds=m
                #分类
                np_t[i][4]=j
                #将数据加入分类   
        fenlei[np_t[i][4]].append(np_t[i])

#计算分类后的中心点
def cent_t():
    cent_s=0
    for i in range(3):
        x=0
        y=0
        z=0
        v=0
        h=0
        for j in fenlei[i]:
            x=x+j[0]
            y=y+j[1]
            z=z+j[2]
            v=v+j[3]
            h=h+1
        if(h==0):
            continue
        x=x/h
        y=y/h
        z=z/h
        v=v/h
        # if((x-cent[i][0]<0.00000001)and (y-cent[i][1]<0.00000001)and (z-cent[i][2]<0.00000001)and (v-cent[i][3]<0.00000001)):
        #     cent_s=cent_s+1
        if(x==cent[i][0]and y==cent[i][1]and z==cent[i][2] and v==cent[i][3]):
            cent_s=cent_s+1
        #更新中心点
        cent[i]=[x,y,z,v,i]
        print(i)
    return cent_s
#第一次聚类
getDistance()
#比较记录中心点与上次中心点是否相同
cent_s=cent_t()
fenlei=[[],[],[]]
a=1

#循环聚类当中心点不变时聚类结束
while 1:
    getDistance()
    cent_s=cent_t()
    a=a+1
    if(cent_s==3):
        break
    fenlei=[[],[],[]] 
print("迭代次数:",a)
filname = './is1.csv'
#打开csv文件
#最好提前准备文件
csvfile = open(filname, 'w', newline='')
#csv画笔
writer = csv.writer(csvfile)
#写入标题
writer.writerow(["sl", "sw", "pl","pw","分类"])
for i in range(3):
    for j in fenlei[i]:
        #录入数据
            writer.writerow(j)
#关闭文件
csvfile.close()

2.画图形聚类

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
import numpy as np
#支持坐标轴中文
plt.rcParams['font.sans-serif']=['SimHei']
iris = load_iris()
X = iris.data   # 特征向量,并且是按顺序排列的
lable = iris.target  # 标签
#数据集预处理,以花萼面积为横坐标,以花瓣面积做纵坐标
arr = np.array(X)
hua_e = arr[:,0]*arr[:,1]
hua_ban = arr[:,2]*arr[:,3]
############################################
#定义需要的函数
def shuju(k):
    b =set()
    while(len(b)<k):
        b.add(np.random.randint(0,150))
    return(b)
#每个点到中心点距离距离
def  getDistance(point_x,point_y,cent_x,cent_y,k):
    x = point_x
    y = point_y
    x0 = cent_x
    y0 = cent_y
    i = 0
    j = 0
    ds = [[]for i in range(len(x))]

    while i < len(x):
        while j < k:
            M = np.sqrt((x[i]-x0[j])  * (x[i]-x0[j]) + (y[i]-y0[j]) * (y[i]-y0[j]))
            M = round(M,1)
            j = j + 1
            ds[i].append(M)
        j = 0
        i = i + 1
    return(ds)

#计算距离误差
def  EDistance(point_x,point_y,cent_x,cent_y,k):
    x = point_x
    y = point_y
    x0 = cent_x
    y0 = cent_y
    i = 0
    j = 0
    sum = 0
    while i < k:
        while j < len(x):
            M = (x[j]-x0[i])  * (x[j]-x0[i]) + (y[j]-y0[i]) * (y[j]-y0[i])
            M = round(M,1)
            sum += M
            j = j + 1
            #ds[i].append(M)
        j = 0
        i = i + 1
    return(sum)

#计算中心点
def cent(lable):
    temp = lable
    mean_x = []
    mean_y = []
    i = 0
    j = 0
    while i < 3:
        cent_x = 0
        cent_y = 0
        count = 0
        while j < len(x):
            if i == temp[j]:
                count = count + 1
                cent_x = cent_x + x[j]
                cent_y = cent_y + y[j]
            j = j + 1
        cent_x = cent_x / count
        cent_y = cent_y / count
        #更新中心点
        mean_x.append(cent_x)
        mean_y.append(cent_y)
        j = 0
        i = i + 1
    return[mean_x,mean_y]

#按照k值聚类
def julei(ds,x):
    x = x
    x = len(x)
    i = 0
    temp = []
    while i < x:
        temp.append(ds[i].index(min(ds[i])))
        i = i + 1
    return(temp)
##############################################
#主程序部分
#这里聚3类,k取3
k = 3

b = shuju(k)
ceshi_hua_e = [hua_e[i] for i in range(len(hua_e)) if (i in b)]
ceshi_hua_ban = [hua_ban[i] for i in range(len(hua_ban)) if (i in b)]
ceshi_lable = [lable[i] for i in range(len(lable)) if (i in b)]
x = hua_e
y = hua_ban
x0 = ceshi_hua_e
y0 = ceshi_hua_ban
#第一次根据随机种子聚类
n = 0
ds = getDistance(x,y,x0,y0,k)
temp = julei(ds,x)
temp1 = EDistance(x,y,x0,y0,k)
n = n + 1
center = cent(temp)
x0 = center[0]
y0 = center[1]
ds = getDistance(x,y,x0,y0,k)
temp = julei(ds,x)
temp2 = EDistance(x,y,x0,y0,k)
n = n + 1
#比较两次平方误差 判断是否相等,不相等继续迭代
while np.abs(temp2 - temp1) != 0:
    temp1 = temp2
    center = cent(temp)
    x0 = center[0]
    y0 = center[1]
    ds = getDistance(x,y,x0,y0,k)
    temp = julei(ds,x)
    temp2 = EDistance(x,y,x0,y0,k)
    n = n + 1
    print(n,temp2)
#结果可视化
print("迭代次数: ", n) # 统计出迭代次数
print('质心位置:',x0,y0)
plt.scatter(x0,y0,color='r',s=50,marker='s')
plt.scatter(x,y,c=temp,s=25,marker='o')
plt.xlabel('花萼面积')
plt.ylabel('花瓣面积')
plt.title("聚3类")
plt.show()
 

python K-means 算法

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2022年3月30日 下午2:36
下一篇 2022年3月30日 下午2:48

相关推荐