Datawhale AI夏令营学习(机器学习)

80 阅读6分钟

机器学习baseline有关内容

#悲伤的事,总有一天,会笑的说出来。
import numpy as np
import pandas as pd
import lightgbm as lgb
from sklearn.metrics import mean_squared_log_error, mean_absolute_error, mean_squared_error
import tqdm
import sys
import os
import gc
import argparse
import warnings
warnings.filterwarnings('ignore')

train = pd.read_csv('./data/train.csv')
test = pd.read_csv('./data/test.csv')

import matplotlib.pyplot as plt
# 不同type类型对应target的柱状图
type_target_df = train.groupby('type')['target'].mean().reset_index()
plt.figure(figsize=(8, 4))
plt.bar(type_target_df['type'], type_target_df['target'], color=['blue', 'green'])
plt.xlabel('Type')
plt.ylabel('Average Target Value')
plt.title('Bar Chart of Target by Type')
plt.show()

specific_id_df = train[train['id'] == '00037f39cf']
plt.figure(figsize=(10, 5))
plt.plot(specific_id_df['dt'], specific_id_df['target'], marker='o', linestyle='-')
plt.xlabel('DateTime')
plt.ylabel('Target Value')
plt.title("Line Chart of Target for ID '00037f39cf'")
plt.show()

specific_id_df = train[train['id'] == '00037f39cf']
plt.figure(figsize=(10, 5))
plt.plot(specific_id_df['dt'], specific_id_df['target'], marker='o', linestyle='-')
plt.xlabel('DateTime')
plt.ylabel('Target Value')
plt.title("Line Chart of Target for ID '00037f39cf'")
plt.show()


def time_model(lgb, train_df, test_df, cols):
    # 训练集和验证集切分
    trn_x, trn_y = train_df[train_df.dt >= 31][cols], train_df[train_df.dt >= 31]['target']
    val_x, val_y = train_df[train_df.dt <= 30][cols], train_df[train_df.dt <= 30]['target']
    # 构建模型输入数据
    train_matrix = lgb.Dataset(trn_x, label=trn_y)
    valid_matrix = lgb.Dataset(val_x, label=val_y)
    # lightgbm参数
    lgb_params = {
        'boosting_type': 'gbdt',
        'objective': 'regression',
        'metric': 'mse',
        'min_child_weight': 5,
        'num_leaves': 2 ** 5,
        'lambda_l2': 10,
        'feature_fraction': 0.8,
        'bagging_fraction': 0.8,
        'bagging_freq': 4,
        'learning_rate': 0.05,
        'seed': 2024,
        'nthread': 16,
        'verbose': -1,
    }
    # 训练模型
    model = lgb.train(lgb_params, train_matrix, 50000, valid_sets=[train_matrix, valid_matrix],
                      categorical_feature=[], verbose_eval=500, early_stopping_rounds=500)
    # 验证集和测试集结果预测
    val_pred = model.predict(val_x, num_iteration=model.best_iteration)
    test_pred = model.predict(test_df[cols], num_iteration=model.best_iteration)
    # 离线分数评估
    score = mean_squared_error(val_pred, val_y)
    print(score)

    return val_pred, test_pred


lgb_oof, lgb_test = time_model(lgb, train, test, train_cols)

# 保存结果文件到本地
test['target'] = lgb_test
test[['id', 'dt', 'target']].to_csv('submit.csv', index=None)


代码精读:

在这段代码中,正在使用Python的几个库来处理和分析一个时间序列数据集,特别是使用了pandas进行数据操作,matplotlib进行数据可视化,以及lightgbm来训练一个梯度提升决策树(Gradient Boosting Decision Tree, GBDT)模型。以下是对代码中关键部分的详细解释:

数据读取

解释
python复制代码
	train = pd.read_csv('./data/train.csv')  

	test = pd.read_csv('./data/test.csv')

这两行代码使用pandasread_csv函数读取训练集和测试集的数据,并分别存储在traintest两个DataFrame对象中。

数据可视化

柱状图

解释
python复制代码
	type_target_df = train.groupby('type')['target'].mean().reset_index()  

	plt.figure(figsize=(8, 4))  

	plt.bar(type_target_df['type'], type_target_df['target'], color=['blue', 'green'])  

	# ...

这段代码首先按type列对train数据集进行分组,并计算每个类型的target平均值。然后,它使用matplotlibbar函数绘制了一个柱状图,展示了不同type的平均target值。这里有一个潜在的问题:color=['blue', 'green']可能不足以覆盖所有可能的type类型(如果type列中有超过两种类型)。

折线图

解释
python复制代码
	specific_id_df = train[train['id'] == '00037f39cf']  

	plt.figure(figsize=(10, 5))  

	plt.plot(specific_id_df['dt'], specific_id_df['target'], marker='o', linestyle='-')  

	# ...

这段代码从train数据集中筛选出id00037f39cf的行,并使用matplotlibplot函数绘制了一个折线图,展示了该ID对应的target值随时间(dt列)的变化。这有助于理解特定ID的target值是如何随时间变化的。

模型训练

time_model函数中,定义了一个用于训练LightGBM模型的函数。不过,函数中的代码片段并未完全展示,但我可以根据已有代码进行解释。

解释
python复制代码
	trn_x, trn_y = train_df[train_df.dt >= 31][cols], train_df[train_df.dt >= 31]['target']  

	val_x, val_y = train_df[train_df.dt <= 30][cols], train_df[train_df.dt <= 30]['target']

这里,根据dt列的值将数据集分为训练集和验证集。具体来说,假设dt列是一个时间序列,且你以某个时间点(这里是31)为界,将之前的数据作为验证集,之后的数据作为训练集。这种划分方式在实际应用中可能不是最优的,因为它假设了时间序列数据的连续性,并且没有考虑数据的随机性。

解释
python复制代码
	train_matrix = lgb.Dataset(trn_x, label=trn_y)  

	valid_matrix = lgb.Dataset(val_x, label=val_y)

这两行代码使用LightGBM的Dataset类将trn_xval_x(特征)以及trn_yval_y(标签)封装成LightGBM模型可识别的格式。

LightGBM参数

解释
python复制代码
	lgb_params = {  

	    'boosting_type': 'gbdt',  

	    'objective': 'regression',  

	    'metric': 'mse',  

	    'min_child_weight': 5,  

	    'num_leaves': 2 ** 5,  

	    # ...  

	}

这里定义了一些LightGBM的参数,包括:

  • boosting_type: 指定了提升类型,这里是梯度提升决策树(GBDT)。
  • objective: 指定了学习任务,这里是回归问题。
  • metric: 评估模型性能的指标,这里使用的是均方误差(MSE)。
  • min_child_weight: 在叶子节点上的最小权重和,用于控制过拟合。
  • num_leaves: 叶子节点的最大数量,影响模型的复杂度和过拟合。

训练模型

python复制代码
	model = lgb.train(lgb_params, train_matrix, 50000, valid_sets=[train_matrix, valid_matrix], categorical_feature=[], callbacks=[lgb.early_stopping(500), lgb.log_evaluation(500)])
  • lgb.train(...): 这是LightGBM的模型训练函数。它接受多个参数来配置训练过程。

  • lgb_params: 这是一个包含LightGBM配置参数的字典,如boosting_typeobjective等。

  • train_matrix: 训练数据的LightGBM数据集对象。

  • 50000: 这是训练的最大迭代次数(即树的数量)。然而,实际停止条件可能会受到早停法(early stopping)的影响。

  • valid_sets=[train_matrix, valid_matrix]: 这里指定了验证集列表。通常,我们只会在列表中包含一个验证集,但这里同时包含了训练集和验证集,这在实际应用中是不常见的,可能是个错误或特殊需求。通常,我们只关心在验证集上的性能。

  • categorical_feature=[]: 指定了哪些特征是分类特征。这里为空列表,表示没有分类特征。

  • callbacks=[...]: 这是一个回调函数列表,用于在训练过程中执行特定操作。这里使用了早停法(early stopping)和日志评估(log evaluation)回调。

    • lgb.early_stopping(500): 如果在最近的500次迭代中,验证集上的性能没有提升,则提前停止训练。
    • lgb.log_evaluation(500): 每500次迭代记录一次评估结果。

预测和评估

解释
python复制代码
	val_pred = model.predict(val_x, num_iteration=model.best_iteration)  

	test_pred = model.predict(test_df[cols], num_iteration=model.best_iteration)  

	score = mean_squared_error(val_pred, val_y)  

	print(score)
  • model.predict(...): 使用训练好的模型进行预测。num_iteration=model.best_iteration确保使用在验证集上表现最好的迭代次数进行预测。
  • mean_squared_error(...): 计算验证集上预测值和真实值之间的均方误差(MSE),用于评估模型性能。

调用模型训练函数和保存结果

解释
python复制代码
	lgb_oof, lgb_test = time_model(lgb, train, test, train_cols)  

	test['target'] = lgb_test  # 这里代码缺失,可能是 test['target'] = lgb_test.flatten() 或类似
  • time_model(...): 调用前面定义的模型训练函数。这里假设train_cols已经定义,并包含了用于训练的所有特征列名。
  • test['target'] = lgb_test: 这行代码意图是将测试集的预测结果赋值给test DataFrame的一个新列'target'。然而,如果lgb_test是一个NumPy数组(通常是这样),它可能是一个二维数组(即使只有一个预测值),因此可能需要使用.flatten()[:, 0]来确保它是一个一维数组,以便正确赋值给DataFrame的列。