第二次打卡的笔记

任务:数据分析与可视化

数据探索性分析,是通过了解数据集,了解变量间的相互关系以及变量与预测值之间的关系,对已有数据在尽量少的先验假设下通过作图、制表、方程拟合、计算特征量等手段探索数据的结构和规律的一种数据分析方法,从而帮助我们后期更好地进行特征工程和建立模型,是机器学习中十分重要的一步。

 示例给的匿名标签与target之间相关性的热力图

 数据

 热力图

 

 x7与target的标签均值

似乎看起来就是x7标签下出现的标签与target出现的概率显示,这一部分和均值的关系并没有看出来,这一部分的均值会不会是x7数据出现概率的数学期望?这个问题还没解决。

以下是示例代码

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

# 读取训练集和测试集文件
train_data = pd.read_csv('用户新增预测挑战赛公开数据/train.csv')
test_data = pd.read_csv('用户新增预测挑战赛公开数据/test.csv')

# 相关性热力图
sns.heatmap(train_data.corr().abs(), cmap='YlOrRd')

# x7分组下标签均值
sns.barplot(x='x7', y='target', data=train_data)

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

 做法和任务一中是类似的:

1.把common_ts中的时间戳改为以ms的数据,用pd.to_datatime完成

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")

2.把ms的数据用dt.hour这种属性设置提成小时

train_data["common_ts_h"] = train_data["common_ts"].dt.hour
test_data["common_ts_h"] = test_data["common_ts"].dt.hour

3.用countplot这种图会更适合做出标签变化感(看见还有人用groupby函数去分析了以小时分组的相对于target次数统计的图,CV过来用一用,太天才了,佩服大佬能想出来)

sns.countplot(x="common_ts_h",hue='target', data=train_data)# 条状图


update_graph = (train_data.groupby("common_ts_h")["target"]
                .value_counts(normalize=True)# 百分比格式
                .sort_index()
                .unstack())
update_graph.plot.bar(stacked = True)# 百分比条状图

 

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

前几步仍然和任务一类似

  1. 声明调用matplotlib.pyplot库和seabron库
    import matplotlib.pyplot as plb
    import seaborn as sns
  2. 自定义一个独热算法函数
    def one_hot(n):
        v = np.zeros(9)
        if n == "unknown":
            return v
        else:
            n = eval(n)
            for i in range(1,10):
                if "key"+str(i) in n:
                    v[i-1] = n["key"+str(i)]
            return v
  3. 把字典格式存储的udmap转换成一个dataframe,改名字并且缝合到原本的train_data里面
    train_data_df = pd.DataFrame(np.vstack(train_data['udmap'].apply(one_hot)))
    train_data_df.columns = ['key' + str(i) for i in range(1, 10)]
    train_data = pd.concat([train_data, train_data_df], axis=1)
  4. 建立一个单独的字典key_mean,然后从1~9算过去,把每个key相对于target的均值算出来存在字典里
    key_means = {}
    for key in ["key"+str(i) for i in range(1,10)]:
        key_mean = train_data[train_data[key]!=0]["target"].mean()
        key_means[key] = key_mean
    key_means
  5. 用字典转换成dataframe并生成图
    key_means_df = pd.DataFrame(key_means, index = [0])
    print(key_means_df)
    plb.figure(figsize=(12, 6))
    sns.barplot(data=key_means_df, palette="Set3")
    plb.xlabel('Keys')
    plb.ylabel('Mean Target')
    plb.title('Stacked Bar Plot of Mean Target by Keys')
    plb.legend(title='Keys', loc='upper right')
    plb.show()

 图

画的柱状图,直方图一直画不出来,

 x1~x7字段的分析

        首先得要把x1~x7之间哪些是类型数据,哪些是数值数据分出来,这两者之间的分别大致在于数量以及连续与否上,像数量小、数据间连续性明显的大多都是类型数据,而数量大、缺少连续性的数据往往会是数值类型。因此在dataframe里面随机取一部分数据出来看看便可以知道类型是什么了

train_data[["x"+str(i)for i in range(1,9)]].head(10)

输出结果是这样的

x1x2x3x4x5x6x7x8
04041107206101
1404124283481
2404171288471
3134117366161
4034192383481
50341104250481
6134115027161
70341143347471
8404124338120
943417559171

        由此可见x3、x4、x5是数值类型,而其余的是类别类型

        然后就得对数值类型的数据进行箱线图刻画了。

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 6))
for i,y in enumerate(['x3', 'x4', 'x5']):
    sns.boxplot(x="target", y=y, data=train_data, width=0.5, showfliers=False,ax=axes[i])

图长这样

 

 (分割的不是很好,标签重合了……)

总结

  1. matplotlib和seaborn用的不是很熟,画一张图要找半天教程
  2. pandas库的groupy函数真的好有玩法,可以干好多事情,分组、找关系用groupby真的好好用
  3. 关于某个数据和target的均值究竟是什么?是target出现1的概率的数学期望还是什么?关于这点我有些搞不清楚,还是希望有个大佬教一下我吧(@o@)

任务:交叉验证

旨在用上多个模型相互检验评估模型的性能和能力,要求尽可能的使用完数据集,并且有比较稳健的表现,这意味着这个模型预测的时候,它的f1-score必须要高,而准确性accura的就没有相对高的要求了。

以下是题解代码

# 导入库
import pandas as pd
import numpy as np

# 读取训练集和测试集文件
train_data = pd.read_csv('用户新增预测挑战赛公开数据/train.csv')
test_data = pd.read_csv('用户新增预测挑战赛公开数据/test.csv')

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

# 导入模型
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

# 训练并验证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))

哪种模型的效果最好?原因?

DecisionTreeClassifier效果最好,它的f1-score是最高的

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

from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt

clf = DecisionTreeClassifier()
clf.fit(
    train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
    train_data['target']
)

# s树的特征重要性可视化
def plot_feature_importances(model):
    n_features = train_data.shape[1]-4 # 列数-4
    plt.barh(range(n_features),model.feature_importances_,align = 'center')# 横向柱状图以及参数
    plt.yticks(np.arange(n_features),train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1).columns)#输数据
    plt.xlabel("Feature importance")
    plt.ylabel("Feature")
    
plot_feature_importances(clf)

 再加入3个模型训练,对比模型精度

不清楚有什么可以用的模型,去网上搜了一下,额外决策树似乎是可以用来看看的

pred = cross_val_predict(
    ExtraTreeClassifier(),
    train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
    train_data['target']
)
print(classification_report(train_data['target'], pred, digits=3))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值