CatBoost - 处理缺失值

缺失值意味着数据集中某些数据不可用。这种情况可能出于不同的原因,例如收集数据时出现错误或故意遗漏某些信息。要建立准确的预测模型,我们必须谨慎管理它们。在数据集中,典型的缺失值以两种方式表示,如下所述:

  • NaN(非数字):在数字数据集中,NaN 通常用于表示缺失或未定义的值。IEEE 标准定义了 NaN,这是一种特定的浮点值,经常用于 Python 等编程语言和 NumPy 等库中。

  • NULL 或 NA:在数据库系统和统计软件中,NULL 或 NA 可用于识别缺失值。这些只是表示特定观察缺乏数据的占位符。

通过处理缺失值实现 CatBoost

CatBoost 可以自行处理缺失值,因此您不必自己修复它们。以​​下是它的工作原理和使用方法 −

1. 安装 CatBoost 库

首先,您必须确保已安装 CatBoost 库。如果未安装,则可以使用以下命令安装它 −

pip install catboost

2. 导入库

安装后,您可以在模型中使用 CatBoost。因此,请在代码中导入必要的库,如 NumPy、Pandas、Matplotlib、Seaborn 和 SKlearn 等,如下所示 −

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from catboost import CatBoostRegressor, Pool
from sklearn.metrics import mean_absolute_error, r2_score
from sklearn.model_selection import train_test_split

3. 加载数据集

现在我们从系统目录加载一个数据集,这里我们使用房价数据集来实现模型。然后,我们将其分为训练集和测试集,并准备分类特征以在训练期间提供给 CatBoost。

# 加载数据集
data = pd.read_csv('/Python/Datasets/train.csv')
# 选择特征和目标变量
features = data.columns.difference(['SalePrice']) # 除 'SalePrice' 之外的所有列
target = 'SalePrice'

# 将分类特征更改为字符串
categorical_features = data[features].select_dtypes(include=['object']).columns
for feature in categorical_features:
    data[feature] = data[feature].astype(str)

# 将数据拆分为特征和目标
X = data[features]
y = data[target]

# 将数据拆分为训练和测试数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 找出分类特征
categorical_features_indices = np.where(X.dtypes == 'object')[0]

此代码加载并准备房价数据集以进行建模。它将类别数据转换为字符串。然后将数据分成两部分:特征 (X) 和目标 (Y)。之后,将数据分成两组:训练 (80%) 和测试 (20%)。CatBoost 使用变量 categorical_features_indices 来找出哪些特征是分类的,从而允许它在训练期间正确管理它们。

探索性数据分析

探索性数据分析 (EDA) 使我们能够更深入地了解数据集。

检查缺失值

这与本章非常相关,并且对任何数据集都很有用。如果缺失值处理不当,它们会对模型的预测产生影响。在这里,我们将看到数据集中哪些列有缺失值以及总数。

# 检查缺失值
missing_values = data.isnull().sum().sort_values(ascending=False)
missing_values = missing_values[missing_values > 0]
print("
缺失值列:
", missing_values)

输出

这是模型的结果 −

Missing Values Columns:
 PoolQC              1453
MiscFeature     1406
Alley                  1369
Fence                1179
FireplaceQu     690
LotFrontage      259
GarageYrBlt       81
GarageCond     81
GarageType      81
GarageFinish    81
GarageQual      81
BsmtFinType2    38
BsmtExposure   38
BsmtQual           37
BsmtCond          37
BsmtFinType1     37
MasVnrArea        8
MasVnrType         8
Electrical              1
dtype: int64

为了检查"数据"DataFrame 中的缺失值,此代码将每列的空值相加。然后打印列的相关计数,但仅针对缺失值大于零的列。这是通过根据缺失数据量按降序排列列来实现的。

CatBoost 处理不平衡类

许多现实世界的应用程序依赖于不平衡的数据集,例如欺诈检测、医疗诊断和收入损失预测。在这些情况下,一个类与另一个类相比被大大忽视。这种差距可能导致模型偏向主导类,从而导致少数类性能低下。

CatBoost 中处理不平衡数据的方法

CatBoost 有几种内置解决方案来处理不平衡数据集。这包括 −

  • 自动类别权重

  • 平衡准确度指标

  • 过采样或欠采样

  • 使用 scale_pos_weight 参数

  • 提前停止

让我们看一个真实的例子,了解如何使用 CatBoost 处理不平衡数据集,然后测试其性能。我们将使用合成数据集来评估不同方法的有效性。

自动类别权重

您可以为不同的类别分配不同的权重,以便为少数类别赋予更多权重。这可以通过使用 CatBoost class_weights 参数来实现,这有助于模型更多地关注少数类别。

catboost_params = {
   'iterations': 500,
   'learning_rate': 0.05,
   'depth': 6,
   'loss_function': 'Logloss',
   # Higher weight for minority class   
   'class_weights': [1, 10]  
}
model = CatBoostClassifier(**catboost_params)
model.fit(X_train, y_train)

平衡准确度指标

使用针对不均匀数据进行调整的评估方法非常重要。平衡准确度指标考虑了两个类别,可用于评估模型。

from sklearn.metrics importbalanced_accuracy_score

y_pred = model.predict(X_test)
balanced_acc =balanced_accuracy_score(y_test, y_pred)
print("平衡准确度:",balanced_acc)

过采样或欠采样

在训练模型之前,您可以对少数类进行过采样或对多数类进行欠采样以平衡数据集。合成少数类过采样技术是一种可用于为少数类创建合成样本的技术。

from imblearn.over_sampling import SMOTE

sm = SMOTE()
X_resampled, y_resampled = sm.fit_resample(X_train, y_train)

model = CatBoostClassifier(iterations=500, learning_rate=0.05,depth=6)
model.fit(X_resampled, y_resampled)

使用 scale_pos_weight 参数

当数据集非常不平衡时,此参数非常有用。它基本上调整少数类的损失函数以减少不平衡。

catboost_params = {
   'iterations': 500,
   'learning_rate': 0.05,
   'depth': 6,
   'loss_function': 'Logloss',
   # Increase for the minority class
   'scale_pos_weight': 10  
}
model = CatBoostClassifier(**catboost_params)
model.fit(X_train, y_train)

提前停止

在高度不平衡的数据集中,提前停止对于防止模型过度拟合多数类非常有帮助。

model = CatBoostClassifier(iterations=500, learning_rate=0.05, depth=6)
model.fit(X_train, y_train, eval_set=(X_val, y_val), early_stopping_rounds=50)