CDA数据分析师Kmeans算法精简版(无for loop循环)( 二 )
本文插图
? 所以对于一个DataFrame来说 , 比如说这里的只包含x和y的data , 假设我们的质心是c = [1,1] , 可以用以下的方式来给出所有的实例点的x和y和点(1,1)之间的差值 。 注意 , 这里的c可以是list , 也可以是numpy array , 甚至可以是元组 。
$$
$$
? 算出每个实例的每个特征和质心点的差距之后 , 则需要将所有的数平方一下 , 然后按每一行加起来则给出了每一个实例点到质心的距离了
$$
$$
用的方法就是使用np.power(data - c, 2).sum(axis = 1)def cal_distant(dataset, centers):#选出不是label的那些特征列data = http://news.hoteastday.com/a/dataset.loc[:, dataset.columns !='label']#使用列表解析式的格式 , 对centers表里的每一行也就是每一个随机的质心点 , 都算一遍所有的点到该质心点的距离 , 并且存入一个list中d_to_centers = [np.power(data - centers.loc[i], 2).sum(axis = 1)for i in centers.index]#所有的实例点到质心点的距离都已经存在了list中 , 则可以直接带入pd.concat里面将数据拼起来return pd.concat(d_to_centers, axis = 1)d_to_centers = cal_distant(data, centers)d_to_centers.head(5)
01200.1533653.9355460.52828611.9878790.0880062.46244420.0279772.3617530.79500430.5434105.1832830.56569641.5055142.2482644.0311655 找出最近的质心点
当每个实例点都和中心点计算好距离后 , 对于每个实例点找出最近的那个中心点,可以用np.where的方法 , 但是pandas已经提供更加方便的方法 , 用idxmin和idxmax,这2个函数可以直接给出DataFrame每行或者每列的最小值和最大值的索引 , 设置axis = 1则是想找出对每个实例点来说 , 哪个质心点离得最近 。 curr_group = d_to_centers.idxmin(axis=1)
这个时候 , 每个点都有了新的group , 这里我们则需要开始更新我们的3个中心点了 。 对每一个临时的簇来说 , 算出X的平均 ,和Y的平均 , 就是这个临时的簇的中心点 。 6 重新计算新的质心点centers = data.loc[:, data.columns != 'label'].groupby(curr_group).mean()centers
xy00.5484680.5234741-1.0036801.0449552-0.125490-0.4753737 迭代
这样我们新的质心点就得到了 , 只是这个时候的算法还是没有收敛的 , 需要将上面的步骤重复多次 。
Kmeans代码迭代部分就完成了 , 将上面的步骤做成一个函数 , 做成函数后 , 方便展示Kmeans的中间过程 。 def iterate(dataset, centers):#计算所有的实例点到所有的质心点之间的距离d_to_centers = cal_distant(dataset, centers)#得出每个实例点新的类别curr_group = d_to_centers.idxmin(axis=1)#算出当前新的类别下每个簇的组内误差SSE = d_to_centers.min(axis = 1).sum()#给出在新的实例点类别下 , 新的质心点的位置centers = dataset.loc[:, dataset.columns != 'label'].groupby(curr_group).mean()return curr_group, SSE, centerscurr_group, SSE, centers = iterate(data,centers)centers, SSE(xy 00.8925790.931085 1 -1.0036801.044955 20.008740 -0.130172, 19.041432436034352)
最后需要判断什么时候迭代停止 , 可以判断SSE差值不变的时候 , 算法停止#创建一个空的SSE_list,用来存SSE的 , 第一个位置的数为0 , 无意义 , 只是方便收敛时最后一个SSE和上一个SSE的对比SSE_list = [0]#初始化质心点centers = initial_centers(data, k = 3)#开始迭代while True:#每次迭代中得出新的组 , 组内误差 , 和新的质心点 , 当前的新的质心点会被用于下一次迭代curr_group, SSE, centers = iterate(data,centers)#检查这一次算出的SSE和上一次迭代的SSE是否相同 , 如果相同 , 则收敛结束if SSE_list[-1] == SSE:break#如果不相同 , 则记录SSE , 进入下一次迭代SSE_list.append(SSE)SSE_list[0, 37.86874675507244, 11.231524142566894, 8.419267088238051]8 代码整合
推荐阅读
- 互联网分析师于斌|对于陆正耀“背后”的愉悦资本来说,反思才是第一要务
- 人群中国科学家通过古人基因组数据探寻中国文明源流
- 联想|联想个人云存储Mac版上线 苹果电脑用户数据备份更便捷
- 信息史上最全SpaceX火箭数据开源,核心、组员舱、起落架、发射信息全都有!
- 云创|真旺(徐州)大数据总经理李华领一行到访云创
- 主题马蜂窝大数据:大人小孩一起过“六一”,主题公园最受欢迎
- |6大数据可视化应用设计规范
- 链上|链上数据5月扫描:10000美元阻力下的链上百态
- 孜然实验室|DNA存储器突破了理论极限,一部手机装下全世界的数据
- 数据驶向智能海洋深处,华为存储的无尽想象