隔离林需要拆分数据吗?

Ali*_*sef 6 python machine-learning pandas scikit-learn jupyter-notebook

我有一个由 10049972 行 x 19 列组成的数据库。我使用隔离森林来检测异常值,然后创建了一个额外的列,将异常值设置为 -1,我删除了所有包含异常值的行为 -1,然后删除了该列。

我的问题是:我是否需要训练、测试和验证隔离森林才能工作?另外有人可以确认我的代码是否有效吗?

这是我的代码。

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

%matplotlib inline

from sklearn.ensemble import IsolationForest


df = pd.read_csv('D:\\Project\\database\\4-Final\\Final After.csv',low_memory=True)


iForest = IsolationForest(n_estimators=100,  contamination=0.1 , random_state=42, max_samples=200)


iForest.fit(df.values.reshape(-1,1))

pred = iForest.predict(df.values.reshape(-1,1))

pred=df['anomaly']

df=df.drop(df['anomaly'==-1],inplace=True)

df.to_csv('D:\\Project\\database\\4-Final\\IF TEST.csv', index=False) 
Run Code Online (Sandbox Code Playgroud)

谢谢你。

Nok*_*oki 4

我的问题是我是否需要进行测试训练和验证才能使隔离林发挥作用?

您只想检测这个批处理文件中的异常值,对吧? 在这种情况下,你的解决方案可能没问题, 但大多数情况下,你必须分裂。

但请尝试了解您何时需要进行拆分。为了解释这一点,让我们进入一个真实的案例场景。

假设您正在尝试预测不同引擎的异常行为。您使用数据库中截至“今天”的可用数据创建模型,并开始预测传入数据。预测数据可能不等于用于训练的数据,对吧?那么,在配置模型时如何模拟这种情况呢?使用训练-测试-验证并使用正确的指标进行评估。

编辑:让我添加一个例子。我会尽力让它变得超级简单。

如果您的引擎数据库数据是:

+----+-------------+--------------+
| id | engine_type | engine_value |
+----+-------------+--------------+
|  1 |           0 | 0.25         |
|  2 |           0 | 0.40         |
|  3 |           1 | 0.16         |
|  4 |           1 | 0.30         |
|  5 |           0 | 5.3          | <- anomaly
|  6 |           1 | 14.4         | <- anomaly
|  7 |           0 | 16.30        | <- anomaly
+----+-------------+--------------+
Run Code Online (Sandbox Code Playgroud)

并用它全部来训练模型,模型将使用这三个异常值来训练,对吧?该算法将使用这 3 个异常值创建森林,因此模型可以更轻松地预测它们。

现在,这个生产数据会发生什么:

+----+-------------+--------------+
| id | engine_type | engine_value |
+----+-------------+--------------+
|  8 |           1 | 3.25         | <- anomaly
|  9 |           1 | 4.40         | <- anomaly
| 10 |           0 | 2.16         |
+----+-------------+--------------+
Run Code Online (Sandbox Code Playgroud)

你将它传递给你的模型,它会说这些点不是异常的,而是正常数据,因为它认为你的“阈值”是大于 5 的值。

这个“阈值”是算法超参数的乘积,也许使用其他配置,模型可以将值预测为异常,但您没有测试模型泛化

那么如何改进这个配置呢?分割您当时可用的数据。您可以只使用其中的一部分进行训练,然后使用另一部分进行测试,例如使用这部分作为训练数据,而不是使用所有数据库数据进行训练:

+----+-------------+--------------+
| id | engine_type | engine_value |
+----+-------------+--------------+
|  1 |           0 | 0.25         |
|  2 |           0 | 0.40         |
|  3 |           1 | 0.16         |
|  4 |           1 | 0.30         |
|  7 |           0 | 16.30        | <- anomaly
+----+-------------+--------------+
Run Code Online (Sandbox Code Playgroud)

这是测试数据:

+----+-------------+--------------+
| id | engine_type | engine_value |
+----+-------------+--------------+
|  5 |           0 | 5.3          | <- anomaly
|  6 |           1 | 14.4         | <- anomaly
+----+-------------+--------------+
Run Code Online (Sandbox Code Playgroud)

并设置超参数组合,使该算法能够正确预测测试数据。它能确保未来的预测是完美的吗?不,不是,但这与仅拟合数据而不评估模型的泛化能力不同。

另外有人可以确认我的代码是否有效吗?

是的,但让我添加一条建议,更改此设置:

iForest.fit(df.values.reshape(-1,1))

pred = iForest.predict(df.values.reshape(-1,1))

pred=df['anomaly']
Run Code Online (Sandbox Code Playgroud)

对此:

df['anomaly'] = iForest.fit_predict(df.values.reshape(-1,1))
Run Code Online (Sandbox Code Playgroud)

另外,如果您使用新的 pandas 版本,请使用:

df['anomaly'] = iForest.fit_predict(df.to_numpy().reshape(-1,1))
Run Code Online (Sandbox Code Playgroud)

  • 2. 阈值不仅由用于训练的数据定义,而且还使用超参数。如果您设置 10 棵树而不是默认的 100 棵树,则生成的阈值将会不同。目标是了解最佳树数,然后使用所有可用数据和最佳树数来训练算法。 (2认同)