ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python不确定性计算之模糊动态聚类实验

2022-06-10 10:02:16  阅读:220  来源: 互联网

标签:matrix temp python 模糊 list 聚类 print class lambda


模糊动态聚类实验

本实验所采用的模糊聚类分析方法是基于模糊关系上的模糊聚类法,也称为系统聚类分析法,可分为三步:
第一步:数据标准化,建立模糊矩阵
第二步:建立模糊相似矩阵
第三步:聚类

本程序读取Excel文件,再由程序读入,在数据标准化中采用了最大值规格法,然后通过夹角余弦法或最大最小法构造模糊相似矩阵,然后按lambda截集进行动态聚类,聚类完成后,采用Xie-Beni指标和F统计指标两种方式进行评判,选出最优聚类和lambda的最优取值。
代码如下:

# -*- coding: utf-8 -*-
import numpy as np
import pprint
import xlrd #读取Excel的扩展工具
from copy import deepcopy
import warnings
#矩阵不用科学计数法的显示方式
np.set_printoptions(suppress=True)

def main():
    path = 'data.xlsx'
    # 0.读取数据
    matrix = read_excel(path)
    # 1.数据标准化
    #k = 2
        
    while( k != 1 and k != 2 and k !=3 ):
        print('请输入标准化方法:\n1.平移-标准差变换\n2.平移-极差变换\n3.最大值规格法')
        k = eval(input())    
    
    x_matrix = std_matrix(matrix,k)
    print(x_matrix)
    # 2.构造模糊相似矩阵
    k = -1
    while( k != 1 and k != 2 ):
        print('请输入构造模糊相似矩阵方法:\n1.夹角余弦法\n2.最大最小法')
        k = eval(input())    
    if( k == 1 ):
        r_matrix = get_rmatrix1(x_matrix)
    else:
        r_matrix = get_rmatrix2(x_matrix)
    #print('===============标准化特征指标矩阵=============',x_matrix)
    #print('==================模糊相似矩阵R================',r_matrix)
    # 3.求传递闭包t(R)
    i = 0
    while True:
        t_r_matrix = get_tR(r_matrix)
        if (t_r_matrix == r_matrix).all():#每个元素都相等
            break
        else:
            r_matrix = t_r_matrix
            i = i + 1
    # 4.按lambda截集进行动态聚类
    result = lambda_clustering(t_r_matrix)
    warnings.filterwarnings("ignore")#因为存在除0情况,需忽略警告

    # 5.利用Xie_beni指数或F统计寻找最优分类
    k = -1
    while( k != 1 and k != 2 ):
        print('请输入评判Lambda取值的标准:\n1.Xie-Beni指标\n2.F统计指标')
        k = eval(input())    
    if( k == 1 ):
        Xie_Beni(result,x_matrix)
    else:
        F_Statistics(result,x_matrix)

# 1.标准化:
def std_matrix(x_matrix,k):
    x = deepcopy(x_matrix)
    #获得特征指标矩阵x的行列数
    x_rows = x.shape[0]#读取矩阵第一维度的长度,即行数
    x_cols = x.shape[1]#读取矩阵第二维度的长度,即列数
    x_mean = np.mean(x,axis = 0)#均值
    x_std = np.std(x,axis = 0)#标准差
    #numerical python
    for i in range(x_rows):
        for j in range(x_cols):
            if(k == 1):
                x[i][j] = (x[i][j] - x_mean[j])/x_std[j]#平移-标准差变换(消除量纲)            
            elif(k == 2):
                x[i][j] = ( x[i][j] - min(x[i]) ) / ( max(x[i]) - min(x[i]) )#平移-极差变换
            else:    
                x[i][j] = round(x[i][j] / max(x_matrix.T[j]),2)#标准化:最大值规格法
    return x


# 2.构造模糊相似矩阵:采用夹角余弦法
def get_rmatrix1(x_matrix):
    x_rows = x_matrix.shape[0]#读取矩阵第一维度的长度,即行数
    x_cols = x_matrix.shape[1]#读取矩阵第二维度的长度,即列数
    # norm_matrix :每一行的2-范式值
    norm_matrix = np.linalg.norm(x_matrix,axis = 1)
    # r_matrix : 模糊相似矩阵
    r_matrix = np.zeros((x_rows,x_rows),dtype = 'float')#初值为零矩阵
    # 获得模糊相似接矩阵行列数
    r_rows = r_matrix.shape[0]
    r_cols = r_matrix.shape[1]
    for i in range(r_rows):
        for j in range(r_cols):
            #multi_matrix = x_matrix[i] * x_matrix[j]
            r_matrix[i][j] = abs(np.dot(x_matrix[i],x_matrix[j])) / (norm_matrix[i] * norm_matrix[j])#矩阵相乘,再除以2范式之积
    return r_matrix

# 2.构造模糊相似矩阵:采用最大最小法
def get_rmatrix2(x_matrix):
    # r_matrix : 模糊相似矩阵
    r_matrix = np.zeros((x_matrix.shape[0],x_matrix.shape[0]),dtype = 'float')
    for i in range(0,x_matrix.shape[0]):
        for j in range(0,x_matrix.shape[0]):
            max_sum = 0
            min_sum = 0
            for k in range(x_matrix.shape[1]):
                max_sum = max_sum + max(x_matrix[i][k], x_matrix[j][k])
                min_sum = min_sum + min(x_matrix[i][k], x_matrix[j][k])
            r_matrix[i][j] = round(min_sum / max_sum , 2)#最小值之和除以最大值之和
    return r_matrix


# 3.平方法求传递闭包t(R)
def get_tR(r_matrix):
    rows = r_matrix.shape[0]#读取矩阵第一维度的长度,即行数
    cols = r_matrix.shape[1]#读取矩阵第二维度的长度,即列数
    min_list = []
    new_mat = np.zeros((rows,cols),dtype = 'float')
    for m in range(rows):
        for n in range(cols):
            min_list = []
            now_row = r_matrix[m]
            for k in range(len(now_row)):
                #先取小,再取大
                min_cell = min(r_matrix[m][k],r_matrix[:,n][k])#先取小
                min_list.append(min_cell)
            new_mat[m][n] = max(min_list)#再取大
    return new_mat


def lambda_clustering(final_matrix):
    rows = final_matrix.shape[0]#读取矩阵第一维度的长度,即行数
    cols = final_matrix.shape[1]#读取矩阵第二维度的长度,即列数
    result = [] #返回的结果
    global lambda_list
    lambda_list = []  #所有的lambda值
    temp_matrix = np.zeros((rows,cols),dtype = 'float')
    global temp_class_all
    temp_class_all = []

    for i in range(0,rows):
        for j in range(0,cols):
            lambda_list.append(final_matrix[i][j])#提取各个特征值到lambda_list

    #print(final_matrix)
    lambda_list = list(set(lambda_list))#去重
    lambda_list.sort()

    #通过循环,逐个计算lambda值的分类情况
    for i in range(len(lambda_list)):
        temp_matrix = np.zeros((rows,cols),dtype = 'float')
        class_list = []  #分类情况
        mark_list = [] #存储当前lambda值已经被分组的样本
        for m in range(rows):
            for n in range(cols):
                if final_matrix[m][n] >= lambda_list[i]:
                    temp_matrix[m][n] = 1 #大于lambda则赋值为1
        #对某个lambda值进行分类
        for m in range(rows):
            if (m+1) in mark_list:
                continue
            now_class = [] #当前分类情况
            now_class.append(m+1)
            mark_list.append(m+1)
            for n in range(m+1,rows):
                if (temp_matrix[m] == temp_matrix[n]).all() :
                    #进行分类
                    now_class.append(n+1)#每个小的分类表
                    #print(now_class)
                    mark_list.append(n+1) #存储当前lambda值,已经被分组的样本
            class_list.append(now_class) #分类完成           
        global temp_class 
        temp_class = class_list
        result.append(['matrix:',temp_matrix,'lambda:',lambda_list[i],'class',temp_class])  
        temp_class_all.append(temp_class)
    return result

# 5.利用Xie_beni指标寻找最优分类
def Xie_Beni(final_matrix,x_matrix):
    class_num = 0    #当前总类数
    class_list = []  #当前分类情况
    rate = float('inf') #Xie_Beni指数
    flag = 0 #标记Xie_Beni指数最大的分类情况
    i = 0
    for temp in final_matrix:
        this_in_measure = 0    #当前分类的类内紧密度,类中各点与类中心的距离平方和
        this_out_measure = float('inf')   #当前分类的类间分离度,最小的类与类中心的平方
        class_list = temp_class_all[i]
        class_num = len(class_list)
        means_list = [np.zeros((1,x_matrix.shape[1]),dtype = 'float')]*class_num #该分类下,每一类的均值
        #遍历每一类
        for i in range(class_num):
            #求每一类的类中心
            this_class_num = len(class_list[i])
            this_sum = np.zeros((1,x_matrix.shape[1]),dtype = 'float')
            this_means = np.zeros((1,x_matrix.shape[1]),dtype = 'float')
            for j in range(this_class_num):
                this_sum += x_matrix[class_list[i][j]-1]
            this_means = this_sum / this_class_num
            means_list[i] = this_means

        #计算当前分类类间分离度
        for m in range(len(means_list)):
            if len(means_list) == 1:
                this_out_measure = 0 #当所有样本分为一类的时候,类间分离度为无穷大,但这样的分类没有任何意义,所以置0,不予以比较。
                break
            for n in range(m+1,len(means_list)):
                temp = np.linalg.norm(means_list[m] - means_list[n])#计算向量欧氏距离
                if temp < this_out_measure:
                    this_out_measure = temp

        #计算当前分类类内紧密度
        for m in range(class_num):
            this_class_num = len(class_list[i])
            for n in range(this_class_num):
                add = np.linalg.norm(means_list[m] - np.array([x_matrix[n-1]]))#计算向量欧氏距离
                this_in_measure = this_in_measure + add

        this_rate = this_in_measure /  this_out_measure# 类内距离 ÷ 类间距离

        print('lambda =',round(lambda_list[i],2))
        print("Xie_Beni指数为%.2f"%this_rate)
        print('当前分类为',class_list)
        print("================================================")
        if (this_rate < rate):
            rate = this_rate
            flag = class_list
            best_lambda = lambda_list[i]
            min_num = this_rate
        i = i + 1
    
    print("****************最优分类结果如下****************")
    print('lambda的最优取值为 %.2f'%best_lambda)
    print('Xie_Beni指数最小值为%.2f'%min_num)
    print('最优分类为',flag)
    
# 5.利用 F统计指标
def F_Statistics(results, standard_matrix):
    #定义变量F 为F统计量数值    #定义class_class变量为类与类之间的距离  F的分子#    定义class_sample变量为类内样品间的距离  F的分母
    temp_F = []
    k = 0
    #print('temp_class_all:',temp_class_all)
    for result in results:
        mean_all = np.mean(standard_matrix, axis=0)#计算矩阵所有样品属性的平均值
        sorts = temp_class_all
        class_class = 0
        class_sample = 0

        #对于每个分类
        for sort in sorts:
            sort = sort[0]
            sort = [i-1 for i in sort]#将分类转化 [4, 9, 10]-->[3, 8, 9]因为矩阵下标从零开始
            # print(standard_matrix[sort])
            mean_j = np.mean(standard_matrix[sort], axis=0)#计算矩阵第j类样品的平均值

            #类间距离
            xj_av_reduce_xall_av = (np.sum((np.square(mean_j - mean_all)), axis=0))**(1/2) #第j类样品的平均值 - 所有样品属性的平均值
            class_class = class_class + (len(sort) * xj_av_reduce_xall_av**2)
            
            #计算类class_sample 为类内样品间的距离
            sum_xij_reduce_xj_av = 0#用来储存这个类中所有样品的xij_reduce_xj_av值
            for s in sort:#求每一个样品的xij_reduce_xj_av,对所有属性
                xij_reduce_xj_av = (np.sum(np.square((standard_matrix[s] - mean_j)), axis=0))**(1/2) #计算x(i,j) - 第j类样品的平均值 
                sum_xij_reduce_xj_av = sum_xij_reduce_xj_av + (xij_reduce_xj_av**2)
            class_sample = class_sample + sum_xij_reduce_xj_av #类内样品间的距离

        F = (class_class / (len(sorts[k])-1)) / (class_sample / (standard_matrix.shape[0] - len(sorts[k]))) #类间距离 ÷ 类内距离

        if(F == float('inf')):
            #当所有样本分为一类的时候,类间分离度为无穷大,但这样的分类没有任何意义,所以置0,不予以比较。
            F = 0
        F = round(F,2)
        temp_F.append(F)

        print('lambda =',round(lambda_list[k],2))
        print('F统计量为',F)
        print('当前分类结果',temp_class_all[k])    
        print("================================================")
        k = k + 1

    print("****************最优分类结果如下****************")
    print('lambda的最优取值为 %.2f'%lambda_list[np.argmax(temp_F)])
    print('F统计量最大值为%.2f'%max(temp_F))
    print('最优分类为',temp_class_all[np.argmax(temp_F)])#取F最大时候的下标

# 7.读取excel目录
def read_excel(path):
    #打开exel
    workbook = xlrd.open_workbook(path,'r') 
    #获得sheet1名字
    sheet1 = workbook.sheets()[0] 
    rows = sheet1.nrows
    cols = sheet1.ncols
    #建立特征指标矩阵
    x_matrix = np.zeros((rows-1,cols-1),dtype = 'float')
    #第一行是列名,从第二行开始
    for i in range(0,rows-1):
        #第一列是序号,从第二列开始
        for j in range(0,cols-1):
            x_matrix[i][j]= sheet1.cell(i+1,j+1).value
    return x_matrix

if __name__ == '__main__':
    main()

测试表格如下:
在这里插入图片描述

标签:matrix,temp,python,模糊,list,聚类,print,class,lambda
来源: https://www.cnblogs.com/chengjunkai/p/16362136.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有