第一部分:不均衡学习
1. 引言
定义与重要性
- 不均衡数据集:指数据集中不同类别的数据数量差异很大,通常是正负样本比例严重失衡。例如,在医疗诊断中,患病患者(正样本)远少于健康患者(负样本)。
- 重要性:在许多实际应用中,如医疗诊断、欺诈检测等,少数类样本往往代表重要的情况。忽略少数类可能导致严重后果,例如未能检测出欺诈交易。
2. 不均衡数据处理方法
重采样方法
欠采样(Under-sampling)
- 定义:通过减少多数类样本的数量来平衡数据集。
- 优点:减少数据量,训练速度快。
- 缺点:可能丢失多数类的重要信息。
Python代码示例:
from imblearn.under_sampling import RandomUnderSampler
from sklearn.datasets import make_classification
# 生成一个不均衡数据集
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, weights=[0.9, 0.1], random_state=42)
# 欠采样
rus = RandomUnderSampler(random_state=42)
X_res, y_res = rus.fit_resample(X, y)
print("原始数据集类分布:", dict(zip(*np.unique(y, return_counts=True))))
print("欠采样后类分布:", dict(zip(*np.unique(y_res, return_counts=True))))
运行结果解释:
- 原始数据集中,正负样本比例可能为90:10。
- 经过欠采样后,正负样本比例接近1:1,但可能丢失了多数类的重要信息。
过采样(Over-sampling)
- 定义:通过增加少数类样本的数量来平衡数据集。
- 优点:保留所有多数类信息。
- 缺点:可能导致过拟合,即模型过于拟合训练数据,在新数据上表现不佳。
Python代码示例:
from imblearn.over_sampling import RandomOverSampler
# 过采样
ros = RandomOverSampler(random_state=42)
X_res, y_res = ros.fit_resample(X, y)
print("原始数据集类分布:", dict(zip(*np.unique(y, return_counts=True))))
print("过采样后类分布:", dict(zip(*np.unique(y_res, return_counts=True))))
运行结果解释:
- 原始数据集中,正负样本比例可能为90:10。
- 经过过采样后,正负样本比例接近1:1,但可能导致模型过拟合。
SMOTE(Synthetic Minority Over-sampling Technique)
- 定义:通过生成少数类的合成样本来平衡数据集。
- 算法原理:
- 对于每个少数类样本,随机选择k个最近邻样本,生成新样本。
- 公式:新样本
x
new
=
x
i
+
λ
⋅
(
x
n
n
−
x
i
)
x_{\text{new}} = x_i + \lambda \cdot (x_{nn} - x_i)
xnew=xi+λ⋅(xnn−xi)
- 其中, x i x_i xi 是少数类样本, x n n x_{nn} xnn 是k个最近邻样本之一, λ \lambda λ 是0到1之间的随机数。
Python代码示例:
from imblearn.over_sampling import SMOTE
# 使用SMOTE
smote = SMOTE(random_state=42)
X_res, y_res = smote.fit_resample(X, y)
print("原始数据集类分布:", dict(zip(*np.unique(y, return_counts=True))))
print("SMOTE后类分布:", dict(zip(*np.unique(y_res, return_counts=True))))
运行结果解释:
- 原始数据集中,正负样本比例可能为90:10。
- 经过SMOTE后,正负样本比例接近1:1,并且生成的新样本更具代表性,有助于减轻过拟合。
数据增强技术
- 定义:通过对现有数据进行变换(如旋转、缩放等)增加样本数量,主要用于图像数据。
- 优点:适用于图像数据,增强模型的泛化能力。
- 缺点:需要特定领域知识。
Python代码示例:
from keras.preprocessing.image import ImageDataGenerator
import numpy as np
# 假设我们有一个图像数据集
datagen = ImageDataGenerator(rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, zoom_range=0.2)
# 假设X_train包含我们的图像数据
X_train_augmented = datagen.flow(X_train, batch_size=32)
运行结果解释:
- 数据增强生成了变换后的新图像数据,有助于提高模型在新图像上的性能。
3. 模型评估指标
混淆矩阵(Confusion Matrix)
- 定义:用于评估分类模型性能的矩阵,显示了真实标签与预测标签的对比。
- 元素:
- True Positive (TP):正类预测正确
- True Negative (TN):负类预测正确
- False Positive (FP):负类预测为正类
- False Negative (FN):正类预测为负类
Python代码示例:
from sklearn.metrics import confusion_matrix
# y_true为真实标签,y_pred为预测标签
y_true = [0, 1, 1, 0, 1, 0, 1, 1, 0, 1]
y_pred = [0, 0, 1, 0, 1, 0, 1, 0, 0, 1]
cm = confusion_matrix(y_true, y_pred)
print("混淆矩阵:\n", cm)
运行结果解释:
- 混淆矩阵显示了模型预测的正负样本数量,帮助分析模型性能。例如,模型预测了3个真正类(TP=3)、4个真负类(TN=4)、1个假正类(FP=1)、2个假负类(FN=2)。
精确率(Precision)、召回率(Recall)与F1分数(F1 Score)
- 定义:
- 精确率(Precision):预测为正类样本中实际为正类的比例。
Precision = T P T P + F P \text{Precision} = \frac{TP}{TP + FP} Precision=TP+FPTP - 召回率(Recall):实际为正类样本中预测为正类的比例。
Recall = T P T P + F N \text{Recall} = \frac{TP}{TP + FN} Recall=TP+FNTP - F1分数(F1 Score):精确率和召回率的调和平均值。
F 1 = 2 ⋅ Precision ⋅ Recall Precision + Recall F1 = 2 \cdot \frac{\text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}} F1=2⋅Precision+RecallPrecision⋅Recall
- 精确率(Precision):预测为正类样本中实际为正类的比例。
Python代码示例:
from sklearn.metrics import precision_score, recall_score, f1_score
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)
print(f"精确率: {precision}, 召回率: {recall}, F1分数: {f1}")
运行结果解释:
- 精确率:预测为正类的样本中,实际为正类的比例。例如,如果精确率为0.75,表示模型预测的正类样本中有75%是正确的。
- 召回率:实际为正类的样本中,预测为正类的比例。例如,如果召回率为0.60,表示所有实际为正类的样本中有60%被正确预测为正类。
- F1分数:综合考虑精确率和召回率的指标。如果F1分数为0.67,表示模型在平衡精确率和召回率方面表现较好。
ROC曲线与AUC
- 定义:
- ROC曲线(Receiver Operating Characteristic Curve):在不同阈值下,真阳性率(TPR)对假阳性率(FPR)的绘图。
- AUC(Area Under the Curve):ROC曲线下的面积,表示模型的整体性能。
Python代码示例:
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
# y_proba是预测为正类的概率
y_proba = [0.1, 0.4, 0.35, 0.8, 0.7, 0.6, 0.55, 0.9, 0.45, 0.3]
fpr, tpr, thresholds = roc_curve(y_true, y_proba)
roc_auc = auc(fpr, tpr)
plt.figure()
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()
运行结果解释:
- ROC曲线显示了在不同阈值下的真阳性率和假阳性率。AUC的值越接近1,模型性能越好。如果AUC为0.85,表示模型在区分正负样本方面表现较好。
4. 不均衡学习算法
权重调整方法(Cost-sensitive Learning)
- 定义:通过调整不同类别的权重,使模型在不均衡数据集上表现更好。通常给少数类样本分配更大的权重。
- 公式:损失函数增加类别权重,例如:
Weighted Loss = ∑ i = 1 N w i ⋅ L ( y i , y ^ i ) \text{Weighted Loss} = \sum_{i=1}^{N} w_i \cdot L(y_i, \hat{y}_i) Weighted Loss=i=1∑Nwi⋅L(yi,y^i)
其中, w i w_i wi 是样本的权重。
Python代码示例(以Logistic回归为例):
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(class_weight='balanced')
model.fit(X_train, y_train)
运行结果解释:
- 使用
class_weight='balanced'
时,模型会根据类别的样本数自动调整权重,使模型更好地处理不均衡数据集。
集成方法(Ensemble Methods)
Bagging和Boosting
- 定义:通过组合多个基模型提升模型性能。
- Bagging(Bootstrap Aggregating):通过对数据集进行多次随机采样训练多个模型,然后平均其预测结果。
- Boosting:通过迭代地训练多个弱分类器,每次迭代根据前一轮的错误率调整样本权重。
Python代码示例:
from sklearn.ensemble import BaggingClassifier, GradientBoostingClassifier
bagging_model = BaggingClassifier()
boosting_model = GradientBoostingClassifier()
bagging_model.fit(X_train, y_train)
boosting_model.fit(X_train, y_train)
运行结果解释:
- Bagging和Boosting可以提高模型的稳定性和准确性,尤其是在处理不均衡数据集时效果显著。
Balanced Random Forest
- 定义:对每个决策树的训练样本进行重采样,使各类别均衡。
- Python代码:
from imblearn.ensemble import BalancedRandomForestClassifier
brf = BalancedRandomForestClassifier()
brf.fit(X_train, y_train)
运行结果解释:
- Balanced Random Forest通过在训练每棵树时对数据进行平衡采样,来处理不均衡数据集,提高模型的泛化能力。
EasyEnsemble
- 定义:通过多次欠采样和集成多个分类器处理不均衡数据集。
- Python代码:
from imblearn.ensemble import EasyEnsembleClassifier
ee = EasyEnsembleClassifier()
ee.fit(X_train, y_train)
运行结果解释:
- EasyEnsemble通过多次欠采样来创建多个训练集,并训练多个分类器,最后将这些分类器的结果进行融合,提高模型在不均衡数据集上的表现。
5. 案例研究
- 使用实际数据集(如信用卡欺诈检测):
- 数据预处理
- 使用不均衡学习方法训练模型
- 模型评估与优化
案例代码示例:
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
# 生成一个不均衡数据集
X, y = make_classification(n_samples=10000, n_features=20, n_classes=2, weights=[0.99, 0.01], random_state=42)
# 数据分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 使用SMOTE进行过采样
smote = SMOTE(random_state=42)
X_train_res, y_train_res = smote.fit_resample(X_train, y_train)
# 训练模型
model = RandomForestClassifier(random_state=42)
model.fit(X_train_res, y_train_res)
# 预测与评估
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred))
运行结果解释:
- 使用SMOTE进行过采样后,模型在测试集上的表现得到了显著提高。分类报告中可以看到精确率、召回率和F1分数的提升。
第二部分:异常点检测
1. 引言
定义与重要性
- 异常点检测:识别数据集中与多数数据显著不同的数据点。例如,网络流量中的异常请求或金融交易中的异常行为。
- 重要性:在网络安全、金融监控等领域,检测异常行为有助于预防潜在威胁。
2. 异常点类型
点异常(Point Anomalies)
- 定义:单个数据点与其他数据点显著不同。
- 示例:网络流量中的异常请求。
语境异常(Contextual Anomalies)
- 定义:在特定上下文中异常的数据点。
- 示例:特定时间段内异常的温度读数。
集体异常(Collective Anomalies)
- 定义:多个数据点组合在一起构成异常。
- 示例:连续的异常网络流量。
3. 异常点检测方法
基于统计的方法
Z-score分析
- 定义:基于标准分数检测异常点。标准分数衡量数据点与平均值的偏离程度。
- 公式:
Z = X − μ σ Z = \frac{X - \mu}{\sigma} Z=σX−μ
其中, X X X 是数据点, μ \mu μ 是均值, σ \sigma σ 是标准差。
Python代码示例:
import numpy as np
def detect_outliers_zscore(data, threshold=3):
mean = np.mean(data)
std = np.std(data)
z_scores = [(x - mean) / std for x in data]
return np.where(np.abs(z_scores) > threshold)
data = [10, 12, 14, 15, 16, 100, 18, 19, 20]
outliers = detect_outliers_zscore(data)
print("异常点索引:", outliers)
运行结果解释:
- 输出异常数据点的索引位置。例如,数据集中的100可能被识别为异常点。
盒须图(Box Plot)
- 定义:通过四分位数和IQR检测异常点。IQR是上四分位数和下四分位数的差值。
- Python代码:
import matplotlib.pyplot as plt
data = [10, 12, 14, 15, 16, 100, 18, 19, 20]
plt.boxplot(data)
plt.show()
运行结果解释:
- 盒须图中的离群点代表异常值。例如,图中的100可能被标记为异常值。
基于距离的方法
K-近邻(K-Nearest Neighbors, KNN)
- 定义:基于与最近邻样本的距离检测异常点。
- Python代码:
from sklearn.neighbors import LocalOutlierFactor
# 假设X是您的特征数据
lof = LocalOutlierFactor(n_neighbors=20)
y_pred = lof.fit_predict(X)
outliers = np.where(y_pred == -1)
print("异常点索引:", outliers)
运行结果解释:
- 输出异常数据点的索引位置。KNN基于数据点与其邻居的距离来检测异常点。
密度基异常点检测(DBSCAN)
- 定义:基于样本密度检测异常点。密度较低的区域可能包含异常点。
- Python代码:
from sklearn.cluster import DBSCAN
db = DBSCAN(eps=0.5, min_samples=5).fit(X)
outliers = np.where(db.labels_ == -1)
print("异常点索引:", outliers)
运行结果解释:
- 输出异常数据点的索引位置。DBSCAN通过检测样本的密度来识别异常点。
基于聚类的方法
K-means
- 定义:基于样本到最近聚类中心的距离检测异常点。
- Python代码:
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
distances = kmeans.transform(X).min(axis=1)
outliers = np.where(distances > np.percentile(distances, 95))
print("异常点索引:", outliers)
运行结果解释:
- 输出异常数据点的索引位置。距离聚类中心较远的数据点可能被标记为异常点。
高斯混合模型(Gaussian Mixture Model, GMM)
- 定义:基于样本的似然值检测异常点。似然值较低的样本可能是异常点。
- Python代码:
from sklearn.mixture import GaussianMixture
gmm = GaussianMixture(n_components=3)
gmm.fit(X)
scores = gmm.score_samples(X)
outliers = np.where(scores < np.percentile(scores, 5))
print("异常点索引:", outliers)
运行结果解释:
- 输出异常数据点的索引位置。似然值较低的数据点可能被标记为异常点。
基于机器学习的方法
一类支持向量机(One-Class SVM)
- 定义:通过学习一个分类超平面,将正常样本与异常样本分离。
- Python代码:
from sklearn.svm import OneClassSVM
ocsvm = OneClassSVM(kernel='rbf', gamma=0.001, nu=0.03)
ocsvm.fit(X_train)
y_pred = ocsvm.predict(X_test)
outliers = np.where(y_pred == -1)
print("异常点索引:", outliers)
运行结果解释:
- 输出异常数据点的索引位置。One-Class SVM通过学习一个超平面,将正常样本与异常样本分离。
随机森林(Random Forest)
- 定义:基于多个决策树检测异常点。通过树的结构来识别异常样本。
- Python代码:
from sklearn.ensemble import IsolationForest
iforest = IsolationForest(contamination=0.1)
iforest.fit(X)
y_pred = iforest.predict(X)
outliers = np.where(y_pred == -1)
print("异常点索引:", outliers)
运行结果解释:
- 输出异常数据点的索引位置。Isolation Forest通过多个决策树来检测异常点。
自编码器(Autoencoders)
- 定义:通过神经网络重构输入数据,基于重构误差检测异常点。重构误差较大的样本可能是异常点。
- Python代码:
import tensorflow as tf
from tensorflow.keras import layers
# 定义自编码器
input_dim = X.shape[1]
encoding_dim = input_dim // 2
input_layer = layers.Input(shape=(input_dim,))
encoded = layers.Dense(encoding_dim, activation='relu')(input_layer)
decoded = layers.Dense(input_dim, activation='sigmoid')(encoded)
autoencoder = tf.keras.Model(input_layer, decoded)
autoencoder.compile(optimizer='adam', loss='mse')
# 训练自编码器
autoencoder.fit(X, X, epochs=50, batch_size=32, validation_split=0.1)
# 重构误差
reconstructions = autoencoder.predict(X)
mse = np.mean(np.power(X - reconstructions, 2), axis=1)
outliers = np.where(mse > np.percentile(mse, 95))
print("异常点索引:", outliers)
运行结果解释:
- 输出异常数据点的索引位置。重构误差较大的数据点可能被标记为异常点。
第三部分:实战项目
项目1:信用卡欺诈检测
- 数据预处理:清洗和处理数据,处理缺失值和不均衡数据。
- 使用不均衡学习方法训练模型:使用SMOTE进行过采样,训练随机森林模型。
- 模型评估与优化:使用混淆矩阵、精确率、召回率和F1分数评估模型,调整参数以优化模型性能。
完整案例代码:
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
from imblearn.over_sampling import SMOTE
# 生成一个不均衡数据集
X, y = make_classification(n_samples=10000, n_features=20, n_classes=2, weights=[0.99, 0.01], random_state=42)
# 数据分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 使用SMOTE进行过采样
smote = SMOTE(random_state=42)
X_train_res, y_train_res = smote.fit_resample(X_train, y_train)
# 训练模型
model = RandomForestClassifier(random_state=42)
model.fit(X_train_res, y_train_res)
# 预测与评估
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred))
运行结果解释:
- 使用SMOTE进行过采样后,模型在测试集上的表现得到了显著提高。分类报告中可以看到精确率、召回率和F1分数的提升。
项目2:网络入侵检测
- 数据预处理:清洗和处理数据,处理缺失值。
- 使用异常点检测方法训练模型:使用Isolation Forest进行异常检测。
- 模型评估与优化:使用ROC曲线和AUC评估模型,调整参数以优化模型性能。
完整案例代码:
from sklearn.ensemble import IsolationForest
from sklearn.metrics import roc_auc_score, roc_curve
import matplotlib.pyplot as plt
# 假设X, y是您的特征和标签
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 训练Isolation Forest模型
iforest = IsolationForest(contamination=0.1, random_state=42)
iforest.fit(X_train)
# 预测与评估
y_pred = iforest.predict(X_test)
y_pred = [1 if x == -1 else 0 for x in y_pred] # 将异常点标记为1,正常点标记为0
# 计算AUC
roc_auc = roc_auc_score(y_test, y_pred)
print("AUC:", roc_auc)
# 绘制ROC曲线
fpr, tpr, thresholds = roc_curve(y_test, y_pred)
plt.plot(fpr, tpr, color='blue', label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()
运行结果解释:
- 使用Isolation Forest检测异常点,计算AUC和绘制ROC曲线,评估模型性能。
项目3:设备故障预测
- 数据预处理:清洗和处理数据,处理缺失值。
- 使用不均衡学习和异常点检测方法训练模型:结合SMOTE和Isolation Forest进行处理。
- 模型评估与优化:使用混淆矩阵、精确率、召回率和F1分数评估模型,调整参数以优化模型性能。
完整案例代码:
# 数据预处理和生成
X, y = make_classification(n_samples=10000, n_features=20, n_classes=2, weights=[0.99, 0.01], random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 使用SMOTE进行过采样
smote = SMOTE(random_state=42)
X_train_res, y_train_res = smote.fit_resample(X_train, y_train)
# 训练Isolation Forest模型
iforest = IsolationForest(contamination=0.1, random_state=42)
iforest.fit(X_train_res)
# 预测与评估
y_pred = iforest.predict(X_test)
y_pred = [1 if x == -1 else 0 for x in y_pred] # 将异常点标记为1,正常点标记为0
# 使用混淆矩阵、精确率、召回率和F1分数评估模型
print(classification_report(y_test, y_pred))
运行结果解释:
- 使用SMOTE和Isolation Forest进行设备故障预测,通过评估报告分析模型性能。