大数据学习笔记(三)-k-均值聚类&多维缩放找聚类

1.k-均值聚类
因为前面的几种求聚类的算法,需要计算两两配对项的关系,在数据集大的时候,速度会很慢。所以我们要学习k-均值聚类
算法思想:我们会事先知道需要聚类的数量。这儿假设我们需要n个聚类,那么我们先随机生成n个中心位置。然后利用聚类算法将各个数据项分配给最邻近的中心位置,然后移动中心位置到聚类的平均位置处,然后循环以上步骤,知道分配过程不再变化,那么算法结束。返回n个聚类。具体代码如下

#k-均值类聚
#rows->数据集,distance->求聚类的算法,k->聚类个数
def kcluster(rows,distance=pearson,k=4):
    #确定每个点的最小值和最大值
    ranges=[(min([row[i] for row in rows]),max(row[i] for row in rows))for i in range(len(rows[0]))]
    #随机创建k个中心点
    clusters=[[random.random()*(ranges[i][1]-ranges[i][0])+ranges[i][0] for i in range(len(rows[0]))]for j in range(k)]
    lastmatches=None
    for t in range(100):
        print 'Iteration %d' %t
        bestmatches=[[]for i in range(k)]

        #在每一行中寻找距离最近的中心点
        for j in range(len(rows)):
            row = rows[j]
            bestmatch=0
            for i in range(k):
                d= distance(clusters[i],row)
                if d<distance(clusters[bestmatch],row):
                    bestmatch=i
            bestmatches[bestmatch].append(j)

        #如果结果与上一次相同,则整个过程结束
        if bestmatches==lastmatches:
            break
        lastmatches=bestmatches
        #把中心点移到其所有成员的平均位置
        for i in range(k):
            avgs=[0.0]*len(rows[0])
            if len(bestmatches[i])>0:
                for rowid in bestmatches[i]:
                    for m in range(len(rows[rowid])):
                        avgs[m]+=rows[rowid][m]
                for j in range(len(avgs)):
                    avgs[j]/=len(bestmatches[i])
                clusters[i]=avgs
    return bestmatches

返回的bestmatches存放的是每个聚类。

2.之前我们学习的类聚,都是基于两个物品间的距离类聚,而我们生活中可以有很多相似的类聚,不仅仅是两个。所以我们需要多维缩放技术寻找聚类。(表达有问题,解释不太清楚)
思路如下:随机生成每一个数据项在二维空间的坐标点。然后通过每个点对一个点的相对的真实距离的施力情况,来对这个点的位置进行调整(这儿就用了多维缩放)。最后调整到总的误差值变大了,则算法结束。
具体代码如下

def scaledown(data,distance=pearson,rate=0.01):
    n=len(data)

    #每一对数据项之间的真实距离
    realdist=[[distance(data[i],data[j])for j in range(n)] for i in range(0,n)]

    outersum=0.0
    #随机初始化节点在二维空间中的起始位置
    loc=[[random.random(),random.random()]for i in range(n)]
    fakedist=[[0.0 for j in range(n)] for i in range(n)]

    lasterror=None

    for m in range(0,1000):
        #寻找投影后的距离
        for i in range(n):
            for j in range(n):
                fakedist[i][j]=sqrt(sum([pow(loc[i][x]-loc[j][x],2) for x in range(len(loc[i]))]))
        #移动节点
        grad=[[0.0,0.0]for i in range(n)]

        totalerror=0
        for k in range(n):
            for j in range(n):
                if j==k:
                    continue
                #误差值等于目标距离与当前距离之间差值的百分比
                errorterm=(fakedist[j][k]-realdist[j][k])/realdist[j][k]

                #每一个节点都需要根据误差的多少,按比例移离或移向其他节点
                grad[k][0]+=((loc[k][0]-loc[j][0])/fakedist[j][k])*errorterm
                grad[k][1]+=((loc[k][1]-loc[j][1])/fakedist[j][k])*errorterm

                #记录总的误差值
                totalerror+=abs(errorterm)
        print totalerror

        #如果节点移动之后的情况变得更糟,则程序结束
        if lasterror and lasterror<totalerror:
            break
        lasterror=totalerror

        #根据rate参数与grad值想乘的结果,移动每一个节点
        for k in range(n):
            loc[k][0]-=rate*grad[k][0]
            loc[k][1]-=rate*grad[k][1]
    return loc

下面代码是结果可视化,作图

def draw2d(data,lables,jpeg='mds2d.jpg'):
    img=Image.new('RGB',(2000,2000),(255,255,255))
    draw=ImageDraw.Draw(img)
    for i in range(len(data)):
        x=(data[i][0]+0.5)*1000
        y=(data[i][1]+0.5)*1000
        draw.text((x,y),lables[i],(0,0,0))
    img.save(jpeg,'JPEG')

这儿作出来的图,是以相对距离来判断他们的关联性的。可以很直观的看出聚类的信息。

这篇博客写的很差,自己理解了, 写不出来,尴尬。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值