FuzzyPy-模糊聚类(传递闭包法)

文章目录

  • **FuzzyPy-模糊聚类(传递闭包法)**
    • **一、传递闭包法的操作步骤**
    • **二、关键技术分析与准备工作**
      • 1、涉及的主要编程技术和模糊数学的计算方法
      • 2、准备工作
    • **三、实现步骤**
      • 1、导入相关库
      • 2、生成相似矩阵
      • 3、计算传递闭包
      • 4、筛选传递闭包的所有元素并排序
      • 5、算出所有截矩阵、分类、记录分类结果
      • 6、输出聚类报告
    • **四、技术总结**
一、传递闭包法的操作步骤
  • 第一步: 计算相似矩阵 RRR 的传递闭包。即依次计算 R2R^2R2、R4R^4R4、…,当第一次出现 R2i=R2i+1R^{2^i}=R^{2^{i+1}}R2i=R2i+1 时 R2iR^{2^i}R2i 就相似矩阵对应的传递闭包;

  • 第二步: 将传递闭包中的元素从大到小排列:λ1>λ2>⋯>λm>\lambda_1>\lambda_2>\cdots>\lambda_m>λ1​>λ2​>⋯>λm​>;

  • 第三步: 求出所有 λk\lambda_kλk​ 对应的截矩阵 Rλ1,Rλ2,⋯,RλmR_{\lambda_1},R_{\lambda_2},\cdots,R_{\lambda_m}Rλ1​​,Rλ2​​,⋯,Rλm​​,根据截矩阵进行分类,并记录分类结果;

  • 第四步: 写出动态聚类结果(输出动态聚类报告);

  • 第五步: 画出动态聚类图。

二、关键技术分析与准备工作
1、涉及的主要编程技术和模糊数学的计算方法
  • (1)传递闭包的计算:模糊矩阵的合成;矩阵相等的判断

  • (2)找出截集水平λk\lambda_kλk​:筛选传递闭包中的重复元素并排序

  • (3)动态分类:计算截矩阵;找出元素为1的元素对应下标,并放入同一集合;

  • (4)输出聚类结果:字符串操作

  • (5)动态聚类图*:相关绘图工具的使用(暂不开发)

2、准备工作

要实现以上技术内容需要安装以下包库:

  • Python

  • Numpy

  • scikit-fuzzymath(skfuzzy)

三、实现步骤
1、导入相关库

方便起见直接将skfuzzy中所有函数导入。

import numpy as np
from skfuzzy import *
2、生成相似矩阵

为方便起见

  • 直接写成 n*n的随机矩阵,取n=5

  • 相似矩阵的元素都只取2位小数

n = 5
R = np.random.rand(n,n)
R = R.dot(R.T)
R = R / np.max(R)
row, col = np.diag_indices_from(R)
R[row,col] = np.ones([n])
R = (R*100).astype(np.int)/100
print(R)
[[1.   0.53 0.5  0.36 0.57][0.53 1.   0.42 0.45 0.65][0.5  0.42 1.   0.44 0.48][0.36 0.45 0.44 1.   0.71][0.57 0.65 0.48 0.71 1.  ]]
3、计算传递闭包

注意: 由于传递闭包至多只需要做 [ln(n)]+1次,因此最简单的实现方法就是直接从0[ln(n)]+1

t_R = R
for i in range(np.log2(n).astype(np.int)+1):     t_R2 = maxmin_composition(t_R,t_R)if np.sum(np.abs(t_R-t_R2))!=0:t_R = t_R2else:        break
print('传递闭包为R的 2^{0} 次方:\r\n'.format(i))
print(t_R)
传递闭包为R的 2^2 次方:[[1.   0.57 0.5  0.57 0.57][0.57 1.   0.5  0.65 0.65][0.5  0.5  1.   0.5  0.5 ][0.57 0.65 0.5  1.   0.71][0.57 0.65 0.5  0.71 1.  ]]
4、筛选传递闭包的所有元素并排序

这个非常简单

  • 去重:直接用numpyunique方法即可

  • 变成数组:直接用reshape(-1)就变成了一维数组

  • 排序:直接用sort。由于默认是升序,因此排完后再用[::-1]倒序即可

lambdas = np.sort(np.unique(t_R).reshape(-1))[::-1]
print(lambdas)
[1.   0.71 0.65 0.57 0.5 ]

这里可以小秀一下:

lam_str = ''
for (i,lam) in zip(range(len(lambdas)),lambdas):if i !=len(lambdas)-1:lam_str += str(lam)+' > 'else:lam_str += str(lam)
print('截集水平:'+lam_str)
截集水平:1.0 > 0.71 > 0.65 > 0.57 > 0.5
5、算出所有截矩阵、分类、记录分类结果

这里需要注意一个问题,我们计算截矩阵的根本目的是找出在该截集水平时有关系的元素的对应下标。在Python里面这个操作其实可以直接实现,可以不用算出截矩阵。

截矩阵的实现方法非常简单:(t_R >= lambda)*1

temp_pairs = np.argwhere(t_R>=lambdas[1])print(temp_pairs)
[[0 0][1 1][2 2][3 3][3 4][4 3][4 4]]

但接下来的问题有点麻烦,我们需要将互相有关系的元素下标放在一起。

为了方便实现,我们用了一种最 的办法,这里大致说一下思路。

  • 从截矩阵返回的内容是所有有关系的元素的下标的list,先遍历所有下标,任意一组下标集中出现它时我们就把另一个下标放进来。这样对每个元素而言,只要和它有关系的元素就会全部放进这一个列表;

  • 由于传递闭包是对称矩阵,因此每组 非对角线 上元素的下标都会成对出现,因此只需将元素遍历一次即可;

  • 由于 对角线元素 的下标并没有被我们删除,因此所有元素都会和它有关系的元素放在同一列表;

  • 每个元素遍历完成后,清除它对应的列表的重复值;最后再对总的列表清理一次重复值,这样就得到了一个只包含最终分类结果的列表。

为了方便起见,我们将这个方法封装起来:

def get_classes(temp_pairs):lists = []for item1 in temp_pairs:temp_list = []for item2 in temp_pairs:if item1[0]==item2[1]:temp_list.append(item2[0])        lists.append(list(set(temp_list)))return(list(np.unique(lists)))print(get_classes(temp_pairs))
[[0], [1], [2], [3, 4]]

接下来遍历所有的 λ\lambdaλ得出所有聚类结果:

classes = []for lam in lambdas:if lam == lambdas[0]:classes.append([[x] for x in range(n)])else:pairs = np.argwhere(t_R >= lam)classes.append(get_classes(pairs))for c in classes:print(c)
[[0], [1], [2], [3], [4]]
[[0], [1], [2], [3, 4]]
[[0], [1, 3, 4], [2]]
[[0, 1, 3, 4], [2]]
[0, 1, 2, 3, 4]
6、输出聚类报告

这一步就简单了,只需要进行简单的字符串操作即可:

report_str = []for c in classes:temp_str = 'classes:$\{'for x in c:sub_class = ''if type(x) == list:sub_class = '\{'for i in x:sub_class += 'x_{' + str(i) + '},'sub_class = sub_class[:-1] + '\},'else:sub_class += 'x_{' + str(x) + '},'temp_str += sub_classtemp_str = temp_str[:-1]temp_str += '\}$'report_str.append(temp_str)for r in report_str:print(r,'\n')
classes:$\{\{x_{0}\},\{x_{1}\},\{x_{2}\},\{x_{3}\},\{x_{4}\}\}$ classes:$\{\{x_{0}\},\{x_{1}\},\{x_{2}\},\{x_{3},x_{4}\}\}$ classes:$\{\{x_{0}\},\{x_{1},x_{3},x_{4}\},\{x_{2}\}\}$ classes:$\{\{x_{0},x_{1},x_{3},x_{4}\},\{x_{2}\}\}$ classes:$\{x_{0},x_{1},x_{2},x_{3},x_{4}\}$

放到 markdown 里看看效果:

classes:{{x0},{x1},{x2},{x3},{x4}}\{\{x_{0}\},\{x_{1}\},\{x_{2}\},\{x_{3}\},\{x_{4}\}\}{{x0​},{x1​},{x2​},{x3​},{x4​}}

classes:{{x0},{x1},{x2},{x3,x4}}\{\{x_{0}\},\{x_{1}\},\{x_{2}\},\{x_{3},x_{4}\}\}{{x0​},{x1​},{x2​},{x3​,x4​}}

classes:{{x0},{x1,x3,x4},{x2}}\{\{x_{0}\},\{x_{1},x_{3},x_{4}\},\{x_{2}\}\}{{x0​},{x1​,x3​,x4​},{x2​}}

classes:{{x0,x1,x3,x4},{x2}}\{\{x_{0},x_{1},x_{3},x_{4}\},\{x_{2}\}\}{{x0​,x1​,x3​,x4​},{x2​}}

classes:{x0,x1,x2,x3,x4}\{x_{0},x_{1},x_{2},x_{3},x_{4}\}{x0​,x1​,x2​,x3​,x4​}

四、技术总结

本文利用Python实现了基于传递闭包法的模糊聚类分析。整个过程可以看出其实实现方法都非常简单。但目前仍然还是有一些不足之处:

1、相似矩阵我们是直接随机生成的,因此要直接应用的话还得自己写出相似矩阵的构造方法。当然这个方法很简单,我们不多讲;

2、在给定的截矩阵的前提下求出对应的分类方法get_classes还有很大的改进空间。目前的复杂度是 n×nn\times nn×n,方法特别笨。另外该方法在处理单位矩阵时其实返回的是一个元素为数字的列表,这导致分类结果没有正确将每个元素各为一类的情况展示出来,这部分必须要改进!

3、动态聚类图还没画!当然这个问题还比较麻烦,暂时不弄了。

完成时间:

import datetime
print(datetime.datetime.now())
2020-11-06 01:46:27.822593

用Python实现模糊聚类(传递闭包法)相关推荐

  1. python实现模糊聚类绝对值减数法

    在进行模糊聚类的时候,我们常常需要计算相似关系系数矩阵,即相似矩阵. 常用的方法有数量积法,相关系数法,最大最小法 ,算术平均最小法,几何平均最小法,绝对值减数法,绝对值指数法,专家打分法等. 这里实 ...

  2. 聚类算法及python实现——模糊C均值(FCM)

    聚类算法及python实现--模糊C均值(FCM) 模糊C和K均值的区别 K均值:硬聚类,隶属度只有0和1,基于"类内误差平方和最小化"原则 模糊C:模糊聚类,隶属度取值为[0,1 ...

  3. 课程学习——模糊C均值聚类分割法

    matlab:C语言逻辑实现模糊C均值聚类分割法. 代码: close all; clear all; clc; data=imread('E:\matlabCX\图片\7.jpg'); [m,n,r ...

  4. 模糊数学笔记:五、模糊聚类

    模糊聚类分析是模糊数学中应用最为广泛的方法之一.近年来也涌现出了多种不同的模糊聚类方法,本文直接从其操作流程出发,介绍模糊聚类分析的主要内容. 1.一般流程 数据预处理 相似关系建立 聚类分析 2.数 ...

  5. 聚类算法 距离矩阵_模糊聚类算法

    模糊聚类算法 1.如何理解模糊聚类 事物间的界线,有些是明确的,有些则是模糊的.当聚类涉及到事物之间的模糊界线时,需要运用模糊聚类分析方法. 如何理解模糊聚类的"模糊"呢:假设有两 ...

  6. 颜色迁移之四——模糊聚类(FCM)算法

    伴随着模糊集理论的形成.发展和深化,RusPini率先提出模糊划分的概念.以此为起点和基础,模糊聚类理论和方法迅速蓬勃发展起来.针对不同的应用,人们提出了很多模糊聚类算法,比较典型的有基于相似性关系和 ...

  7. 模糊聚类算法(FCM)

    伴随着模糊集理论的形成.发展和深化,RusPini率先提出模糊划分的概念.以此为起点和基础,模糊聚类理论和方法迅速蓬勃发展起来.针对不同的应用,人们提出了很多模糊聚类算法,比较典型的有基于相似性关系和 ...

  8. 模糊数学 3、模糊聚类

    ------------------------2020.8.17更新------------------------------ 模糊数学视频链接:https://pan.baidu.com/s/1 ...

  9. FCM模糊聚类 学习笔记

    就总结注释一下 怕忘了 我看的博客地址(模糊聚类算法 - 知乎) 逐步模糊聚类: 逐步聚类法类是中心点聚类法.(上述博客原话) 逐步聚类法是一种基于模糊划分的模糊聚类分析法.它是预先确定好待分类的样本 ...

  10. 模糊数学学习笔记 5:模糊聚类

    个人博客地址 Glooow,欢迎光临~~~ 文章目录 1. 数据标准化 2. 建立模糊相似矩阵 1.1 相关系数类 1.2 距离类 1.3 贴近度类 3. 聚类 4. 其他问题 5. 模糊C均值法(F ...

最新文章

  1. python爬取aspx数据
  2. linux进程--进程组、会话、守护进程(八)
  3. Python Set Literals
  4. tp5获取所有请求参数、请求头和IP(亲测)
  5. php实现跑马灯闪亮,易达CMS实现跑马灯特效!
  6. 如何在 C# 平台调用云开发?
  7. volatile的应用
  8. [ 原创 ]学习笔记-Android中隐式Intent 的使用
  9. atitit.atiHtmlUi web组件化方案与规范v1
  10. Clark变换和Park变换仿真验证
  11. couchbase 报 The Content of this Observable is already released. Subscribe earlier or tune the Couch
  12. 《指数基金定投指南》读书笔记
  13. 干货 | 携程Dynamo风格存储的落地实践
  14. php为网页更改颜色,php如何设置网页颜色?
  15. 清明节微信公众号图文排版有哪些经典素材?
  16. 使用OpenCV检测摄像头视频中的人脸
  17. 关于寻迹小车组装建议
  18. _()---由此知度娘和google的冷暖
  19. 微信小程序 拍照打卡功能实现
  20. 中国大学MOOC创业融资题库及答案

热门文章

  1. 边缘检测帧差法matlab,【数字图像处理】帧差法与Kirsch边缘检测实现运动目标识别与分割...
  2. OpenRefine安装使用
  3. 车载双目摄像头,为什么特斯拉还在迟疑?
  4. 什么是Linux 软件源
  5. 高通平台如何抓RAMDUMP
  6. haversine根据经纬度算距离
  7. Java 生产环境 linux下汉字变方框解决
  8. Arduino实现语音实时播报当前温湿度
  9. CAD输出图至Word
  10. 2010年6月CCNA题库新增15道新题视频讲解