Python机器学习实验课K-means聚类代码和注释
数据集为鸢尾花数据集,特征有4个,类别有3类,分为训练集和测试集,进行K-means聚类,以学习K-means聚类算法。
import operator
import csv
import numpy as np
import random
names = ['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'] #类别
train_lables = []
test_lables = []
##数据集读取和划分
def loaddata(filename1, filename2, train_set=[], test_set=[]):
with open(filename1, 'r') as f:
lines = csv.reader(f)
train_set = list(lines)#训练数据列表
for i in range(len(train_set)):
del(train_set[i][0])#删除每行的第0列,也就是标号
#为训练数据添加标签
if train_set[i][-1] == names[0]:
train_lables.append(0)
elif train_set[i][-1] == names[1]:
train_lables.append(1)
else:
train_lables.append(2)
del(train_set[i][-1])#删除原训练列表中的标签,因为已经有了标签列表
for j in range(4): #因为有4个特征,把每一个特征都变成float类型
train_set[i][j] = float(train_set[i][j])
train_set[i] = np.array(train_set[i]) #把训练集的特征列表变成numpy数组
with open(filename2, 'r') as f:#测试集同上
lines = csv.reader(f)
test_set = list(lines)
for i in range(len(test_set)):
del(test_set[i][0])
if test_set[i][-1] == names[0]:
test_lables.append(0)
elif test_set[i][-1] == names[1]:
test_lables.append(1)
else:
test_lables.append(2)
del(test_set[i][-1])
for j in range(4):
test_set[i][j] = float(test_set[i][j])
test_set[i] = np.array(test_set[i])
return train_set, test_set
#计算聚类中心坐标和相应的数据,参数:现在的聚类中心数据,要聚成的类别数
def get_core(core, k):
newcore = [] #新的聚类中心坐标
newcoredata = [] #聚类中心对应的数据
for i in range(k): #初始化,每个聚类中心都还没对应数据
newcoredata.append([])
for i in range(len(train_set)):
distance = []
for j in range(k):
distance.append(np.linalg.norm(train_set[i] - core[j], ord=None, axis=None, keepdims=False))
#np.linalg.norm:求范数,参数1:矩阵,4;参数2:范数类型,ord=None是默认情况,求整个矩阵元素平方和再开根号;
#参数3:axis=None表示矩阵范数;参数4:keepdims=False,表示不保持矩阵的二维特性
#这里就是计算一个训练样本到每个聚类中心的距离
newcoredata[distance.index(min(distance))].append(i)#选择最小的距离的索引,也就定位了是哪个聚类中心,将此样本的索引加入到该聚类中心对应的样本索引列表中
for i in range(k):
temp = np.zeros(4)
for j in newcoredata[i]: #最终得到的temp是每个类的总距离
temp = train_set[j]
newcore.append(temp / len(newcoredata[i]))#每个,类的平均距离
return newcore, newcoredata
#kmeans计算
def kmeans(k):
core = [] #聚类中心的索引号
while len(core) < 3: #当聚类中心还不到3个时,
x = random.randint(0, len(train_set)) #随机选取训练集中的一个样本,
if x not in core:#如果选的这个样本与之前选的不重复,就把它添加到聚类中心列表
core.append(x)
now_core = [train_set[i] for i in core] #记录聚类中心本身的内容(坐标)
print(now_core)#打印结果:[array([5.1, 3.5, 1.4, 0.2]), array([7.7, 3. , 6.1, 2.3]), array([5.3, 3.7, 1.5, 0.2])]
for i in range(10):#kmeans聚类迭代10次
new_core, newcoredata = get_core(now_core, k) #计算新的聚类中心的坐标和相应的数据
print(new_core, newcoredata)
#打印新的聚类中心的坐标和对应的数据(样本索引号)
#[array([4.85384615, 3.21153846, 1.49615385, 0.25 ]), array([6.43269231, 2.99230769, 5.15576923, 1.80192308]), array([5.44 , 3.43 , 2.345, 0.62 ])]
#[[0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 14, 19, 20, 21, 22, 23, 24, 27, 29, 30, 31, 32, 33, 34, 37, 60], [38, 39, 41, 42, 43, 44, 46, 48, 49, 50, 51, 52, 53, 54, 56, 57, 61, 62, 63, 64, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97], [8, 11, 12, 13, 15, 16, 17, 18, 25, 26, 28, 35, 36, 40, 45, 47, 55, 58, 59, 65]]
dis = 0
for i in range(k):
dis = np.linalg.norm(new_core[i] - now_core[i], ord=None, axis=None, keepdims=False) #计算新的聚类中心和现在的聚类中心的距离
if dis >= 0.1:#如果总距离>=0.1,更新聚类中心,继续迭代;否则迭代结束
now_core = new_core
else:
break
return now_core, newcoredata #返回聚类中心的坐标和每个聚类中心对应数据的索引
#判断聚类中的一个类是哪个具体的类别
def get_response(neighbors):
class_vote = {}#空的字典
for i in range(len(neighbors)):
response = neighbors[i]
#统计某个类别的样本数量
if response not in class_vote:
class_vote[response] = 1#计数
else:
class_vote[response] = 1#计数
softed_vote = sorted(class_vote.items(), key=operator.itemgetter(1), reverse=True)#降序排序
return softed_vote[0][0] #得出了对应样本数量最多的类别,所以这一簇就是这个类
#预测
def predection(test_data, core_label):
result = []
for i in range(len(test_data)):
distance = []
for j in range(k):
distance.append(np.linalg.norm(test_data[i] - core[j], ord=None, axis=None, keepdims=False)) #测试样本和某个聚类中心的距离
result.append(core_label[distance.index(min(distance))]) #距离哪个聚类中心距离最小则属于哪个类别
return result#预测结果
if __name__ == "__main__":
k = 3
#数据集读取和划分
train_set, test_set = loaddata('data/data42984/iris_train.csv', 'data/data42984/iris_test.csv') #得到训练集和测试集,均为numpy.array
#kmeans计算
core, data = kmeans(k)#得到聚类中心的坐标和每个聚类中心对应数据的索引
core_label = []
for i in range(k):
temp = [train_lables[j] for j in data[i]] #得到的temp为一个聚类中心对应数据的标签
core_label.append(get_response(temp))#get_response(temp)判断聚类中的一个类是哪个具体的类别,依次把具体的类别加入到core_label中。
print(core_label) #打印:[0, 2, 1]
#预测
result = predection(test_set, core_label)
print(test_lables) #打印:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
print(result) #打印:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 2, 2]
acc_num = 0 #所有正确预测的数量
for i in range(len(test_lables)):
if result[i] == test_lables[i]:
acc_num = 1
print(acc_num/len(test_lables))#打印:0.8846153846153846
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgcghik
系列文章
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13