模糊c均值聚類的python實現
存在的問題:
用來判斷終止條件的變數dist,是前後兩次隸屬度矩陣的對應元素做差,取絕對值,再取最大值。用鳶尾花資料集的話,dist的值最低只能到小數點後兩位,但是網上別的**能達到小數點後6、7位。
但是標準互資訊指數nmi的值相差不大,都在0.74左右。
import numpy as np
from sklearn import metrics
import time
def read_txt(path, delimiter=','):
data = np.loadtxt(path, delimiter=delimiter)
n_row, n_col = data.shape
n_col = n_col - 1
y = np.array(data[:, -1], dtype=np.int)
x = data[:, 0:n_col]
return x, y
def random_membership_matrix(n_sample, k):
# 初始化乙個隸屬度矩陣
membership_matrix = np.zeros((n_sample, k), dtype=np.float)
for i in range(n_sample):
temp = np.random.random(k) # 生成k個隨機浮點數
temp = temp / sum(temp)
membership_matrix[i] = temp
return membership_matrix
def iterate(x, u, k, m):
# 停止條件來自:
# 前後兩次隸屬度矩陣對應元素做差,差的最大值不超過某一閾值
n_sample, dim = x.shape
# 先把前一次的隸屬度矩陣存起來
old_u = np.array(u)
ter = 0.0000001 # 閾值
iteration = 0
dist = float('inf')
max_iter = 20 # 最大迭代次數,這個次數之內達不到閾值,就得重新隨機隸屬度矩陣了
center = np.zeros((k, dim), dtype=np.float) # 類中心,每行存乙個類中心
# 滿足最小閾值,或者達到最大迭代次數時停止
while dist > ter and iteration < max_iter:
iteration = iteration + 1
# 根據隸屬度矩陣求中心
for i in range(k):
up = np.zeros((dim,), dtype=np.float)
down = 0.0
for j in range(n_sample):
up += np.power(u[j, i], m) * x[j]
down += np.power(u[j, i], m)
center[i] = up / down
# 根據中心求隸屬度矩陣
for p in range(n_sample):
for q in range(k):
down = 0.0
up = np.power(np.linalg.norm(x[p] - center[q]), -2/(m-1))
for e in range(k):
down += np.power(np.linalg.norm(x[p] - center[e]), -2/(m-1))
u[p, q] = up / down
# 求終止條件
dist = (abs(u - old_u)).max()
return center, u
def cluster(membership_matrix):
# 根據隸屬度求聚類結果,把樣本點歸到隸屬度最大的類
n_sample = membership_matrix.shape[0]
y_pred = np.zeros((n_sample,), dtype=np.int)
for i in range(n_sample):
y_pred[i] = np.argmax(membership_matrix[i])
return y_pred
if __name__ == '__main__':
k = 3
m = 2
filename = 'iris'
x, y = read_txt('./dataset/' + filename + '.txt')
n_sample, dim = x.shape
# 多跑幾次取最好結果
best_y_pred = np.zeros((n_sample,), dtype=np.int)
best_nmi = 0.0
center = np.zeros((k, dim), dtype=np.float)
for d in range(10):
print('**********第%d次隨機隸屬度矩陣**********' % d)
membership_matrix = random_membership_matrix(n_sample, k)
center, membership_matrix = iterate(x, membership_matrix, k, m)
y_pred = cluster(membership_matrix)
nmi = metrics.normalized_mutual_info_score(y, y_pred)
if nmi > best_nmi:
best_nmi = nmi
best_y_pred = y_pred
print('best_nmi: %f' % best_nmi)
print(center)
模糊C均值聚類
模糊c均值聚類 fcm 即眾所周知的模糊isodata,是用隸屬度確定每個資料點屬於某個聚類的程度的一種聚類演算法。1973年,bezdek提出了該演算法,作為早期硬c均值聚類 hcm 方法的一種改進。fcm把n個向量x i i 1,2,n 分為c個模糊組,並求每組的聚類中心,使得非相似性指標的價值...
模糊c均值聚類
fcm演算法是一種基於劃分的聚類演算法,它的思想就是使得被劃分到同一簇的物件之間相似度最大,而不同簇之間的相似度最小。模糊c均值演算法是普通c均值演算法的改進,普通c均值演算法對於資料的劃分是硬性的,而fcm則是一種柔性的模糊劃分。在介紹fcm具體演算法之前我們先介紹一些模糊集合的基本知識。6.1....
模糊C均值聚類原理
fcm演算法是一種基於劃分的聚類演算法,它的思想就是使得被劃分到同一簇的物件之間相似度最大,而不同簇之間的相似度最小。模糊c均值演算法是普通c均值演算法的改進,普通c均值演算法對於資料的劃分是硬性的,而fcm則是一種柔性的模糊劃分。硬聚類把每個待識別的物件嚴格的劃分某類中,具有非此即彼的性質,而模糊...