本文目录导读:

的模糊粗糙自监督学习(Fuzzy-Rough Self-Supervised Learning),这是一种结合模糊逻辑和粗糙集理论的自监督学习方法。
核心概念架构
import numpy as np
from sklearn.mixture import GaussianMixture
from sklearn.decomposition import PCA
from scipy.spatial.distance import cdist
from typing import List, Tuple, Dict
import warnings
warnings.filterwarnings('ignore')
class FuzzyRoughSelfSupervised:
"""模糊粗糙自监督学习器"""
def __init__(self, n_clusters: int = 5, fuzzy_threshold: float = 0.3):
self.n_clusters = n_clusters
self.fuzzy_threshold = fuzzy_threshold
self.membership_matrix = None
self.lower_approximation = None
self.upper_approximation = None
模糊隶属度计算
class FuzzyMembership:
"""模糊隶属度计算"""
@staticmethod
def calculate_membership(X: np.ndarray, centers: np.ndarray, m: float = 2.0) -> np.ndarray:
"""
计算模糊C均值隶属度矩阵
Args:
X: 数据矩阵 (n_samples, n_features)
centers: 聚类中心 (n_clusters, n_features)
m: 模糊指数(通常为2)
Returns:
隶属度矩阵 (n_samples, n_clusters)
"""
n_samples = X.shape[0]
n_clusters = centers.shape[0]
# 计算距离矩阵
distances = cdist(X, centers)
# 避免除零
distances = np.maximum(distances, 1e-10)
# 模糊隶属度计算
membership = np.zeros((n_samples, n_clusters))
for i in range(n_samples):
for j in range(n_clusters):
sum_term = 0
for k in range(n_clusters):
ratio = (distances[i, j] / distances[i, k]) ** (2/(m-1))
sum_term += ratio
membership[i, j] = 1.0 / sum_term if sum_term > 0 else 0
return membership
@staticmethod
def gaussian_membership(X: np.ndarray, mean: np.ndarray, std: np.ndarray) -> np.ndarray:
"""高斯型隶属度函数"""
return np.exp(-0.5 * ((X - mean) / (std + 1e-10)) ** 2)
粗糙集近似计算
class RoughSetApproximation:
"""粗糙集上下近似计算"""
@staticmethod
def compute_approximations(membership: np.ndarray,
threshold: float = 0.5) -> Tuple[np.ndarray, np.ndarray]:
"""
计算上下近似
Args:
membership: 隶属度矩阵
threshold: 阈值
Returns:
lower_approx: 下近似矩阵
upper_approx: 上近似矩阵
"""
# 下近似:完全属于某类的样本
lower_approx = (membership >= (1 - threshold)).astype(float)
# 上近似:可能属于某类的样本
upper_approx = (membership >= threshold).astype(float)
# 边界区域:上下近似的差
boundary = upper_approx - lower_approx
return lower_approx, upper_approx, boundary
@staticmethod
def compute_roughness(membership: np.ndarray,
lower_approx: np.ndarray) -> float:
"""计算粗糙度"""
n_samples, n_clusters = membership.shape
roughness = 0
for j in range(n_clusters):
# 粗糙度 = 1 - |下近似| / |上近似|
lower_count = np.sum(lower_approx[:, j])
upper_count = np.sum(lower_approx[:, j]) + np.sum(
(membership[:, j] > 0) & (lower_approx[:, j] == 0)
)
if upper_count > 0:
cluster_roughness = 1 - lower_count / upper_count
roughness += cluster_roughness
return roughness / n_clusters
自监督训练核心
class FuzzyRoughSelfTraining:
"""模糊粗糙自监督训练"""
def __init__(self, n_clusters: int = 5, fuzzy_threshold: float = 0.3):
self.n_clusters = n_clusters
self.fuzzy_threshold = fuzzy_threshold
self.fuzzy_membership = FuzzyMembership()
self.rough_approx = RoughSetApproximation()
def create_pseudo_labels(self, X: np.ndarray,
centers: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
"""
创建伪标签和置信度
Returns:
pseudo_labels, confidence_scores, uncertainty_mask
"""
# 计算模糊隶属度
membership = self.fuzzy_membership.calculate_membership(X, centers)
# 计算粗糙近似
lower, upper, boundary = self.rough_approx.compute_approximations(
membership, self.fuzzy_threshold
)
# 生成伪标签(选择最大隶属度)
pseudo_labels = np.argmax(membership, axis=1)
# 计算置信度(基于上下近似)
confidence = np.zeros(X.shape[0])
for i in range(X.shape[0]):
if np.any(lower[i] > 0): # 属于下近似
confidence[i] = 1.0
elif np.any(upper[i] > 0): # 属于上近似但不在下近似
confidence[i] = 0.5
else: # 不确定样本
confidence[i] = 0.1
# 不确定性掩码
uncertainty_mask = np.any(boundary > 0, axis=1)
return pseudo_labels, confidence, uncertainty_mask
def train_step(self, X: np.ndarray, labels: np.ndarray,
lr: float = 0.01) -> np.ndarray:
"""
训练步骤
Args:
X: 输入数据
labels: 当前标签
lr: 学习率
Returns:
更新后的聚类中心
"""
# 计算各分类中心
centers = np.zeros((self.n_clusters, X.shape[1]))
for k in range(self.n_clusters):
mask = labels == k
if np.sum(mask) > 0:
centers[k] = np.mean(X[mask], axis=0)
else:
centers[k] = X[np.random.randint(len(X))]
# 创建伪标签
pseudo_labels, confidence, _ = self.create_pseudo_labels(X, centers)
# 加权更新(置信度高的样本贡献更大)
weighted_centers = np.zeros_like(centers)
for k in range(self.n_clusters):
mask = pseudo_labels == k
if np.sum(mask) > 0:
weights = confidence[mask]
weighted_centers[k] = np.average(X[mask], weights=weights, axis=0)
# 平滑更新
centers = lr * weighted_centers + (1 - lr) * centers
return centers
端到端训练框架
class FuzzyRoughSelfSupervisedLearner:
"""完整的模糊粗糙自监督学习器"""
def __init__(self, n_epochs: int = 100, n_clusters: int = 5,
fuzzy_threshold: float = 0.3, learning_rate: float = 0.05):
self.n_epochs = n_epochs
self.n_clusters = n_clusters
self.fuzzy_threshold = fuzzy_threshold
self.learning_rate = learning_rate
self.trainer = FuzzyRoughSelfTraining(n_clusters, fuzzy_threshold)
self.history = {
'loss': [],
'roughness': [],
'confidence': []
}
def extract_features(self, text_files: List[str]) -> np.ndarray:
"""
从文本文件提取特征
使用TF-IDF或词嵌入
"""
from sklearn.feature_extraction.text import TfidfVectorizer
import os
# 读取文件内容
documents = []
for file_path in text_files:
with open(file_path, 'r', encoding='utf-8') as f:
documents.append(f.read())
# TF-IDF特征提取
vectorizer = TfidfVectorizer(max_features=1000, stop_words='english')
features = vectorizer.fit_transform(documents).toarray()
# 降维以加速
pca = PCA(n_components=50)
features_reduced = pca.fit_transform(features)
return features_reduced
def train(self, X: np.ndarray) -> Dict:
"""
训练模型
Args:
X: 输入数据矩阵 (n_samples, n_features)
Returns:
训练历史
"""
# 初始化聚类中心
idx = np.random.choice(len(X), self.n_clusters, replace=False)
centers = X[idx].copy()
for epoch in range(self.n_epochs):
# 创建伪标签
pseudo_labels, confidence, uncertainty = self.trainer.create_pseudo_labels(
X, centers
)
# 更新中心
centers = self.trainer.train_step(X, pseudo_labels, self.learning_rate)
# 计算粗糙度
membership = self.trainer.fuzzy_membership.calculate_membership(X, centers)
lower, upper, boundary = self.trainer.rough_approx.compute_approximations(
membership, self.fuzzy_threshold
)
roughness = self.trainer.rough_approx.compute_roughness(membership, lower)
# 记录历史
self.history['roughness'].append(roughness)
self.history['confidence'].append(np.mean(confidence))
# 计算损失(模糊C均值目标函数)
m = 2.0
distances = cdist(X, centers)
distances = np.maximum(distances, 1e-10)
loss = np.sum(membership ** m * distances ** 2)
self.history['loss'].append(loss)
if epoch % 10 == 0:
print(f"Epoch {epoch}: Loss={loss:.4f}, "
f"Roughness={roughness:.4f}, "
f"Confidence={np.mean(confidence):.4f}")
self.centers_ = centers
self.labels_ = pseudo_labels
self.confidence_ = confidence
return self.history
def predict(self, X: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
"""预测新数据"""
membership = self.trainer.fuzzy_membership.calculate_membership(
X, self.centers_
)
labels = np.argmax(membership, axis=1)
confidence = np.max(membership, axis=1)
return labels, confidence
使用示例
# 使用示例
if __name__ == "__main__":
# 生成模拟数据(实际使用时应替换为文件内容)
from sklearn.datasets import make_blobs
# 创建模拟文件内容特征
X, y_true = make_blobs(n_samples=1000, n_features=50,
centers=5, random_state=42)
# 创建学习器
learner = FuzzyRoughSelfSupervisedLearner(
n_epochs=50,
n_clusters=5,
fuzzy_threshold=0.3,
learning_rate=0.05
)
# 训练
history = learner.train(X)
# 预测新数据
X_test, _ = make_blobs(n_samples=100, n_features=50,
centers=5, random_state=24)
labels, confidence = learner.predict(X_test)
print(f"\n预测完成!")
print(f"预测标签分布: {np.bincount(labels)}")
print(f"平均置信度: {np.mean(confidence):.4f}")
关键特性
- 模糊处理:使用模糊C均值处理不确定性
- 粗糙集:上下近似处理边界样本
- 自监督:自动生成伪标签进行训练
- 置信度评估:提供每个预测的置信度分数
这种方法特别适合处理:
- 标签噪声多的数据集
- 类别边界模糊的文本数据
- 需要不确定性估计的场景