《Kaggle教程 特征工程》系列课程目录
Kaggle教程 特征工程1 Baseline-Model
Kaggle教程 特征工程2 Categorical Encodings
Kaggle教程 特征工程3 Feature Generation
Kaggle教程 特征工程4 Feature Selection
1. 介绍
现在您已经构建了一个基线模型,您已经准备好使用一些聪明的方法将分类变量转换为数值特征来改进它。这些编码将从数据本身学习。最基本的编码是一次性编码(在中级机器学习课程中介绍过)和标签编码,您在第一个教程中看到过。
在这里,您将学习计数编码、目标编码(和变体)和奇异值分解。
下面是在第一个教程中重建基线模型的代码。
import pandas as pd
from sklearn.preprocessing import LabelEncoder
ks = pd.read_csv('../input/kickstarter-projects/ks-projects-201801.csv',
parse_dates=['deadline', 'launched'])
# Drop live projects
ks = ks.query('state != "live"')
# Add outcome column, "successful" == 1, others are 0
ks = ks.assign(outcome=(ks['state'] == 'successful').astype(int))
# Timestamp features
ks = ks.assign(hour=ks.launched.dt.hour,
day=ks.launched.dt.day,
month=ks.launched.dt.month,
year=ks.launched.dt.year)
# Label encoding
cat_features = ['category', 'currency', 'country']
encoder = LabelEncoder()
encoded = ks[cat_features].apply(encoder.fit_transform)
data_cols = ['goal', 'hour', 'day', 'month', 'year', 'outcome']
baseline_data = ks[data_cols].join(encoded)
# 定义将帮助我们测试编码的函数
import lightgbm as lgb
from sklearn import metrics
def get_data_splits(dataframe, valid_fraction=0.1):
valid_fraction = 0.1
valid_size = int(len(dataframe) * valid_fraction)
train = dataframe[:-valid_size * 2]
# valid size == test size, last two sections of the data
valid = dataframe[-valid_size * 2:-valid_size]
test = dataframe[-valid_size:]
return train, valid, test
def train_model(train, valid):
feature_cols = train.columns.drop('outcome')
dtrain = lgb.Dataset(train[feature_cols], label=train['outcome'])
dvalid = lgb.Dataset(valid[feature_cols], label=valid['outcome'])
param = {'num_leaves': 64, 'objective': 'binary',
'metric': 'auc', 'seed': 7}
print("Training model!")
bst = lgb.train(param, dtrain, num_boost_round=1000, valid_sets=[dvalid],
early_stopping_rounds=10, verbose_eval=False)
valid_pred = bst.predict(valid[feature_cols])
valid_score = metrics.roc_auc_score(valid['outcome'], valid_pred)
print(f"Validation AUC score: {valid_score:.4f}")
return bst
# 根据基线数据训练模型
train, valid, _ = get_data_splits(baseline_data)
bst = train_model(train, valid)
'''
Training model!
Validation AUC score: 0.7467
'''
Count Encoding (数编码)
计数编码将每个分类值替换为它在数据集中出现的次数。例如,如果“GB”值在国家特性中出现了10次,那么每个“GB”都将被数字10代替。
我们将使用category -encodings包来获得这种编码。编码器本身作为CountEncoder可用。这个编码器和其他分类编码的工作原理类似于带有.fit和.transform方法的scikit-learn转换器
import category_encoders as ce
cat_features = ['category', 'currency', 'country']
count_enc = ce.CountEncoder()
count_encoded = count_enc.fit_transform(ks[cat_features])
data = baseline_data.join(count_encoded.add_suffix("_count"))
# Training a model on the baseline data
train, valid, test = get_data_splits(data)
bst = train_model(train, valid)
'''
Training model!
Validation AUC score: 0.7486
'''
添加计数编码特性将验证分数从0.7467提高到0.7486,只有轻微的改进。
Target Encoding (目标编码)
目标编码将类别值替换为该特性值的目标平均值。例如,给定country值“CA”,您将计算country == 'CA’的所有行的平均结果,约为0.28。这通常与整个数据集上的目标概率混合使用,以减少很少出现的值的方差。
这种技术使用目标来创建新特性。因此,在目标编码中包含验证或测试数据将是目标泄漏的一种形式。相反,您应该只从训练数据集中学习目标编码,并将其应用于其他数据集。
category_encoders包提供了用于目标编码的TargetEncoder。实现类似于CountEncoder。
import category_encoders as ce
cat_features = ['category', 'currency', 'country']
# 创建编码器本身
target_enc = ce.TargetEncoder(cols=cat_features)
train, valid, _ = get_data_splits(data)
# 使用分类特征和目标匹配编码器
target_enc.fit(train[cat_features], train['outcome'])
# 转换特性,使用_target后缀重命名列,并连接到dataframe
train = train.join(target_enc.transform(train[cat_features]).add_suffix('_target'))
valid = valid.join(target_enc.transform(valid[cat_features]).add_suffix('_target'))
train.head()
bst = train_model(train, valid)
'''
Training model!
Validation AUC score: 0.7491
'''
验证分数再次升高,从0.7467到0.7491。
CatBoost编码
最后,我们来看看CatBoost编码。这与目标编码相似,因为它基于给定值的目标概率。但是使用CatBoost,对于每一行,目标概率仅从其前面的行计算。
cat_features = ['category', 'currency', 'country']
target_enc = ce.CatBoostEncoder(cols=cat_features)
train, valid, _ = get_data_splits(data)
target_enc.fit(train[cat_features], train['outcome'])
train = train.join(target_enc.transform(train[cat_features]).add_suffix('_cb'))
valid = valid.join(target_enc.transform(valid[cat_features]).add_suffix('_cb'))
bst = train_model(train, valid)
'''
Training model!
Validation AUC score: 0.7492
'''
这比目标编码稍微好一点。
======================================================