当前位置:   article > 正文

模糊C均值聚类(FCM)python_python fcm

python fcm

目录

一、模糊C均值聚类的原理 

二、不使用skfuzzy的python代码

三、 使用skfuzzy的python代码


一、模糊C均值聚类的原理 

 

二、不使用skfuzzy的python代码

  1. import numpy as np
  2. import random
  3. import matplotlib.pyplot as plt
  4. plt.rcParams['font.sans-serif']=['SimHei']
  5. plt.rcParams['axes.unicode_minus']=False
  6. '''初始化隶属矩阵'''
  7. def initial_u0(n,K):
  8. '''
  9. :param n:样本数量
  10. :param K:簇的数量
  11. :return: 初始化的隶属矩阵
  12. '''
  13. u0=np.zeros((K,n))
  14. for i in range(K):
  15. for j in range(n):
  16. if i==0:
  17. u0[i][j]=random.uniform(0,1)
  18. elif i<K-1:
  19. s=0
  20. for k in range(i):
  21. s=s+u0[k][j]
  22. u0[i][j]=random.uniform(0,1-s)
  23. else:
  24. s=0
  25. for k in range(i):
  26. s=s+u0[k][j]
  27. u0[i][j]=1-s
  28. return u0
  29. '''聚类函数'''
  30. def Cluster(U,n):
  31. '''
  32. :param U:隶属度矩阵
  33. :param n: 样本数量
  34. :return: 聚类结果
  35. '''
  36. cluster=[]
  37. for i in range(n):
  38. A=U.T[i].tolist()
  39. a=A.index(max(A))
  40. cluster.append(int(a))
  41. return cluster
  42. '''计算隶属中心矩阵'''
  43. def center(data,U,m,n,K,dim):
  44. '''
  45. :param data:样本数据
  46. :param U: 隶属度矩阵
  47. :param m: 模糊加权参数,一般取2
  48. :param n: 样本数量
  49. :param K: 聚类数目
  50. :param dim: 维度
  51. :return: 隶属中心矩阵
  52. '''
  53. '''进行初始聚类'''
  54. cluster=Cluster(U,n)
  55. '''初始化隶属中心矩阵'''
  56. Z=np.zeros((K,dim))
  57. '''计算隶属中心矩阵'''
  58. #初始化
  59. u_x=[np.zeros((1,dim)) for i in range(K)]
  60. u=[0 for i in range(K)]
  61. #计算
  62. for i in range(n):
  63. c=cluster[i] #类别
  64. u[c]=u[c]+(U[c][i])**m
  65. u_x[c]=u_x[c]+((U[c][i])**m)*data[i]
  66. for i in range(K):
  67. Z[i]=u_x[i]/u[i]
  68. '''返回隶属中心矩阵'''
  69. return Z
  70. '''基于欧氏距离计算各点到聚类中心的距离矩阵'''
  71. def distinct(data,n,dim,Z,K):
  72. '''
  73. :param data:样本数据
  74. :param n: 样本数量
  75. :param dim: 数据维度
  76. :param Z: 隶属中心矩阵
  77. :param K: 聚类数目
  78. :return: 基于欧氏距离的距离矩阵
  79. '''
  80. '''初始化距离矩阵'''
  81. D=np.zeros((K,n))
  82. '''计算欧式距离'''
  83. for i in range(K):
  84. for j in range(n):
  85. z=Z[i] #隶属中心
  86. df=data[j] #数据点
  87. df_z=df-z
  88. d=0
  89. for k in range(dim):
  90. d=d+(df_z[k])**2
  91. d=np.sqrt(d)
  92. D[i][j]=d
  93. '''返回距离矩阵'''
  94. return D
  95. '''定义目标函数并返回目标函数值'''
  96. def function(data,Z,n,dim,K,U,m,D):
  97. '''
  98. :param data:样本数据
  99. :param Z: 隶属中心矩阵
  100. :param n: 样本数量
  101. :param dim: 数据维度
  102. :param K: 聚类数目
  103. :param U: 隶属度矩阵
  104. :param m: 模糊加权参数
  105. :param D: 距离矩阵
  106. :return: 目标函数值
  107. '''
  108. '''初始化聚类'''
  109. cluster=Cluster(U,n)
  110. '''计算目标函数值'''
  111. J=0 #目标函数值
  112. W=[0 for i in range(K)]
  113. for i in range(n):
  114. c=cluster[i] #聚类类别
  115. df=data[i] #数据点
  116. z=Z[c] #聚类中心
  117. d=D[c][i] #数据点到聚类中心的距离
  118. u=U[c][i] #隶属度
  119. W[c]=W[c]+(u**m)*(d**2)
  120. J=sum(W)
  121. '''返回目标函数值'''
  122. return J
  123. '''更新隶属度矩阵'''
  124. def update_U(data,Z,n,dim,K,D,m):
  125. '''
  126. :param data:样本数据
  127. :param Z: 隶属中心矩阵
  128. :param n: 样本数量
  129. :param dim: 数据维度
  130. :param K: 聚类数目
  131. :param D: 距离矩阵
  132. :param m: 模糊加权参数
  133. :return: 更新后的隶属度矩阵
  134. '''
  135. '''初始化隶属度矩阵'''
  136. U=np.zeros((K,n))
  137. '''更新隶属度矩阵'''
  138. for i in range(K):
  139. for j in range(n):
  140. r=0
  141. for k in range(K):
  142. r=r+(D[i][j]/D[k][j])**(2/(m-1))
  143. U[i][j]=1/r
  144. '''返回更新后的隶属度矩阵'''
  145. return U
  146. '''模糊C均值聚类函数'''
  147. def FCM(data,K,Tmax,m,error):
  148. '''
  149. :param data:样本数据
  150. :param K: 聚类数目
  151. :param Tmax: 最大迭代步数
  152. :param m: 模糊加权参数
  153. :param error: 迭代停止阈值,一般取0.001至0.01
  154. :return: 聚类结果
  155. '''
  156. '''样本数量'''
  157. n=data.shape[0]
  158. '''数据维度'''
  159. dim=data.shape[1]
  160. '''初始化隶属度矩阵'''
  161. U0=initial_u0(n,K)
  162. U=U0.copy()
  163. '''存储目标函数值'''
  164. J=[]
  165. '''循环'''
  166. for i in range(Tmax):
  167. #计算隶属中心矩阵
  168. Z=center(data,U,m,n,K,dim)
  169. #基于欧氏距离计算各点到聚类中心的距离矩阵
  170. D=distinct(data,n,dim,Z,K)
  171. #计算目标函数的值
  172. J.append(function(data,Z,n,dim,K,U,m,D))
  173. #更新隶属度矩阵
  174. U=update_U(data,Z,n,dim,K,D,m)
  175. #判断阈值
  176. if i!=0 and abs(J[i-1]-J[i])<=error:
  177. break
  178. '''得到聚类结果'''
  179. cluster=Cluster(U,n)
  180. '''返回聚类结果(聚类类别,聚类中心,目标函数值)'''
  181. return cluster,Z,J[-1]
  182. '''主函数'''
  183. if __name__=="__main__":
  184. '''随机产生400组在区间[0,1]上的二维数据'''
  185. data=np.array([[random.uniform(0, 1) for i in range(2)] for j in range(400)])
  186. '''聚类'''
  187. cluster,cntr,J=FCM(data,K=4,Tmax=1000,m=2,error=0.0001)
  188. print("聚类结果:\n{}".format(cluster))
  189. print("目标函数值:\n{}".format(J))
  190. #将数据分类
  191. fdata=data.tolist()
  192. X1=[]
  193. Y1=[]
  194. X2=[]
  195. Y2=[]
  196. X3=[]
  197. Y3=[]
  198. X4=[]
  199. Y4=[]
  200. for i in range(400):
  201. if cluster[i]==0:
  202. X1.append(fdata[i][0])
  203. Y1.append(fdata[i][1])
  204. if cluster[i]==1:
  205. X2.append(fdata[i][0])
  206. Y2.append(fdata[i][1])
  207. if cluster[i]==2:
  208. X3.append(fdata[i][0])
  209. Y3.append(fdata[i][1])
  210. if cluster[i]==3:
  211. X4.append(fdata[i][0])
  212. Y4.append(fdata[i][1])
  213. # 聚类图
  214. plt.scatter(X1, Y1, c='red', marker='o')
  215. plt.scatter([cntr[0][0]], [cntr[0][1]], marker='>', c="black", label='聚类中心1')
  216. plt.scatter(X2, Y2, c='blue', marker="o")
  217. plt.scatter([cntr[1][0]], [cntr[1][1]], marker='<', c="black", label="聚类中心2")
  218. plt.scatter(X3, Y3, c='green', marker="o")
  219. plt.scatter([cntr[2][0]], [cntr[2][1]], marker='^', c="black", label="聚类中心3")
  220. plt.scatter(X4, Y4, c='orange', marker="o")
  221. plt.scatter([cntr[3][0]], [cntr[3][1]], marker="D", c="black", label="聚类中心4")
  222. plt.legend()
  223. plt.xlabel("x")
  224. plt.ylabel("y")
  225. plt.title("聚类图")
  226. plt.show()

三、 使用skfuzzy的python代码

  1. import numpy as np
  2. import random
  3. import skfuzzy as fuzz
  4. import matplotlib.pyplot as plt
  5. plt.rcParams['font.sans-serif']=['SimHei']
  6. plt.rcParams['axes.unicode_minus']=False
  7. '''随机产生400组在区间[0,1]上的二维数据'''
  8. data = np.array([[random.uniform(0,1) for i in range(2)] for j in range(400)])
  9. '''初始化隶属度矩阵(聚成4类)'''
  10. '''
  11. cntr:聚类中心
  12. u:最后的隶属度矩阵
  13. u0:初始化的隶属度矩阵
  14. d:是一个矩阵,记录每一个点到聚类中心的欧式距离
  15. jm:是目标函数的优化历史
  16. p:p是迭代的次数
  17. fpc:全称是fuzzy partition coefficient, 是一个评价分类好坏的指标,它的范围是0到1, 1表示效果最好,后面可以通过它来选择聚类的个数。
  18. '''
  19. cntr, u, u0, d, jm, p, fpc = fuzz.cluster.cmeans(data.T, 4, 2, error=0.0001, maxiter=1000)
  20. '''迭代计算'''
  21. cntr, u, u0, d, jm, p, fpc = fuzz.cluster.cmeans(data.T, 4,2, error=0.0001, maxiter=1000)
  22. '''获得聚类结果'''
  23. cluster_membership = np.argmax(u, axis=0)
  24. '''绘制聚类结果'''
  25. #将数据分类
  26. fdata=data.tolist()
  27. X1=[]
  28. Y1=[]
  29. X2=[]
  30. Y2=[]
  31. X3=[]
  32. Y3=[]
  33. X4=[]
  34. Y4=[]
  35. for i in range(400):
  36. if cluster_membership[i]==0:
  37. X1.append(fdata[i][0])
  38. Y1.append(fdata[i][1])
  39. if cluster_membership[i]==1:
  40. X2.append(fdata[i][0])
  41. Y2.append(fdata[i][1])
  42. if cluster_membership[i]==2:
  43. X3.append(fdata[i][0])
  44. Y3.append(fdata[i][1])
  45. if cluster_membership[i]==3:
  46. X4.append(fdata[i][0])
  47. Y4.append(fdata[i][1])
  48. #聚类图
  49. plt.scatter(X1,Y1,c='red',marker='o')
  50. plt.scatter([cntr[0][0]],[cntr[0][1]],marker='>',c="black",label='聚类中心1')
  51. plt.scatter(X2,Y2,c='blue',marker="o")
  52. plt.scatter([cntr[1][0]],[cntr[1][1]],marker='<',c="black",label="聚类中心2")
  53. plt.scatter(X3,Y3,c='green',marker="o")
  54. plt.scatter([cntr[2][0]],[cntr[2][1]],marker='^',c="black",label="聚类中心3")
  55. plt.scatter(X4,Y4,c='orange',marker="o")
  56. plt.scatter([cntr[3][0]],[cntr[3][1]],marker="D",c="black",label="聚类中心4")
  57. plt.legend()
  58. plt.xlabel("x")
  59. plt.ylabel("y")
  60. plt.title("聚类图")
  61. plt.show()
  62. print(cluster_membership)
  63. '''
  64. print("cntr:\n{}".format(cntr))
  65. print("u:\n{}".format(u))
  66. print("u0:\n{}".format(u0))
  67. print("d:\n{}".format(d))
  68. print("jm:\n{}".format(jm))
  69. print("p:\n{}".format(p))
  70. print("fpc:\n{}".format(fpc))
  71. '''

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/702509
推荐阅读
相关标签
  

闽ICP备14008679号