模糊动态聚类之python实现

来源:互联网 发布:中国网络经济人登陆 编辑:程序博客网 时间:2024/06/06 09:34

模糊动态聚类

聚类过程: 1.数据标准化(建立模糊矩阵),最大值标准化法,平移——极差变换 2.建立模糊相似矩阵 3.聚类(求动态聚类图)

模糊动态聚类主要用于非监督学习的聚类分析,假设样本数据为n*m维(共有n个样本,m个属性),可以使用模糊动态聚类的方法得出聚类结果。根据上述过程会得到不同lambd值对应的划分,对于不同的类别根据F—统计的大小得到最优的聚类结果。
python代码如下:

# -*- coding: utf-8 -*-"""Created on Tue Dec  5 10:55:07 2017@author: mynumber"""import numpy as npimport pandas as pdclass CLUST(object):    """模糊动态聚类    聚类过程:     1.数据标准化(建立模糊矩阵),最大值标准化法,平移——极差变换     2.建立模糊相似矩阵     3.聚类(求动态聚类图)     """    def __init__(self,standard_choice='Max_standard',Maxlike_choice='MinMax'):        self.standard_choice=standard_choice        self.Maxlike_choice=Maxlike_choice        self.lambd=0        self.cluster=[]                        #对应的lambd值,及其对应的数据        self.best_lambd=[]                     #最优的lambd        self.F=[]                              #除去全部分为一类和全部分为两类的数据    def standard(self,data):        """数据标准化"""        data_min,data_max=np.min(data,axis=0),np.max(data,axis=0)        numSamples,numShapes=np.shape(data)        delta_data=data_max-data_min        if self.standard_choice=='Max_standard':            for i in range(numSamples):                data[i,:]= (data[i,:] )/data_max            #将四舍五入保留两位数字            for i in  range(numSamples):                for j in range(numShapes):                    data[i,j]=round(float(data[i,j]),2)            return data        if self.standard_choice == 'std_standard':            for i in range(numSamples):               data[i,:]= (data[i,:]-data_min)/delta_data            #将四舍五入保留两位数字            for i in  range(numSamples):                            for j in range(numShapes):                    data[i,j]=round(float(data[i,j]),2)            return data    def MatrixLike(self,data):        """构造模糊相似矩阵"""        numSamples,numShapes=np.shape(data)        r=np.zeros((numSamples,numSamples))        for i in  range(numSamples):            for j in range(numSamples):                r[i,j]=np.sum(self.Min(data[i,:],data[j,:]))/np.sum(self.Max(data[i,:],data[j,:]))                r[i,j]=round(r[i,j],2)        return r    def Max(self,a,b):        """取最大值"""        a_or_b=[]        for (i,j) in zip(a,b):            if i>j:                  a_or_b.append(i)            else:                a_or_b.append(j)        return a_or_b    def Min(self,a,b):        """取最小值"""        a_and_b=[]        for (i,j) in zip(a,b):            if i<j:                a_and_b.append(i)            else:                a_and_b.append(j)        return a_and_b    def t_R(self,R):        """计算传递闭包"""        numSamples,numShapes=np.shape(R)        T_R=np.zeros(np.shape(R))        for i in range(numSamples):            for j in range(numShapes):                T_R[i,j]=max(self.Min(R[i,:],R[j,:]))        return T_R    def judge(self,T1,T2):        """判断T1,T2是否相同        相同返回1,不同返回0"""        flag=1        for i,j in zip(T1.flat,T2.flat):            if i!=j :                flag=0                break        return flag    def main(self,data):        """程序调用"""        i=1        data=self.standard(data)        R=self.MatrixLike(data)        temp=self.t_R(R)                              #计算第一个传递闭包        flag=self.judge(temp,R)        while(flag!=1):            i+=1            temp_1=self.t_R(temp)            flag=self.judge(temp_1,temp)            temp=temp_1        T=temp        lambd=np.unique(T)        lambd_length=len(lambd)        for i in range(lambd_length):            temp={}            temp['lambd']=round(lambd[lambd_length-i-1],2)            temp['answer']=self.clust_T(T,lambd[lambd_length-i-1])            self.cluster.append(temp)        self.choise_lambd(data)        print("模糊聚类结果为:",self.cluster)        ind=self.F.index(max(self.F))        print("根据F统计,最佳聚类结果为:",self.cluster[ind+1]['answer'])    def clust_T(self,T,lam):        """        根据给定的lambda,对数据进行划分        """        answer= T>=lam        numI,numJ=answer.shape        xindex,yindex=[],[]        for i in range(numI):            for j in range(numJ):                if answer[i,j]==True:                    xindex.append(i+1)                    yindex.append(j+1)        num=list(np.unique(xindex))        total_clust=[]        for i in num:            temp=[]                for j,k in zip(xindex,yindex):                if i==j:                    temp.append(k)            total_clust.append(temp)        if len(total_clust)==len(xindex):            return total_clust        else :            return  np.unique((total_clust))#xindex,yindex    def data_mean(self,data,index):         """计算每类的中心,flag=1表示data只有一组,否则含有多组"""         flag=len(index)         if flag==1:             return data         else :             return np.mean(data,axis=0)    def choise_lambd(self,data):         #根据F统计,选择最优的lambd值         n=np.shape(data)[0]         self.x_k=np.mean(data,axis=0)         length=len(self.cluster)         for choice in range(1,length-1):       #针对每个选择             total_sum1=0                   #计算F统计的分子值             total_sum2=0                     #计算F统计的分母值             r=len(self.cluster[choice]['answer'])             for i in self.cluster[choice]['answer']:    #针对每个选择的每个类别                     i=[j-1 for j in i]                 num1=np.sum(np.square(self.data_mean(data[i,:],i)-self.x_k))                 total_sum1+=len(i)*num1                 num2=0                 for k in i:                     num2+=np.sum(np.square(self.data_mean(data[i,:],i)-data[k,:]))                 total_sum2+=num2                F1=total_sum1/(r-1)             F2=total_sum2/(n-r)             F=F1/F2             self.F.append(F)xdata=np.array([[60.,10.,6.,2.],               [50.,1.,6.,4.],               [90.,6.,4.,6.],               [40.,5.,7.,3.],               [10.,1.,2.,4.]])clu=CLUST()clu.main(xdata)
原创粉丝点击