机器学习(7)--K均值算法及python实现(附练习数据资源文件百度云)

吴恩达ML课程课后总结,以供复习、总结、温故知新,也欢迎诸位评论讨论分享,一起探讨一起进步:


上一篇:机器学习(6)--SVM使用sklearn模块python实现(附练习数据资源文件百度云)https://blog.csdn.net/qq_36187544/article/details/88377748

下一篇:机器学习(8)--PCA算法及python中sklearn模块实现https://blog.csdn.net/qq_36187544/article/details/88394909


上数据资源与源代码:

链接:https://pan.baidu.com/s/1YlTDOHqDDNjLZadhZrGsuQ 
提取码:4gyd 

raw.txt是美国人口普查数据原集,train.txt是从中取100行的数据为了实现K均值,07.py是源码


进入正题,现在到了无监督学习,主要就是聚类算法,就是没有对应的y输出,将数据集分类,比如将人群分类等, 比如市场收集了关于衣服身高和体重的数据,想划分大中小号,就可以用k=3的K均值算法

K-Means算法,k均值算法(每次都要被这些算法的思想所惊艳到)。

核心思想是,先随机确定K个聚类中心,然后将聚类附近的点划分到聚类中心所属簇,计算当前簇的平均值,将聚类中心移动到平均值处,再次循环,划分聚类中心所属簇,计算均值,移动聚类中心。。。最终当聚类中心不再移动时,得到合适的分类集。如下左图,随机初始化两个点(两个×,将数据划分到两个×对应的簇里),计算平均值移动两个聚类中心(下中图),重新聚类(如下右图),直到中心不再改变。


详细算法

1.初始化K值,确定几个聚类中心,并随机化,直接用几个样本点作为初始化值

2.重复循环:(1)聚类,计算距离每个点到每个聚类中心的二范数平方即距离,取最小,认为当前点属于该聚类中心。(2)移动聚类中心

注:如果存在某个聚类中心一个点都没有,一般做法是移除该点,若非要K个聚类中心,可重新随机初始化聚类中心计算


优化目标:为了让算法更优,避免陷入局部最优解,提出优化目标,失真代价函数(畸变函数)如下图, J是所有点到该聚类中心二范数平方和的均值。就是从数学的角度再解释了一下点划分到最近的簇,为了让代价函数最小。


如何避开局部最优:初始随机化时直接用几个样本点作为聚类中心,除此之外,多次随机(次数一般在50-1000次)是必不可少的(这只针对K在2-10范围内,若太大,多次随机能稍微改变分类结果,但效果不明显)

如何选择聚类数量?手动选择。
一种思路:绘制横坐标为K聚类数量,纵坐标为J畸变函数的图像,像一个手肘,选择肘部那个点(下左图),肘部法则,如果没有清晰拐点(下右图),随便选一个合适的罗。


另一种思路:通过实际来确定K聚类数量,是需要更精确的划分还是更划算的划分。


数据来源于人口普查,特征数量过多,取两个,方便平面可视化。

取100组数据,绘制如下,由于数据都为整点,所以看起来可能会有些许奇怪,由于重叠显示看起来不多:

最后运行分类结果为,大点为聚类中心:

源码如下:

import numpy as np
import matplotlib.pyplot as plt
import random

# 求二范数方
def get2(x1,x2,y1,y2):
    return pow(x1-y1,2)+pow(x2-y2,2)

# K-means,这里让k=2吧
def k_means(x1,x2):
    c1,c2 = random.randint(0,99),random.randint(0,99)
    len_x = len(x1)
    center1,center2= [x1[c1],x2[c1]],[x1[c2],x2[c2]]    # 聚类中心
    for iii in range(1000):
        center1_cluster, center2_cluster = [], []# 属于不同聚类中心的集合
        for i in range(len_x):
            if get2(center1[0],center1[1],x1[i],x2[i]) > get2(center2[0],center2[1],x1[i],x2[i]):
                center2_cluster.append(i)
            else:center1_cluster.append(i)
        sum1,sum2=0,0
        for i in range(len(center1_cluster)):
            sum1+=x1[center1_cluster[i]]
            sum2+=x2[center1_cluster[i]]
        center1[0]=sum1/len(center1_cluster)
        center1[1]=sum2/len(center1_cluster)
        sum1, sum2 = 0, 0
        for i in range(len(center2_cluster)):
            sum1 += x1[center2_cluster[i]]
            sum2 += x2[center2_cluster[i]]
        center2[0] = sum1 / len(center2_cluster)
        center2[1] = sum2 / len(center2_cluster)
    return [center1_cluster,center2_cluster,center1,center2]    # 转为list传回,center1_cluster里存的是Index,在把中心传回绘制

x1, x2 = [],[]
for sample in open("census1990_train.txt", "r"):
    # 原始数据太多需要占位
    a1,_x1,a2,a3,a4,a5,_x2,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53,a54,a55,a56,a57,a58,a59,a60,a61,a62,a63,a64,a65,a66,a67 = sample.split(",")
    x1.append(float(_x1))
    x2.append(float(_x2))
x1, x2 = np.array(x1), np.array(x2) # 转化为Numpy数组待处理
# print(x1)
# print(x2)
plt.figure()
plt.xlabel("age(10)")
plt.ylabel("class")
re_list = k_means(x1,x2)
# 第一簇绘制
x1_1,x1_2=[],[]
for i in range(len(re_list[0])):
    x1_1.append(x1[re_list[0][i]])
    x1_2.append(x2[re_list[0][i]])
plt.scatter(x1_1, x1_2, c="r", s=6) #s是点的大小,c是颜色‘b’blue‘g’green‘r’red‘c’cyan‘m’magenta‘y’yellow‘k’black‘w’white
plt.scatter(re_list[2][0], re_list[2][1], c="r", s=36)
print("红色聚类中心:"+str(re_list[2][0])+","+str(re_list[2][1]))
# print(x1_1)
# print(x1_2)
# 第一簇绘制
x2_1,x2_2=[],[]
for i in range(len(re_list[1])):
    x2_1.append(x1[re_list[1][i]])
    x2_2.append(x2[re_list[1][i]])
plt.scatter(x2_1, x2_2, c="b", s=6)
plt.scatter(re_list[3][0], re_list[3][1], c="b", s=36)
print("蓝色聚类中心:"+str(re_list[3][0])+","+str(re_list[3][1]))
plt.show()

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值