WEBKT

深入理解 Isolation Forest:核心超参调优与实战案例

19 0 0 0

1. Isolation Forest 算法原理回顾

2. 核心超参数详解

2.1 n_estimators:森林中树的数量

2.2 max_samples:每棵树使用的样本数量

2.3 contamination:数据集中异常点的比例

3. 信用卡欺诈检测案例实战

3.1 数据准备

3.2 模型训练与评估(初始设置)

3.3 超参数调优:网格搜索

3.4 超参数调优:手动调整

4. 总结与最佳实践

大家好,我是老K,今天咱们聊聊异常检测领域的一个明星算法——Isolation Forest(孤立森林)。这玩意儿特别好用,尤其是在处理高维数据和大规模数据集的时候。它不仅速度快,而且效果还不错,简直是异常检测的利器。

今天,咱们不玩虚的,就来点硬核的。我会带你深入理解 Isolation Forest 的核心超参数,比如 n_estimatorsmax_samplescontamination,它们对模型性能的影响以及如何选择和调整它们。同时,我还会结合一个信用卡欺诈检测的案例,手把手教你如何通过网格搜索和手动调整这些参数来优化模型性能。

准备好了吗?咱们这就开始!

1. Isolation Forest 算法原理回顾

在深入探讨超参数之前,咱们先简单回顾一下 Isolation Forest 的基本原理,这样你才能更好地理解这些参数的作用。

Isolation Forest 的核心思想是:异常点通常是那些更容易被“孤立”的点。想象一下,你有一堆数据点,正常的数据点通常会聚集在一起,而异常点则会散落在数据空间的边缘。

Isolation Forest 通过构建随机的决策树(Isolation Trees)来“孤立”这些点。对于每个数据点,算法会计算它在所有 Isolation Trees 中的平均路径长度。异常点通常路径长度较短,因为它们更容易被划分到叶子节点。

具体来说,Isolation Forest 的构建过程如下:

  1. 随机选择特征: 在每个节点上,随机选择一个特征。
  2. 随机选择分割点: 在选定的特征的取值范围内,随机选择一个分割点。
  3. 构建树: 按照选定的特征和分割点,将数据划分到左子树或右子树,重复上述过程,直到满足停止条件(例如,树的深度达到最大深度,或者节点只包含一个样本)。
  4. 计算异常分数: 对于每个样本,计算它在所有 Isolation Trees 中的平均路径长度。路径长度越短,异常分数越高。

2. 核心超参数详解

现在,咱们来深入了解 Isolation Forest 的三个核心超参数:n_estimatorsmax_samplescontamination

2.1 n_estimators:森林中树的数量

n_estimators 表示 Isolation Forest 中 Isolation Trees 的数量。这个参数控制了森林的规模,也就是模型的复杂度。一般来说,n_estimators 越大,模型越稳定,结果越可靠。但是,增加 n_estimators 也会增加训练时间和内存消耗。

  • 影响:
    • 模型稳定性: 增加 n_estimators 可以提高模型的稳定性,减少结果的方差。因为更多的树可以提供更全面的数据分割,降低了单个树的随机性对最终结果的影响。
    • 计算成本: 增加 n_estimators 会增加计算成本,包括训练时间和预测时间。对于大规模数据集,需要权衡计算成本和模型性能。
  • 选择策略:
    • 经验法则: 通常,n_estimators 的取值范围在 100 到 1000 之间。你可以从一个较小的值开始,例如 100 或 200,然后逐渐增加,观察模型性能的变化。
    • 交叉验证: 使用交叉验证来评估不同 n_estimators 值下的模型性能。选择在验证集上表现最好的值。
    • 网格搜索: 使用网格搜索来自动搜索最佳的 n_estimators 值。这可以帮助你找到一个在计算成本和模型性能之间取得平衡的值。

2.2 max_samples:每棵树使用的样本数量

max_samples 表示每棵 Isolation Tree 使用的样本数量。这个参数控制了每棵树的训练数据量,进而影响了树的深度和结构。

  • 影响:
    • 树的深度: 较小的 max_samples 值会导致树更浅,异常检测速度更快,但可能不够准确。较大的 max_samples 值会导致树更深,异常检测可能更准确,但也会增加计算成本。
    • 模型泛化能力: 较小的 max_samples 值可以提高模型的泛化能力,降低过拟合的风险。因为每棵树只使用一小部分样本进行训练,可以减少对特定样本的依赖。
  • 选择策略:
    • 经验法则: max_samples 的取值范围可以从 0.1 到 1.0(相对于总样本数的比例),或者直接指定具体的样本数量。通常,可以尝试使用 0.5 或 0.7 作为初始值。
    • 数据量: 如果数据集非常大,可以减小 max_samples 的值,以减少计算成本。如果数据集较小,可以增加 max_samples 的值,以提高模型性能。
    • 网格搜索: 同样,可以使用网格搜索来找到最佳的 max_samples 值。

2.3 contamination:数据集中异常点的比例

contamination 表示数据集中异常点的比例。这个参数是 Isolation Forest 最重要的参数之一,因为它直接影响了模型的异常检测结果。你需要根据你的业务场景和数据情况,来估计这个比例。

  • 影响:
    • 阈值设置: contamination 用于设置异常点的阈值。Isolation Forest 会根据这个比例,将分数高于阈值的样本标记为异常点。
    • 预测结果: contamination 的值直接影响了预测结果的准确性。如果 contamination 设置得过高,模型可能会将正常点误判为异常点;如果 contamination 设置得过低,模型可能会漏掉一些异常点。
  • 选择策略:
    • 业务理解: 了解你的业务场景,估计异常点的比例。例如,在信用卡欺诈检测中,欺诈交易的比例通常很小,可能只有 0.1% 到 1%。
    • 数据分析: 分析你的数据,例如通过可视化方法,来观察异常点的分布情况。这可以帮助你估计 contamination 的值。
    • 交叉验证: 使用交叉验证,并结合评估指标(例如,F1-score, ROC AUC)来选择最佳的 contamination 值。尝试不同的 contamination 值,观察模型在验证集上的表现。
    • 经验法则: 如果你对数据集中异常点的比例一无所知,可以尝试 0.01、0.05 或 0.1 作为初始值。

3. 信用卡欺诈检测案例实战

现在,咱们来通过一个信用卡欺诈检测的案例,来演示如何调整这些超参数。这个案例会让你更直观地理解这些参数的作用,以及如何通过实际操作来优化模型性能。

3.1 数据准备

首先,咱们需要准备一些信用卡交易数据。这里,咱们使用一个公开的信用卡欺诈检测数据集,你可以在 Kaggle 上找到它。这个数据集包含了大量的信用卡交易记录,其中一小部分是欺诈交易。

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import IsolationForest
from sklearn.metrics import classification_report, roc_auc_score
from sklearn.model_selection import GridSearchCV
# 加载数据
df = pd.read_csv('creditcard.csv')
# 数据预处理
# 移除 'Time' 列,因为它对欺诈检测没有太大帮助
df = df.drop('Time', axis=1)
# 分割特征和标签
X = df.drop('Class', axis=1)
y = df['Class']
# 分割训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print(f'训练集形状: {X_train.shape}')
print(f'测试集形状: {X_test.shape}')
# 检查数据集中异常点的比例
print(f'原始数据中异常点的比例: {y.value_counts(normalize=True)}')

这段代码完成了以下几个步骤:

  1. 加载数据: 使用 pd.read_csv 加载信用卡交易数据集。
  2. 数据预处理: 移除 Time 列,因为它对欺诈检测没有太大帮助。
  3. 分割特征和标签: 将数据分成特征 (X) 和标签 (y)。
  4. 分割训练集和测试集: 使用 train_test_split 将数据分成训练集和测试集。
  5. 打印数据集的形状和异常点比例: 方便我们后续分析和调参。

3.2 模型训练与评估(初始设置)

接下来,咱们使用默认参数训练一个 Isolation Forest 模型,并评估其性能。

# 创建 Isolation Forest 模型
model = IsolationForest(random_state=42)
# 训练模型
model.fit(X_train)
# 预测异常分数
y_pred = model.decision_function(X_test)
# 根据contamination设置阈值,将预测分数转换为二分类结果
threshold = -0.04 # 根据实际情况调整
y_pred_binary = (y_pred < threshold).astype(int)
# 评估模型
print(classification_report(y_test, y_pred_binary))
print(f'ROC AUC: {roc_auc_score(y_test, -y_pred)}')

在这段代码中,咱们:

  1. 创建模型: 创建一个 Isolation Forest 模型,并设置 random_state 以确保结果可复现。
  2. 训练模型: 使用训练集 X_train 训练模型。
  3. 预测异常分数: 使用 decision_function 方法预测测试集 X_test 中每个样本的异常分数。
  4. 设置阈值并转换为二分类结果: 因为 contamination 参数在训练时使用,而评估时需要二分类结果,所以这里根据 contamination 估计的异常比例,手动设置阈值,将预测分数转换为二分类结果(0 表示正常,1 表示异常)。阈值的设置非常关键,需要根据具体情况调整。如果模型预测的异常分数偏高,可以适当降低阈值;反之,则提高阈值。
  5. 评估模型: 使用 classification_reportroc_auc_score 来评估模型的性能。classification_report 提供了更详细的指标,例如精确率、召回率和 F1-score,而 roc_auc_score 则衡量了模型区分异常点和正常点的能力。

3.3 超参数调优:网格搜索

现在,咱们使用网格搜索来优化模型的超参数。网格搜索是一种系统地搜索超参数空间的方法,它可以帮助你找到最佳的超参数组合。

# 定义超参数的搜索空间
param_grid = {
'n_estimators': [100, 200, 300],
'max_samples': [0.5, 0.7, 1.0],
'contamination': [0.001, 0.01, 0.05]
}
# 创建 Isolation Forest 模型
model = IsolationForest(random_state=42)
# 创建 GridSearchCV 对象
grid_search = GridSearchCV(model, param_grid, scoring='roc_auc', cv=3, n_jobs=-1)
# 在训练集上进行网格搜索
grid_search.fit(X_train, y_train)
# 打印最佳参数和最佳得分
print(f'最佳参数: {grid_search.best_params_}')
print(f'最佳 ROC AUC: {grid_search.best_score_}')
# 使用最佳模型进行预测
best_model = grid_search.best_estimator_
y_pred = best_model.decision_function(X_test)
# 根据contamination设置阈值,将预测分数转换为二分类结果
threshold = -0.04 # 根据实际情况调整
y_pred_binary = (y_pred < threshold).astype(int)
# 评估模型
print(classification_report(y_test, y_pred_binary))
print(f'ROC AUC: {roc_auc_score(y_test, -y_pred)}')

这段代码做了以下几件事:

  1. 定义超参数搜索空间: 使用字典 param_grid 定义了需要搜索的超参数及其取值范围。这里,咱们搜索了 n_estimatorsmax_samplescontamination 这三个参数。
  2. 创建 GridSearchCV 对象: 创建一个 GridSearchCV 对象,用于执行网格搜索。scoring='roc_auc' 指定了评估指标为 ROC AUC,cv=3 指定了交叉验证的折数,n_jobs=-1 使用所有 CPU 核心进行并行计算,加快搜索速度。
  3. 执行网格搜索: 使用 fit 方法在训练集上进行网格搜索。GridSearchCV 会尝试所有超参数的组合,并使用交叉验证来评估每个组合的性能。
  4. 打印最佳参数和最佳得分: 使用 best_params_ 属性获取最佳的超参数组合,使用 best_score_ 属性获取最佳的 ROC AUC 分数。
  5. 使用最佳模型进行预测和评估: 使用 best_estimator_ 属性获取最佳模型,并使用它在测试集上进行预测和评估。评估过程与之前的初始设置部分相同。

3.4 超参数调优:手动调整

除了网格搜索,你还可以手动调整超参数。这需要你对 Isolation Forest 的原理和超参数的作用有深入的理解。通过观察模型在不同超参数设置下的表现,你可以逐步优化模型性能。

# 尝试手动调整超参数
n_estimators = 200
max_samples = 0.7
contamination = 0.01
# 创建 Isolation Forest 模型
model = IsolationForest(n_estimators=n_estimators, max_samples=max_samples, contamination=contamination, random_state=42)
# 训练模型
model.fit(X_train)
# 预测异常分数
y_pred = model.decision_function(X_test)
# 根据contamination设置阈值,将预测分数转换为二分类结果
threshold = -0.04 # 根据实际情况调整
y_pred_binary = (y_pred < threshold).astype(int)
# 评估模型
print(classification_report(y_test, y_pred_binary))
print(f'ROC AUC: {roc_auc_score(y_test, -y_pred)}')

在这段代码中,咱们:

  1. 手动设置超参数: 直接设置了 n_estimatorsmax_samplescontamination 的值。这些值可以是你通过网格搜索获得的,也可以是你根据业务理解和数据分析得出的。
  2. 创建模型、训练模型、预测异常分数、转换为二分类结果和评估模型: 这些步骤与之前的初始设置部分相同。

通过手动调整超参数,你可以更灵活地控制模型,并根据实际情况进行优化。这需要你对模型有更深入的理解,并不断尝试和调整。

4. 总结与最佳实践

Isolation Forest 是一个强大的异常检测算法,但要充分发挥它的潜力,你需要深入理解它的核心超参数。通过本文的讲解和案例实战,相信你已经对 n_estimatorsmax_samplescontamination 的作用有了更深刻的理解。

以下是一些最佳实践,可以帮助你更好地使用 Isolation Forest:

  • 数据预处理: 确保你的数据经过适当的预处理,例如缺失值处理、特征缩放等。数据质量对模型性能至关重要。
  • 业务理解: 深入了解你的业务场景,尤其是异常点的比例。这有助于你选择合适的 contamination 值。
  • 交叉验证: 使用交叉验证来评估模型性能,并选择最佳的超参数组合。
  • 评估指标: 使用多种评估指标,例如精确率、召回率、F1-score 和 ROC AUC,来全面评估模型性能。
  • 手动调整: 不要完全依赖自动化方法,例如网格搜索。尝试手动调整超参数,并根据实际情况进行优化。
  • 可视化: 使用可视化工具来观察异常点的分布情况,这有助于你更好地理解模型的结果。

希望这篇文章对你有所帮助。如果你有任何问题,欢迎在评论区留言,咱们一起交流学习!

感谢阅读!

希望这篇文章能够帮助你更好地理解和使用 Isolation Forest。 记住,理论知识很重要,但实践更重要。多动手尝试,才能真正掌握这些知识!

祝你在异常检测的道路上越走越远!

老K Isolation Forest异常检测超参数调优机器学习信用卡欺诈

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/8870