2023AI夏令营(三)-机器学习第二次笔记-用户新增预测挑战赛

声明:很怪,别看。(满屏荒唐言,一把辛酸泪)

2.1数据分析与可视化

1.库

import matplotlib.pyplot as plt

import seaborn as sns

2.热力图

sns.heatmap(train_data.corr().abs(),cmap='YlOrRd')
#注意看,是英文小写l不是数字1,是英文大写O不是数字0。
#总之参数全英。

 结果分析:target和x7相关性较强

3. x7

Python可视化 | Seaborn5分钟入门(二)——barplot和countplot - 知乎 (zhihu.com)

对列中的数值进行归类后按照estimator参数的方法(默认为平均值)计算相应的值,计算出来的值就作为条形图所显示的值(条形图上的误差棒则表示各类的数值相对于条形图所显示的值的误差

sns.barplot(x='x7', y='target', data=train_data)

 

 

 疑似结论:x7值为1的都是target1,target1的x7不都为1;x7为1的数量极少,参考意义难评。

4.回答问题

1.字段x1至x8为用户相关的属性,为匿名处理字段。添加代码对这些数据字段的取值分析,那些字段为数值类型?那些字段为类别类型?

#数据显示版
for i in range(1,9):
    a=train_data['x'+str(i)].value_counts()
    print(a)
    print('=====================')

#画图版
fig, my_grid = plt.subplots(nrows=2, ncols=4, figsize=(18,8))
for i in range(1,9):
    plt.subplot(2,4 , i )
    sns.barplot(y=train_data['x'+str(i)].value_counts().values, x=train_data['x'+str(i)].value_counts().index)

 

 

答:根据数据字段的取值分布,x1(5),x2(4),x6(5),x7(10),x8(2)数据字段可能是类别类型。 

2.对于数值类型的字段,考虑绘制在标签分组下的箱线图。

失败样例:

可能成功样例:

y1=train_data.loc[train_data.target==1,['x3']]
y1.rename(columns = {'x3' : '1'}, inplace = True)
y2=train_data.loc[train_data.target==0,['x3']]
y2.rename(columns = {'x3' : '0'}, inplace = True)
x3_box = pd.concat([y1, y2], axis=1)
x3_box.boxplot()

循环可能:

fig, my_grid = plt.subplots(nrows=1, ncols=3, figsize=(18,8))
for i in [3,4,5]:
    plt.subplot(1,3,i-2)
    y1=train_data.loc[train_data.target==1,['x'+str(i)]]
    y1.rename(columns = {'x'+str(i) : '1'}, inplace = True)
    y2=train_data.loc[train_data.target==0,['x'+str(i)]]
    y2.rename(columns = {'x'+str(i): '0'}, inplace = True)
    x_box = pd.concat([y1, y2], axis=1)
    x_box.boxplot()

偷到的好东西:(dbq)

2023.8夏令营“用户新增预测”学习笔记(二)_dandellion_的博客-CSDN博客

for i in [3,4,5]:
    sns.boxplot(x='target', y='x'+str(i), data=train_data)
    plt.show()

 

3.从common_ts中提取小时,绘制每小时下标签分布的变化。

#提取小时
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
#绘条形图
sns.barplot(x='common_ts_hour', y='target', data=train_data)

 

#绘折线图
sns.lineplot(x='common_ts_hour', y='target', data=train_data)

 

4.对udmap进行onehot,统计每个key对应的标签均值,绘制直方图。

#baseline
# 定义函数 udmap_onethot,用于将 'udmap' 列进行 One-Hot 编码
def udmap_onethot(d):
    v = np.zeros(9)  # 创建一个长度为 9 的零数组
    if d == 'unknown':  # 如果 'udmap' 的值是 'unknown'
        return v  # 返回零数组
    d = eval(d)  # 将 'udmap' 的值解析为一个字典
    for i in range(1, 10):  # 遍历 'key1' 到 'key9', 注意, 这里不包括10本身
        if 'key' + str(i) in d:  # 如果当前键存在于字典中
            v[i-1] = d['key' + str(i)]  # 将字典中的值存储在对应的索引位置上
            
    return v  # 返回 One-Hot 编码后的数组


# 使用 apply() 方法将 udmap_onethot 函数应用于每个样本的 'udmap' 列
# np.vstack() 用于将结果堆叠成一个数组
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)))
# 为新的特征 DataFrame 命名列名
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 = pd.concat([train_data, train_udmap_df], axis=1)
test_data = pd.concat([test_data, test_udmap_df], axis=1)


# 编码 udmap 是否为空
# 使用比较运算符将每个样本的 'udmap' 列与字符串 'unknown' 进行比较,返回一个布尔值的 Series
# 使用 astype(int) 将布尔值转换为整数(0 或 1),以便进行后续的数值计算和分析
train_data['udmap_isunknown'] = (train_data['udmap'] == 'unknown').astype(int)
test_data['udmap_isunknown'] = (test_data['udmap'] == 'unknown').astype(int)
#绘图
for i in range(1,10):
    sns.barplot(x='key'+str(i),y='target',data=train_data)
    plt.show()

结论:key4,5,7,8,9的取值差别对target的影响不大。

 2.2模型交叉验证

考察过拟合或欠拟合,

将原始的训练数据划分为多个子集(也称为折叠),然后将模型训练和验证

进行多次循环。在每一次循环中,使用其中一个子集作为验证集,其他子集作为训练集。

1.导入

# 导入模型
from sklearn.linear_model import SGDClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import MultinomialNB
from sklearn.ensemble import RandomForestClassifier

# 导入交叉验证和评价指标
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import classification_report

2.训练并验证模型

# 训练并验证SGDClassifier
pred = cross_val_predict(
    SGDClassifier(max_iter=10),
    train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
    train_data['target']
)
print(classification_report(train_data['target'], pred, digits=3))

 

# 训练并验证DecisionTreeClassifier
pred = cross_val_predict(
    DecisionTreeClassifier(),
    train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
    train_data['target']
)
print(classification_report(train_data['target'], pred, digits=3))

 

 

# 训练并验证MultinomialNB
pred = cross_val_predict(
    MultinomialNB(),
    train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
    train_data['target']
)
print(classification_report(train_data['target'], pred, digits=3))

 

 

# 训练并验证RandomForestClassifier
pred = cross_val_predict(
    RandomForestClassifier(n_estimators=5),
    train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
    train_data['target']
)
print(classification_report(train_data['target'], pred, digits=3))

 

 

3.回答问题

1.在上面模型中哪一个模型的macro F1效果最好,为什么这个模型效果最好?

答:第二个决策树模型DecisionTreeClassifier效果最好。对1和0的f1_score都较高。

2.使用树模型训练,然后对特征重要性进行可视化;

# 导入库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

y_importances = clf.feature_importances_
x_importances = list(train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1).columns)
y_pos = np.arange(len(x_importances))
# 横向柱状图
plt.barh(y_pos, y_importances, align='center')
plt.yticks(y_pos, x_importances)
plt.xlabel('Importances')
plt.xlim(0,1)
plt.title('Features Importances')
plt.show()

 

2.3特征工程

看上去似乎是,增加更多参考数据。

1.遇到问题

ValueError: Input contains NaN, infinity or a value too large for dtype('float32').

ValueError: Input contains NaN, infinity or a value too large for dtype(‘float64‘)._lzx_850404536的博客-CSDN博客 

2.回答问题

 1.加入特征之后模型的精度有什么变化?

答:线上提交分数大大提高,突破0.7

2.思考并加入3个额外的特征,并观测模型精度的变化

答:先测试模型,选择好的模型;然后查看该模型的特征重要性;最后对重要性强的特征进行进一步挖掘和增加。

参考:

10分钟实战python简单数据分析 - 知乎 (zhihu.com)


Python可视化 | Seaborn5分钟入门(二)——barplot和countplot - 知乎 (zhihu.com)4.7 Pandas中的Dataframe数据选取(三)(Python)_python取dataframe_ibun.song的博客-CSDN博客

数据分析科普_类别型数据_夏目-的博客-CSDN博客 

请分享一下数据分析方面的思路,如何做好数据分析? - 知乎 (zhihu.com)

【Python-数据分析】pandas 高级技巧:values_count()、日期索引与分组统计可视化 (zhihu.com)

使用Python循环快速绘制多张图表 - 知乎 (zhihu.com)

【Python】在同一图形中的绘制多个子图_python创建多个子图_赵卓不凡的博客-CSDN博客

python matplotlib绘画十一种常见数据分析图_python_脚本之家 (jb51.net)

Python绘制数据分布_笔记大全_设计学院 (python100.com)

Python 可视化:分组箱线图 - 知乎 (zhihu.com)

2023.8夏令营“用户新增预测”学习笔记(二)_dandellion_的博客-CSDN博客

基于树模型的参数和可视化实现问题_answer3lin的博客-CSDN博客

机器学习笔记二(任务二)_橘子汽水海的博客-CSDN博客

ValueError: Input contains NaN, infinity or a value too large for dtype(‘float64’)._valueerror: input contains nan._陈冰莹的博客-CSDN博客

ValueError: Input contains NaN, infinity or a value too large for dtype(‘float64‘)._lzx_850404536的博客-CSDN博客 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值