有个同学给我两篇论文
《基于聚类集成的特征选择方法研究_李玥》
《基于基聚类器对齐的聚类集成方法研究_杨康》,
基于相似度的方法跟他讲了一遍他自己复现好了,但是他觉得他的数据集有几万条,时间和空间复杂度太高,就让我帮他实现一下重标记法
原理参见这篇写的很好的博文《学习笔记2-聚类集成方法》
这里实现的的是其中的7.4.2硬标记对应法
import numpy as np
from copy import deepcopy
import pandas as pd
# 假设聚成3类
K = 3
# 样本量为7条
sample_nums = 7
model1 = np.array([1,1,2,2,3,3,1])
# 方便后面用下标去等价类别,这里让类别也从0开始,后面操作同义
model1 -= 1
model2 = np.array([2,2,3,3,1,1,2]) - 1
model3 = np.array([1,1,2,2,2,3,3]) - 1
model4 = np.array([2,3,3,2,2,1,1]) - 1
model_to_do_list = [model2, model3, model4] # 作为原数据
model_done_list = deepcopy(model_to_do_list) # 作为改动数据,这里使用deepcopy深层复制一份,防止干扰原数据
# 创建一个种类数*种类数的矩阵O_mat
O_mat = np.zeros((K, K))
model_i = model1 # 这里定死model_i就是model1
for model_idx in range(len(model_to_do_list)):
# model_to_do_list[model_idx]就是model_j原模型数据
# 在原模型数据上遍历,用于记录model_i的 第i_cls类 与model_j的第j_cls类的共同样本数
# 对于模型i的种类遍历
for i_cls in range(K): # 注意range是 [) 左闭右开
# 对于模型j的种类遍历
for j_cls in range(K):
# 取模型i属于第i_cls类的样本下标的集合,flatten将数据打平(可以不打平看看是什么结果)
model1_set = set(np.argwhere(model_i==i_cls).flatten()) # {0,1}
# 取模型i属于第i_cls类的样本下标的集合
model2_set = set(np.argwhere(model_to_do_list[model_idx]==j_cls).flatten()) # {1}
# 对集合取交集则为共同样本,取长度则为共同样本数
O_mat[i_cls][j_cls] = len(model1_set & model2_set) # 交集{1}, 长度为1
print(f"初始O_mat = n{O_mat}")
# 当O_mat不是∅空集时,一直循环进行重标记
while (O_mat == np.zeros((K, K))).sum() != K*K:
# 获取O_mat中最大的值的坐标
u, v = np.unravel_index(np.argmax(O_mat), O_mat.shape)
print(f"O_mat = n{O_mat}n, 现在的argmax坐标为(u,v)=({u},{v})")
# 将模型j的第j_cls类(即v)改为第i_cls类(即u)
# 先从原模型数据中得到要修改的索引
to_modify_idx = np.argwhere(model_to_do_list[model_idx]==v)
# 修改改动模型数据的对应索引
model_done_list[model_idx][to_modify_idx] = u
# 第u行和第v列都删除,不用再找了,记为0即可
O_mat[u] = 0
O_mat[:, v] = 0
# 转为pandas的dataframe
bagging_mat = pd.DataFrame(data=np.array([model1, *model_done_list]))
# 取每列的众数作为投票结果
classify_group = bagging_mat.mode().values[0]
print(classify_group)
参考:
Numpy中返回下标操作函数
TODO:留个坑,有时间把基于相似度的实现掉



