孤立森林排除“异常值”可以提高模型效能的论证
排除异常值可以让数据集的分布相对更加集中,更有利于算法的拟合,所以,设想是适当地去掉异常值,可以提高模型的效能。
为了证明以上的设想,使用两个数据集来分别在排除异常值前后构建模型并评估效能。
结果
第一个数据集效能降了;第二个数据集效能持平
结论
孤立森林排除异常值对提高模型效能似乎并没有作用,看来起初的猜想有些想当然了,后者还是要具体考察。
讨论
说实话,在验证之前我觉得排除异常值应该能够提高模型效能,并且是十拿九稳的,结果确实出乎意料,一时还真想不到什么样的理由来解释这个事情。
一种可能性是,数据集不存在异常值,因为孤立森林是按照比例删除数据,或许是降低了样本量导致效能下降。
另一种可能性,数据量过小,如果原始数据集本身的数据量就比较小,使用孤立森林排除异常值可能会进一步减少有效数据量,导致模型可学习的信息不足,无法充分捕捉数据的特征和规律,进而影响模型的效能。但是使用的两个数据集分别是900和300,应该算不上很小。
附:相关的代码
一、排除“异常值”前
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import RFE
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report
# 对object类型数据进行编码
categorical_cols = data.select_dtypes(include=['object']).columns
for col in categorical_cols:le = LabelEncoder()data[col] = le.fit_transform(data[col])# 划分特征和目标变量
X = data.drop('HeartDisease', axis=1)
y = data['HeartDisease']# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)rf = RandomForestClassifier(n_estimators=100, random_state=42)# 使用选择的特征进行建模和预测rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print('使用选择的特征的模型准确率:', accuracy)
#使用选择的特征的模型准确率: 0.8804347826086957
二、排除“异常值”
from sklearn.ensemble import IsolationForest# # 对object类型数据进行编码
# categorical_cols = data.select_dtypes(include=['object']).columns
# for col in categorical_cols:
# le = LabelEncoder()
# data[col] = le.fit_transform(data[col])# 初始化 Isolation Forest 模型
isolation_forest = IsolationForest(n_estimators=100, contamination=0.05, random_state=42)# 拟合模型并预测异常值
data['is_outlier'] = isolation_forest.fit_predict(data)# 去除异常值
data_cleaned = data[data['is_outlier'] == 1].drop('is_outlier', axis=1)print('原始数据行数和列数:', data.shape)
print('去除异常值后数据的行数和列数:', data_cleaned.shape)
三、排除“异常值后”
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score# 划分特征和目标变量
X = data_cleaned.drop('HeartDisease', axis=1)
y = data_cleaned['HeartDisease']# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
#
# 创建随机森林分类器
rf = RandomForestClassifier(n_estimators=100, random_state=42)# 在训练集上训练模型
rf.fit(X_train, y_train)# 在测试集上进行预测
y_pred = rf.predict(X_test)# 计算准确率
accuracy = accuracy_score(y_test, y_pred)print(f'随机森林模型的准确率:{accuracy:.2%}')
#随机森林模型的准确率:85.71%