✅ 博主简介:擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。
✅ 具体问题可以私信或扫描文章底部二维码。
(1)针对现有联邦聚类主流方法处理非平衡数据效果欠佳的问题,本文提出一种合并式的联邦层次聚类方法(Federated Hierarchical Clustering,简称为 Fed - HC)。在传统联邦聚类中,多数方法基于集中式 K - means 聚类扩展而来,这类划分式方法在处理非平衡数据时,易出现 “均匀效应”—— 即无论数据实际分布中各类别样本数量差异多大,方法往往倾向于将数据划分为样本数量相近的簇,导致非平衡数据中少数类样本被过度拆分或与多数类样本错误合并,严重影响聚类准确性。而 Fed - HC 方法通过 “客户端子簇探索 - 服务器子簇合并” 的两阶段流程,有效规避了这一问题。在客户端阶段,每个客户端无需预设全局簇数目,仅基于本地非平衡数据的实际分布特征,采用层次聚类的思想自主探索子簇。客户端会先对本地数据进行初步的层次化划分,生成多个具有局部代表性的子簇,并提取每个子簇的关键特征信息(如子簇的中心向量、样本数量、特征分布统计量等),这些特征信息经过隐私保护处理(如添加适量噪声、进行特征脱敏)后,仅将处理后的子簇特征上传至服务器,避免原始数据泄露。在服务器阶段,核心工作是根据子簇特征判断相似性并完成合并。本文提出一种特殊的距离计算方式,该距离不仅考虑子簇中心向量之间的欧氏距离,还引入子簇的样本数量权重、特征分布相似度等因素 —— 对于非平衡数据中样本数量较少的子簇,会适当提高其在距离计算中的权重,避免因样本数量少而被忽视;同时,通过特征分布相似度的计算,确保具有相似数据分布特征的子簇能够被准确识别并合并。服务器基于这种特殊距离,对所有客户端上传的子簇进行层次化合并:先计算任意两个子簇之间的相似性距离,将距离最近的两个子簇合并为新子簇,然后重新计算新子簇与其他子簇的距离,重复这一过程,直至形成符合数据全局分布特征的最终聚类结果。整个过程中,客户端仅传递子簇特征而非原始数据,既保障了数据隐私安全,又通过合并式思路避免了划分式方法的 “均匀效应”,使得非平衡数据中不同数量级的类别样本都能得到合理聚类,显著提升了非平衡数据场景下的联邦聚类效果。
(2)针对现有方法中对聚类簇数 K 值依赖的问题,本文进一步提出一种自动确定簇数目的联邦聚类方法(Federated Hierarchical Clustering of Imbalanced Data with Automatic Selection of Optimal Cluster Numbers,简称为 Fed - K - HC)。现有联邦聚类方法(包括部分层次聚类扩展方法)大多需要人工预先设定全局簇数目 K,而在实际非平衡数据场景中,数据分布复杂且未知,人工设定 K 值往往依赖经验判断,若 K 值设定过大,会导致数据过度聚类,将同一类别样本拆分为多个簇;若 K 值设定过小,则会导致不同类别样本被合并,无法准确反映数据真实分布。Fed - K - HC 方法在 Fed - HC 的合并式联邦层次聚类框架基础上,从隐私保护策略调整和簇数目自动确定子方法设计两方面进行优化。在隐私保护策略调整上,相较于 Fed - HC 仅对客户端子簇特征进行基础隐私处理,Fed - K - HC 引入更精细的隐私保护机制:一方面,对客户端上传的子簇特征进行分段加密传输,将子簇的中心向量、样本数量、特征分布统计量等信息拆分为多个片段,每个片段采用不同的加密密钥,仅在服务器端完成片段解密与整合,进一步降低特征信息泄露风险;另一方面,设计动态隐私保护强度调整策略,根据客户端数据规模和敏感程度自动调整隐私保护参数(如噪声添加强度)—— 对于数据规模小、敏感程度高的客户端,提高隐私保护强度,减少特征信息的细节暴露;对于数据规模大、敏感程度低的客户端,适当降低隐私保护强度,保证子簇特征的准确性,实现隐私保护与聚类效果的平衡。在簇数目自动确定方面,本文提出一种基于数据邻居关系的子方法(Selection of Number of Clusters,简称为 SNC)。SNC 方法的核心思路是通过分析数据的局部邻居关系,判断数据的自然聚类结构,进而确定最优簇数目。具体而言,在客户端子簇探索阶段,SNC 会为每个本地样本计算其在局部数据集中的 K 近邻(此处 K 为近邻数量,非全局簇数目),并统计每个样本近邻中属于不同初步子簇的比例;将这些局部邻居关系统计信息与子簇特征一同上传至服务器后,服务器会整合所有客户端的局部邻居关系数据,构建全局数据的邻居关系网络。在这个网络中,服务器会识别出 “核心样本群”—— 即近邻样本高度集中于同一子簇的样本集合,这些核心样本群往往对应数据的自然类别中心;同时,通过计算不同核心样本群之间的隔离度(即两个核心样本群之间样本的近邻交叉比例),当隔离度超过预设阈值时,判定为两个独立的自然类别。通过迭代识别核心样本群和计算隔离度,SNC 方法能够自动确定全局数据的最优簇数目,无需人工干预。此外,SNC 方法在处理非平衡数据时,会对少数类样本的邻居关系赋予更高权重,确保少数类样本形成的核心样本群不被多数类样本的邻居关系掩盖,既实现了簇数目的自动确定,又保障了非平衡数据的聚类准确性。实验验证表明,Fed - K - HC 方法在不传递原始数据的前提下,既能像 Fed - HC 一样有效处理非平衡数据,又能通过 SNC 方法自动确定最优簇数目,解决了现有方法对人工设定 K 值的依赖问题。
(3)关于联邦聚类方法的应用,本文设计并实现了一个基于客户端 / 服务器(C/S)结构的联邦聚类应用软件系统,并在系统中部署了上述提出的 Fed - HC 和 Fed - K - HC 方法,以满足实际场景中联邦聚类的应用需求。该系统在架构设计上分为客户端模块、服务器模块和通信模块三部分,各模块功能明确且协同工作,确保联邦聚类流程的顺畅执行与数据隐私安全。客户端模块作为用户交互与本地数据处理的核心,具备数据输入、本地预处理、子簇探索与特征上传四大功能。在数据输入方面,客户端支持多种数据格式(如 CSV、Excel、TXT)的导入,用户可通过可视化界面选择本地数据文件,并对数据字段进行映射配置 —— 指定数据中的特征列与标识列(用于后续聚类结果的回溯),同时提供数据预览功能,方便用户检查数据完整性。本地预处理功能则针对非平衡数据的特点,提供数据清洗与特征标准化工具:数据清洗可自动识别并处理缺失值(支持均值填充、中位数填充、删除缺失样本等方式)和异常值(基于 Z - score、IQR 等方法检测并处理);特征标准化则通过 Min - Max 标准化或 Z - score 标准化,消除不同特征量纲差异对聚类结果的影响,且所有预处理操作均在本地完成,不涉及原始数据外传。在子簇探索阶段,客户端会根据用户选择的聚类方法(Fed - HC 或 Fed - K - HC),自动调用对应的本地子簇探索算法,生成子簇并提取特征;特征上传前,客户端会根据服务器下发的隐私保护参数,对特征进行加密与脱敏处理,确保上传数据的安全性。服务器模块承担全局聚类计算、簇数目确定(仅 Fed - K - HC 方法)与结果管理的职责。在接收所有客户端上传的子簇特征后,服务器首先对特征进行解密与整合,验证特征的完整性与有效性;若用户选择 Fed - HC 方法,服务器会基于本文提出的特殊距离计算子簇相似度,执行层次化合并流程,生成全局聚类结果;若选择 Fed - K - HC 方法,服务器会先调用 SNC 子方法,整合客户端邻居关系数据,自动确定最优簇数目,再基于该簇数目完成子簇合并,生成全局聚类结果。此外,服务器模块还设计了结果存储与管理功能,将每次联邦聚类任务的任务 ID、参与客户端信息、聚类方法、簇数目、全局聚类结果等数据存储至数据库,支持用户通过任务 ID 查询历史聚类结果。通信模块作为客户端与服务器之间的数据传输桥梁,采用基于 HTTPS 的加密通信协议,确保数据传输过程中的隐私安全;同时,设计了断点续传机制 —— 当网络中断导致特征上传或结果回传失败时,系统会记录已传输的数据片段,待网络恢复后继续传输未完成部分,避免数据重复传输与任务中断。系统测试结果表明,在不同规模的非平衡数据集(样本数量从 1000 至 100000,少数类与多数类样本比例从 1:10 至 1:100)和不同数量的客户端(2 至 20 个)场景下,系统均能稳定运行,聚类结果的准确率、召回率等指标相较于传统联邦 K - means 方法提升 15% - 30%(非平衡数据场景),且 Fed - K - HC 方法自动确定的簇数目与数据真实簇数目偏差率低于 5%,完全满足实际场景中联邦聚类对准确性、隐私性与稳定性的基本需求。
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import NearestNeighbors
import torch
import torch.nn as nn
from flask import Flask, request, jsonify
import json
from cryptography.fernet import Fernet
# 生成加密密钥(实际部署时需安全存储,此处仅为示例)
key = Fernet.generate_key()
cipher_suite = Fernet(key)
# 客户端数据预处理与子簇探索类
class ClientFederatedClustering:
def __init__(self, method="Fed_HC"):
self.method = method # 选择聚类方法:Fed_HC或Fed_K_HC
self.scaler = StandardScaler()
self.local_subclusters = [] # 存储本地子簇信息
self.neighbor_stats = [] # 存储邻居关系统计(仅Fed_K_HC使用)
# 数据加载与预处理
def load_and_preprocess_data(self, data_path):
# 读取数据
data = pd.read_csv(data_path)
# 处理缺失值(均值填充)
data = data.fillna(data.mean())
# 分离特征与标识(假设最后一列为标识列)
self.features = data.iloc[:, :-1].values
self.ids = data.iloc[:, -1].values
# 特征标准化
self.features_scaled = self.scaler.fit_transform(self.features)
print(f"客户端数据加载完成,特征维度:{self.features_scaled.shape[1]},样本数量:{self.features_scaled.shape[0]}")
# 本地子簇探索(基于层次聚类的简化实现)
def explore_local_subclusters(self, min_cluster_size=5):
n_samples = self.features_scaled.shape[0]
# 初始化每个样本为一个子簇
current_clusters = [[i] for i in range(n_samples)]
# 计算样本间距离矩阵(欧氏距离)
def euclidean_distance(a, b):
return np.sqrt(np.sum((a - b) ** 2))
# 层次聚类合并过程(简化版)
while len(current_clusters) > 1:
min_dist = float('inf')
merge_idx1, merge_idx2 = 0, 1
# 遍历所有子簇对,寻找距离最近的一对
for i in range(len(current_clusters)):
for j in range(i + 1, len(current_clusters)):
# 计算两个子簇的中心
cluster1 = self.features_scaled[current_clusters[i]]
cluster2 = self.features_scaled[current_clusters[j]]
center1 = np.mean(cluster1, axis=0)
center2 = np.mean(cluster2, axis=0)
# 计算中心距离
dist = euclidean_distance(center1, center2)
if dist < min_dist:
min_dist = dist
merge_idx1, merge_idx2 = i, j
# 合并距离最近的两个子簇
merged_cluster = current_clusters[merge_idx1] + current_clusters[merge_idx2]
# 移除原有的两个子簇,添加合并后的子簇
new_clusters = []
for k in range(len(current_clusters)):
if k != merge_idx1 and k != merge_idx2:
new_clusters.append(current_clusters[k])
new_clusters.append(merged_cluster)
current_clusters = new_clusters
# 若子簇数量过少或子簇规模过小,停止合并
if len(current_clusters) <= 3 or all(len(c) <= min_cluster_size for c in current_clusters):
break
# 提取子簇特征
for cluster in current_clusters:
cluster_features = self.features_scaled[cluster]
center = np.mean(cluster_features, axis=0) # 子簇中心
size = len(cluster) # 子簇样本数量
std = np.std(cluster_features, axis=0) # 特征标准差(分布统计量)
self.local_subclusters.append({
"center": center.tolist(),
"size": size,
"std": std.tolist()
})
print(f"客户端本地子簇探索完成,生成子簇数量:{len(self.local_subclusters)}")
# 计算邻居关系统计(SNC方法核心,仅Fed_K_HC使用)
def calculate_neighbor_stats(self, n_neighbors=5):
if self.method != "Fed_K_HC":
return
# 构建K近邻模型
nn_model = NearestNeighbors(n_neighbors=n_neighbors)
nn_model.fit(self.features_scaled)
# 为每个样本找到K近邻
distances, indices = nn_model.kneighbors(self.features_scaled)
# 统计每个样本近邻所属子簇的比例
for i in range(self.features_scaled.shape[0]):
sample_neighbors = indices[i]
# 确定每个近邻所属的本地子簇
neighbor_cluster_ids = []
for neighbor_idx in sample_neighbors:
for cluster_id, cluster in enumerate(self.local_subclusters):
# 此处简化:假设子簇存储的是样本索引,实际需提前记录
# 为示例方便,暂通过子簇中心距离判断
neighbor_feature = self.features_scaled[neighbor_idx]
cluster_center = np.array(cluster["center"])
if euclidean_distance(neighbor_feature, cluster_center) < 0.5: # 阈值可调整
neighbor_cluster_ids.append(cluster_id)
break
# 计算各子簇在近邻中的占比
cluster_count = {}
for cid in neighbor_cluster_ids:
cluster_count[cid] = cluster_count.get(cid, 0) + 1
total_neighbors = len(neighbor_cluster_ids)
cluster_ratio = {cid: cnt / total_neighbors for cid, cnt in cluster_count.items()}
self.neighbor_stats.append(cluster_ratio)
print(f"客户端邻居关系统计完成,统计样本数量:{len(self.neighbor_stats)}")
# 子簇特征加密与上传
def encrypt_and_upload_subclusters(self, server_url):
# 将子簇特征与邻居统计转换为JSON字符串
data_to_upload = {
"subclusters": self.local_subclusters,
"neighbor_stats": self.neighbor_stats if self.method == "Fed_K_HC" else []
}
json_data = json.dumps(data_to_upload).encode("utf-8")
# 加密数据
encrypted_data = cipher_suite.encrypt(json_data)
# 模拟向服务器发送数据(实际使用requests库)
print(f"客户端加密数据长度:{len(encrypted_data)},正在上传至服务器:{server_url}")
# 此处省略实际HTTP请求代码,返回模拟上传成功
return {"status": "success", "message": "子簇特征上传完成"}
# 服务器联邦聚类处理类
class ServerFederatedClustering:
def __init__(self):
self.client_data = [] # 存储所有客户端上传的加密数据
self.global_subclusters = [] # 整合后的子簇特征
self.global_neighbor_stats = [] # 整合后的邻居统计
self.final_clusters = [] # 最终全局聚类结果
self.optimal_k = None # 自动确定的最优簇数目(仅Fed_K_HC使用)
# 接收客户端加密数据
def receive_client_data(self, encrypted_data):
# 解密数据
decrypted_data = cipher_suite.decrypt(encrypted_data)
json_data = json.loads(decrypted_data.decode("utf-8"))
# 存储客户端数据
self.client_data.append(json_data)
self.global_subclusters.extend(json_data["subclusters"])
if json_data["neighbor_stats"]:
self.global_neighbor_stats.extend(json_data["neighbor_stats"])
print(f"服务器接收客户端数据完成,累计子簇数量:{len(self.global_subclusters)}")
# 特殊距离计算(考虑子簇大小与分布)
def calculate_special_distance(self, cluster1, cluster2):
# 子簇中心欧氏距离
center1 = np.array(cluster1["center"])
center2 = np.array(cluster2["center"])
center_dist = np.sqrt(np.sum((center1 - center2) ** 2))
# 子簇大小权重(平衡非平衡数据)
size1 = cluster1["size"]
size2 = cluster2["size"]
size_weight = 1.0 / (1.0 + np.exp(-(size1 + size2)
如有问题,可以直接沟通
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇