2023.8夏令营“用户新增预测”学习笔记(四)

本文介绍了使用Python的sklearn库构建决策树模型,对特征进行重要性可视化,并处理过拟合问题,包括特征预处理、模型复杂度调整和数据读取效率优化。
摘要由CSDN通过智能技术生成

随便记点今天学的

决策树特征重要性可视化

# 导入必要的库
from sklearn.tree import DecisionTreeClassifier
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt  # 绘图库
# 忽略警告
import warnings
warnings.filterwarnings('ignore')
# 解决画图中文字体显示的问题
plt.rcParams['font.sans-serif'] = ['SimSun', 'Times New Roman']  # 汉字字体集
plt.rcParams['font.size'] = 10  # 字体大小
plt.rcParams['axes.unicode_minus'] = False
# 读取训练集和测试集文件
train_data = pd.read_csv('E:/编程/用户新增预测大赛/train.csv')
test_data = pd.read_csv('E:/编程/用户新增预测大赛/test.csv')


# 提取udmap特征,人工进行onehot
def udmap_onethot(d):
    w = np.zeros(9)
    if d == 'unknown':
        return w
    d = eval(d)
    for i in range(1, 10):
        if 'key' + str(i) in d:
            w[i - 1] = d['key' + str(i)]

    return w


train_udmap_df = pd.DataFrame(np.vstack(train_data['udmap'].apply(udmap_onethot)))
test_udmap_df = pd.DataFrame(np.vstack(test_data['udmap'].apply(udmap_onethot)))
train_udmap_df.columns = ['key' + str(i) for i in range(1, 10)]
test_udmap_df.columns = ['key' + str(i) for i in range(1, 10)]

# 编码udmap是否为空
train_data['udmap_isunknown'] = (train_data['udmap'] == 'unknown').astype(int)
test_data['udmap_isunknown'] = (test_data['udmap'] == 'unknown').astype(int)

# udmap特征和原始数据拼接
train_data = pd.concat([train_data, train_udmap_df], axis=1)
test_data = pd.concat([test_data, test_udmap_df], axis=1)

# 提取eid的频次特征
train_data['eid_freq'] = train_data['eid'].map(train_data['eid'].value_counts())
test_data['eid_freq'] = test_data['eid'].map(train_data['eid'].value_counts())

# 提取eid的标签特征
train_data['eid_mean'] = train_data['eid'].map(train_data.groupby('eid')['target'].mean())
test_data['eid_mean'] = test_data['eid'].map(train_data.groupby('eid')['target'].mean())

train_data['eid_std'] = train_data['eid'].map(train_data.groupby('eid')['target'].std()).astype(np.float32)
test_data['eid_std'] = test_data['eid'].map(train_data.groupby('eid')['target'].std()).astype(np.float32)

# 提取时间戳
train_data['common_ts'] = pd.to_datetime(train_data['common_ts'], unit='ms')
test_data['common_ts'] = pd.to_datetime(test_data['common_ts'], unit='ms')
train_data['common_ts_hour'] = train_data['common_ts'].dt.hour
test_data['common_ts_hour'] = test_data['common_ts'].dt.hour

         进行数据载入/检测与特征分析工作。

# 训练模型:自己按需选取特征
x = train_data.drop(['udmap', 'common_ts', 'uuid', 'target', 'common_ts_hour', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7',
                     'x8', 'eid', 'eid_std', 'eid_mean', 'eid_freq', 'key1', 'key2', 'key3', 'key4', 'key5', 'key6',
                    'key7', 'key8', 'key9'], axis=1)
y = train_data['target']
clf = DecisionTreeClassifier()
clf.fit(x, y)

        实在不知道怎么突破数据量限制,绘制完整特征重要性图像,只能分组绘制了。

# 获取特征重要性得分
feature_importances = clf.feature_importances_

# 创建特征名列表
feature_names = list(x.columns)

# 创建一个DataFrame,包含特征名和其重要性得分
feature_importances_df = pd.DataFrame({'feature': feature_names, 'importance': feature_importances})

# 对特征重要性得分进行排序
feature_importances_df = feature_importances_df.sort_values('importance', ascending=False)

# 颜色映射
colors = plt.cm.viridis(np.linspace(0, 1, len(feature_names)))

# 可视化特征重要性
fig, ax = plt.subplots(figsize=(10, 6))
ax.barh(feature_importances_df['feature'], feature_importances_df['importance'], color=colors)
ax.invert_yaxis()  # 翻转y轴,使得最大的特征在最上面
ax.set_xlabel('特征重要性', fontsize=12)  # 图形的x标签
ax.set_title('决策树特征重要性可视化', fontsize=16)
for i, v in enumerate(feature_importances_df['importance']):
    ax.text(v + 0.01, i, str(round(v, 3)), va='center', fontname='Times New Roman', fontsize=10)

# 保存图形
plt.savefig('./特征重要性.jpg', dpi=400, bbox_inches='tight')
plt.show()

过拟合


定义:学习器把训练样本自身的一些特点当作了所有潜在样本都会具有的一般性质,导致泛化性能下降。具体表现就是最终模型在训练集上效果好;在测试集上效果差。模型泛化能力弱。

原因:

  1. 训练数据中噪音干扰过大,使得学习器认为部分噪音是特征从而扰乱学习规则
  2. 建模样本选取有误,例如训练数据太少,抽样方法错误,样本label错误等,导致样本不能代表整体
  3. 模型不合理,或假设成立的条件与实际不符
  4. 特征维度/参数太多,导致模型复杂度太高

解决办法(过拟合无法彻底避免,只能缓解):

  1. 保留验证集,获取额外数据进行交叉验证
  2. 降低模型复杂度,对于决策树可以限制树深,剪枝,限制叶节点数量
  3. 正则化,将权值的大小作为惩罚项加入到损失函数里,限制权值weight-decay
  4. 增加噪声

欠拟合

定义:对训练样本的一般性质尚未学好。在训练集及测试集上的表现都不好。

原因:

  1. 模型复杂度过低,表达能力较差
  2. 特征量过少,或现有特征与样本标签的相关性不强

解决办法:

  1. 增加特征数
  2. 增加模型复杂度
  3. 减小正则化系数

数据读取效率优化

# 尝试对比csv文件与parquet文件的读取效率
import pandas as pd
import time

start = time.time()  # 计时起点
train_data = pd.read_csv('E:/编程/用户新增预测大赛/train.csv')
test_data = pd.read_csv('E:/编程/用户新增预测大赛/test.csv')
end = time.time()    # 计时终点
print(end - start)   # 输出读取csv文件耗时

train_data.to_parquet('train.parquet', compression=None)
test_data.to_parquet('test.parquet', compression=None)

start = time.time()
train_data = pd.read_parquet('train.parquet', engine='fastparquet')
test_data = pd.read_parquet('test.parquet', engine='fastparquet')
end = time.time()
print(end - start)   # 输出读取parquet文件耗时

   

         显然,pandas库的read_csv函数的读写效率不如read_parquet函数。

引用

【机器学习】随机森林预测并可视化特征重要性

过拟合与欠拟合

系列文章(持续更新)

2023.8夏令营“用户新增预测”学习笔记(一)

2023.8夏令营“用户新增预测”学习笔记(二)

2023.8夏令营“用户新增预测”学习笔记(三)

2023.8夏令营“用户新增预测”学习笔记(五)  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值