代价敏感学习是一种针对数据不均衡问题的机器学习方法,它通过给不同类别的样本赋予不同的代价或权重,以便更好地处理数据不均衡情况。代价敏感学习方法可以在模型训练过程中考虑到不同类别样本的重要性,从而提高模型对少数类样本的识别能力。
一、代价敏感支持向量机,决策树,逻辑回归,随机森林
sklearn库中支持向量机、决策树、逻辑回归和随机森林等函数有相应的代价敏感参数设置,或者也可人为根据数据比例设置权重矩阵。
# 生成不均衡数据集
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
X, y = make_classification(n_samples=1000, n_features=20, n_informative=2, n_redundant=10,
random_state=42) # 生成一个分类问题的数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 划分训练集和测试集
from numpy import mean
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.svm import SVC # 可使用上述其他模型如随机森林、逻辑回归等
# 1、人为根据数据比例设置权重
weights = {0:1.0, 1:100.0} #少数类别与多数类别比为1:100,人为设置权重矩阵
model = SVC(gamma='scale', class_weight= weights)
# 2、使用函数balanced 代价敏感参数
model = SVC(gamma='scale', class_weight='balanced') # 'balanced' 为函数内置的代价敏感参数
# 使用五折交叉建立验证模型
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# 模型评估
scores = cross_val_score(model, X, y, scoring='roc_auc', cv=cv, n_jobs=-1)
print('Mean ROC AUC: %.3f' % mean(scores))
二、Ada-Cost 代价敏感
Ada-Cost是基于AdaBoost算法的一种改进版本,专门用于处理数据不均衡问题。Ada-Cost通过给不同类别的样本分配不同的代价权重,使得模型更加关注少数类样本,从而提高模型对少数类样本的识别能力。
import numpy as np
from sklearn.ensemble import AdaBoostClassifier
from sklearn.utils import check_random_state
# 定义Ada-Cost函数,基于AdaBoostClassifier库
class AdaCostClassifier(AdaBoostClassifier):
def __init__(self, base_estimator=None, n_estimators=50, learning_rate=1.,
algorithm='SAMME.R', random_state=None, cost_matrix=None):
super().__init__(base_estimator, n_estimators, learning_rate, algorithm, random_state)
self.cost_matrix = cost_matrix
def fit(self, X, y, sample_weight=None):
if sample_weight is None:
sample_weight = np.ones(y.shape, dtype=np.float64)
if self.cost_matrix is not None:
n_classes = len(np.unique(y))
cost_per_class = self.cost_matrix.sum(axis=1)
avg_cost = cost_per_class.mean()
for i in range(n_classes):
sample_weight[y == i] *= avg_cost / cost_per_class[i]
return super().fit(X, y, sample_weight)
# 定义代价矩阵,假设类0的误分类代价为1,类1的误分类代价为100
cost_matrix = np.array([[1, 100], [100, 1]])
ada_cost = AdaCostClassifier(random_state=42, cost_matrix=cost_matrix)
ada_cost.fit(X_train, y_train)
y_pred = ada_cost.predict(X_test)
accuracy = (y_pred == y_test).mean()
print(f"Accuracy: {accuracy}")
三、元代价
元代价(MetaCost)是一种代价敏感学习的方法,用于将普通的分类器转化为代价敏感的分类器。在元代价方法中,我们通过修改样本的标签和权重来反映误分类的代价。
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# 定义代价矩阵,假设类0的误分类代价为1,类1的误分类代价为100
cost_matrix = np.array([[1, 100], [100, 1]]) # 示例代价矩阵,根据实际情况调整
# 计算每个类别的平均误分类代价
avg_cost_per_class = cost_matrix.sum(axis=1) / cost_matrix.shape[1]
cost_weights = avg_cost_per_class[y_train]
model = LogisticRegression(max_iter=1000, random_state=42)
model.fit(X_train, y_train, sample_weight=cost_weights)
y_pred = base_classifier.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy}")
代价敏感学习方法可以有效地应对数据不均衡问题,但需要根据具体情况选择合适的方法,并在训练和验证过程中进行调参和评估,以确保模型的性能和泛化能力。