一、背景介绍
分类预测是机器学习领域的一个重要分支,旨在根据已有的数据特征将样本划分为不同的类别。在实际应用中,这种分类可以是二分类,如判断用户是否会订阅某项服务,也可以是多分类,如识别图像中的物体类型。本文将以一个二分类任务为例,即预测用户是否会订阅某项服务,来展示整个建模和分析过程。
代码源码:
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn import preprocessing
from sklearn.model_selection import train_test_split, KFold
from sklearn.metrics import roc_auc_score
from lightgbm.sklearn import LGBMClassifier
# 定义一个函数用于将连续的duration列离散化为分组
def bin_duration(df, bins, column):
# 使用pd.cut函数将指定列按照bins切分为不同的区间
df['duration_group'] = pd.cut(df[column], bins, right=False)
# 统计每个区间的频数
time = df['duration_group'].value_counts().sort_index()
# 绘制柱状图展示每个区间的频数占比
plt.figure(figsize=(6, 2), dpi=120)
sns.barplot(x=time.index, y=time, color='royalblue')
# 添加百分比标签
for x_loc, jobs in zip(range(len(time)), time):
plt.text(x_loc, jobs + 2, '{:.1f}%'.format(jobs / sum(time) * 100), ha='center', va='bottom', fontsize=8)
plt.xticks(fontsize=8)
plt.yticks([])
plt.ylabel('')
plt.title('duration_group Distribution', size=8)
sns.despine(left=True)
plt.show()
# 绘制特征的分布图,区分训练集和测试集
def plot_feature_distribution(df, test, Nu_feature, Ca_feature):
# 确保分类特征列表不包含目标列'subscribe'
Ca_feature = [col for col in Ca_feature if col != 'subscribe']
# 分别绘制数值特征和分类特征的分布
plt.figure(figsize=(20, 15))
for i, col in enumerate(Nu_feature, start=1):
sns.kdeplot(df[col], color='red', label='Train', ax=plt.subplot(4, 4, i))
sns.kdeplot(test[col], color='cyan', label='Test', ax=plt.subplot(4, 4, i))
plt.subplot(4, 4, i).set_xlabel(col)
plt.subplot(4, 4, i).set_ylabel('Density')
plt.tight_layout()
plt.show()
plt.figure(figsize=(20, 10))
for j, col in enumerate(Ca_feature, start=1):
sns.countplot(x=df[col], color='red', label='Train', ax=plt.subplot(len(Ca_feature), 1, j))
sns.countplot(x=test[col], color='cyan', label='Test', ax=plt.subplot(len(Ca_feature), 1, j))
plt.subplot(len(Ca_feature), 1, j).set_xlabel(col)
plt.subplot(len(Ca_feature), 1, j).set_ylabel('Count')
plt.tight_layout()
plt.show()
# 对分类特征进行编码
def encode_categorical_features(df, cols):
lb = preprocessing.LabelEncoder()
for col in cols:
df[col] = lb.fit_transform(df[col]) # 将分类特征转换为整数编码
return df
# 准备训练和测试数据集
def prepare_data(df, test, Ca_feature):
# 从训练集中移除ID列、目标列以及所有分类特征列
X = df.drop(columns=['id', 'subscribe'] + Ca_feature)
Y = df['subscribe'] # 提取目标列
# 对测试集进行同样的处理,包括移除ID列和对分类特征进行编码
test = test.drop(columns='id')
test = encode_categorical_features(test, Ca_feature)
# 确保测试集的列与训练集保持一致
test = test[X.columns]
return X, Y, test
# 训练模型并进行预测
def train_model_and_predict(X, Y, test):
# 初始化LGBM分类器
gbm = LGBMClassifier(n_estimators=600, learning_rate=0.01, boosting_type='gbdt',
objective='binary', max_depth=-1,
random_state=2022, metric='auc')
# 初始化结果列表和平均AUC分数
result = []
mean_score = 0
n_folds = 7
kf = KFold(n_splits=n_folds, shuffle=True, random_state=2022)
# K折交叉验证
for train_index, val_index in kf.split(X):
x_train_fold, x_val_fold = X.iloc[train_index], X.iloc[val_index]
y_train_fold, y_val_fold = Y.iloc[train_index], Y.iloc[val_index]
# 在每个折叠上训练模型
gbm_fold = LGBMClassifier(**gbm.get_params()) # 使用当前gbm的参数重新初始化
gbm_fold.fit(x_train_fold, y_train_fold)
# 预测并计算AUC
y_pred = gbm_fold.predict_proba(x_val_fold)[:, 1]
print(f'Validation AUC: {roc_auc_score(y_val_fold, y_pred)}')
mean_score += roc_auc_score(y_val_fold, y_pred) / n_folds
# 使用全部训练数据训练最终模型并预测测试集
y_pred_final = gbm.fit(X, Y).predict_proba(test)[:, 1]
# 结果存储(此处简化为直接使用y_pred_final)
cat_pre = y_pred_final
# 转换预测概率为类别标签并保存
ret = pd.DataFrame(cat_pre, columns=['subscribe'])
ret['subscribe'] = np.where(ret['subscribe'] > 0.5, 'yes', 'no').astype('str')
ret.to_csv('GBM_prediction.csv', index=False)
print(f'Mean Validation AUC: {mean_score}')
if __name__ == "__main__":
# 示例使用过程
bins = [0, 143, 353, 1873, 5149] # 示例bins划分
df = pd.read_csv('train.csv') # 读取训练数据
test = pd.read_csv('test.csv') # 读取测试数据
# 分离数值特征和分类特征
Nu_feature = df.select_dtypes(exclude=['object', 'category']).columns.tolist()
Ca_feature = df.select_dtypes(include=['object', 'category']).columns.tolist()
# 确保分类特征列表不包含'subscribe'
if 'subscribe' in Ca_feature:
Ca_feature.remove('subscribe')
# 绘制特征分布图
plot_feature_distribution(df, test, Nu_feature, Ca_feature)
# 数据预处理
X, Y, test = prepare_data(df, test, Ca_feature)
# 训练模型并预测
train_model_and_predict(X, Y, test)
二、数据准备与初步分析
数据加载与清洗
代码中的pd.read_csv('train.csv')
和pd.read_csv('test.csv')
展示了数据加载的过程。在加载后,数据可能需要进一步的清洗,如处理缺失值、异常值或重复值。您的代码未直接展示清洗步骤,但这是一个重要的预处理环节。
特征分析
通过df.select_dtypes
方法,您成功地将特征分为数值型和分类特征。这是特征分析的重要一步,有助于理解数据的性质并决定后续的处理方法。
三、特征处理与可视化
数值型特征分布
使用sns.kdeplot
对数值型特征进行可视化是一个很好的选择,它可以帮助我们直观地理解数据的分布。不过,对于高维数据或大量特征,可能需要考虑更高效的可视化方法。
分类特征分布
使用sns.countplot
对分类特征进行可视化是一个标准的做法。通过比较训练和测试数据的分布,我们可以检查是否存在类别不平衡的问题。
分箱处理
bin_duration
函数展示了如何对连续型数值特征进行分箱处理。分箱不仅可以简化模型,还可以帮助捕捉非线性关系。然而,分箱的参数(如bins的数量和边界)可能需要通过交叉验证等方法进行调优。
四、特征编码与数据准备
特征编码
您使用了标签编码对分类特征进行处理。虽然标签编码在许多情况下是有效的,但对于某些算法(如基于距离的算法),独热编码可能更合适。此外,对于高基数的分类特征,可以考虑使用特征哈希或特征嵌入等方法来减少维度。
数据划分
在prepare_data
函数中,您对数据进行了划分,但并未直接展示。确保训练集和测试集具有相似的数据分布是非常重要的,可以通过分层抽样等方法来实现。
五、模型构建与训练
模型参数设置
在train_model_and_predict
函数中,您设置了LightGBM模型的参数。这些参数对模型的性能有重大影响,建议通过网格搜索或随机搜索等方法进行调优。
交叉验证
您使用了K折交叉验证来评估模型的性能。这是一个很好的做法,因为它可以帮助我们评估模型的泛化能力。然而,对于大型数据集,可以考虑使用其他高效的交叉验证方法,如留出验证或自助法。
六、模型评估与预测
评估指标
您选择了ROC AUC作为评估指标,这是一个常用的二分类评估指标。然而,根据具体的应用场景,可能还需要考虑其他指标,如准确率、召回率、F1分数等。
预测结果保存
您将预测结果保存为CSV文件,这是一个很好的做法,方便后续的业务应用。但请注意,保存格式和命名应清晰明了,以方便其他人理解和使用。
七、总结与展望
总结
通过对您的代码进行深入分析,我们可以看到整个建模和分析过程的细节和关键点。从数据准备到模型评估,每一步都至关重要。通过合理的特征处理和模型调优,我们可以构建出高效、准确的分类预测模型。
展望
随着数据量的增长和算法技术的进步,我们可以探索更多先进的机器学习算法和技术手段来提高模型的性能和泛化能力。同时,结合业务需求和实际应用场景,不断优化模型的结构和参数设置,以满足不同场景下的分类预测需求。此外,还可以考虑集成多个模型或使用深度学习等方法来进一步提升预测效果。