当构建机器学习模型时,当测试数据(一般近期时间维度)结果与训练、验证数据结果差异较大时,一般认为是模型存在过拟合问题。除此之外,近期的测试数据可能与模型训练数据本身就存在分布的差异,也会导致模型效果的下降。
下面提出一些初步判定模型分布的方法。
一、二分类模型,检查y标签是否存在较大差异,主要观察正样本占比:
# 阳性案件情况对比
print('训练数据:',len(model_train_y))
print('验证数据:',len(model_val_y))
print('测试数据:',len(model_test_y))
print('-----------')
print('训练数据阳性:', model_train_y.sum())
print('验证数据阳性:', model_val_y.sum())
print('测试数据阳性:',model_test_y.sum())
print('-----------')
print('训练数据阳性占比:', model_train_y.sum() / len(model_train_y))
print('验证数据阳性占比:', model_val_y.sum() / len(model_val_y))
print('测试数据阳性占比:',model_test_y.sum() / len(model_test_y))
二、观察入参X指标的分布
通过模型输出重点指标排序情况
# 模型特征重要性输出
clf_v4.feature_importances_
1、对于多类别型指标,直接按照类别画柱状图,观察柱状图差异分布是否存在差异
# 多类别型指标
plt.hist(model_train_x.columns1)
plt.show()
plt.hist(model_val_x.columns1)
plt.show()
plt.hist(model_test_x.columns1)
plt.show()
2、对于0、1的二类别型指标,直接将两类频数相除,观察是否变化较大
print('训练数据出险占比:',model_train.colums1.sum()/len(model_train_x))
print('验证数据出险占比:',model_val.colums1.sum()/len(model_val_x))
print('测试数据出险占比:',model_test.colums1.sum()/len(model_test_x))
3、对于连续型变量,可将变量等距离划分区间,然后统计每个区间频数,画频数柱状图,观察频数柱状图分布变化是否较大
# 柱状图生成函数
def columns_plot(get_column,num):
# 选择需要列表
data_train_plot = model_train_x_v4[[get_column]]
data_val_plot = model_val_x_v4[[get_column]]
data_test_plot = disease_all_data_test[[get_column]]
# 数据排序
data_train_plot.sort_values(by = get_column, ascending = True, inplace = True)
data_val_plot.sort_values(by = get_column, ascending = True, inplace = True)
data_test_plot.sort_values(by = get_column, ascending = True, inplace = True)
# 新建区间列
quantiles = np.linspace(model_train_x_v4[get_column].min()-0.1,
model_train_x_v4[get_column].max()+0.1) / num
data_train_plot['range_label'] = pd.cut(data_train_plot[get_column], bins= quantiles)
data_val_plot['range_label'] = pd.cut(data_val_plot[get_column], bins= quantiles)
data_test_plot['range_label'] = pd.cut(data_test_plot[get_column], bins= quantiles)
# 计算每区间数据频数
result_train = data_train_plot[['range_label']+[get_column]
].groupby('range_label')[get_column].count().reset_index()
result_val = data_val_plot[['range_label']+[get_column]
].groupby('range_label')[get_column].count().reset_index()
result_test = data_test_plot[['range_label']+[get_column]
].groupby('range_label')[get_column].count().reset_index()
# 画区间分布图
plt.bar(result_train.index,result_train[get_column])
plt.show()
plt.bar(result_val.index,result_val[get_column])
plt.show()
plt.bar(result_test.index,result_test[get_column])
plt.show()
# 针对连续型指标调取函数,生成分布图
# 忽略警告信息
import warnings
warnings.filterwarnings("ignore", category=pd.core.common.SettingWithCopyWarning)
# 生成柱状图(colums1表示指标,5000表示生成区间数)
columns_plot(colums1,5000)