大数据比赛第一步——数据分析

前言

大家好,我是机器学习领域的新手,最近新开了《从零开始的机器学习之旅》专栏,希望能与大家共同进步,如有错误和意见请不吝指出,谢谢。

最近看了一些比赛code,也自己试着提交了一下,真正体验到比赛的乐趣。但是,光看代码提高不了比赛能力,总结才是王道。所以我打算做一个系列,总结成模板,方便能有部分思路能够应用到以后的所有比赛中。

系列包括:

  1. 数据分析
  2. 特征工程
  3. 模型训练
  4. 模型融合

数据分析

对数据的分析,无疑是十分重要的。

毕竟数据里属性(特征)众多,我们对数据进行分析,可以找出哪些属性对标签的影响更为重要,哪些特征没有作用,甚至对结果(标签)产生负影响等等。

还可以找出哪些属性有缺失值,哪些属性可以合并生成新属性等等,当然我们在后续【特征工程】部分会进行处理。

一、加载数据

1.1 准备工作

首先,无脑导入numpy和pandas准没错。而为了做数据分析画图是必须的,因此导入seaborn和matplotlib

import pandas as pd #数据分析
import numpy as np #科学计算
from pandas import Series,DataFrame
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline

1.2 数据导入

这是不管做什么项目、比赛的第一步,巧妇难为无米之炊,有了数据才能开始干活。我没有设置工作路径,数据和程序放在同一个文件夹。

train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")

一般的小比赛,只有训练集和测试集,直接导入即可。

1.3 数据合并

1.3.1 merge

有的大比赛,会有好几个csv文件,我们导入后,在对数据进行一定了解后,可以进行merge合并。

train=train1.merge(train2,how='left',on='userID')

这里用到了merge函数。把训练集1和训练集2按照userID合并。

DataFrame.merge(*right*, *how='inner'*, *on=None*, *left_on=None*, *right_on=None*, *left_index=False*, *right_index=False*, *sort=False*, *suffixes=('_x'*, *'_y')*, *copy=True*, *indicator=False*, *validate=None*)

我主要用到howon两个参数。
on用来指明要加入的列 (名称)。必须在左、 右综合对象中找到。
how指明merge的方式,一共有四种。

  • left:只使用左边框的键,类似于SQL左外部连接; 保持按键顺序
  • right:仅使用右框架中的键,类似于SQL右外连接; 保持按键顺序
  • outer:使用两个框架中的键的联合,类似于SQL全外连接; 按字典顺序排序键
  • inner:使用来自两个框架的键的交集,类似于SQL内部联接; 保留左键的顺序

看到有人说的不错,引用下:

df = pd.merge(df1, df2, how='left', on='user_id')

how="left"就是说,保留user_id字段的全部信息,不增加也不减少,但是拼接的时候只把df2表中的与df1中user_id字段交集的部分合并上就可以了,如果df2中出现了某个user_id在df1中没有出现,就抛弃掉这个样本不作处理。

自己跑个小程序,加深一下理解。可以发现,df2加到df1后,只有A0和A1的信息拼接上去了,而A4和A5因为df1里没有,故E、F、G的值都为NaN。
1523715178415

其他参数可以从官方手册进行了解

1.3.2 concat

用来进行简单的拼接,可以保留这些表单的全部信息。

pandas.concat(*objs*, *axis=0*, *join='outer'*, *join_axes=None*, *ignore_index=False*, *keys=None*, *levels=None*, *names=None*, *verify_integrity=False*, *copy=True*)

参数axis=1表示列拼接,axis=0表示行拼接。

比如把df1和df2的数据按列拼接起来成一个大的Dataframe,如下:

frames = [df1, df2]
pd.concat(frames, axis = 1)

其实,我们经常要把训练集和测试集concat起来一起进行处理,用到的频率比较高,所以这里单独列出来。

其他参数可以从官方手册进行了解

1.3.3 其他

此外好像还有append,join,concatenate,用到了再补充。

train.drop('PassengerId',axis=1, inplace=True)

很常用的函数drop,就是去掉某一列,生成新dataframe。

1.4 预设数据

datasets里有一些预设的数据,可以方便我们进行模型的学习,比如很多教程用到的iris花的数据:

iris = datasets.load_iris()

二、数据总体预览

2.1 一些基本操作

train.head(5)

读取前5行数据,对数据有个直观了解。

train.info()

会对每一列的属性进行统计,包括名词、个数、是否为null、数据类型(int、float、object等)

这里数据个数很重要,可以直观看出是否有数据的缺失。

数据类型也很重要,涉及到后续的一些处理操作。

train.columns

输出列名称,相当于上一步的简化版,用在数据维度较多的地方,看起来比较方便。

train.describe()

会给出数值型数据的一些信息。比如个数、均值、std、min、max、25%、50%、75%。到了这一步往往能可以对一些特征的分布得出一些初步结论。

train['Survived'].value_counts()

统计特征(这里举例Survived这个特征,下同)里的各种值,包括数值型和object型,并列表。

train.drop('PassengerId',axis=1).corr()

corr函数,给出了数值型协方差,能了解数据间的相关性,大于0是正相关,小于0的负相关。理论上说,特征间相关度太高,可能会后面模型训练出来过拟合。从这里就可以对数据进行初步筛选。
特征PassengerId,是用户ID,由人脑经验得出,这应该与别的特征没有任何关系,故直接先去掉。
同时这个函数,也是绘制heatmap的前置函数,后面会讲到heatmap。

df.groupby(['key1']).size()

按key1的值分组,并统计个数。

df.groupby(['key1','key2']).size()

按'key1','key2'两列分组,并统计个数。

train.groupby(['Pclass'])['Pclass','Survived'].mean()

按Pclass分组后,统计分组下的Pclass和Survived的平均值。比较经典的用法是,分组后,可以画柱状图,来直观显示数据。

df['data1'].astype(float)

将data1列数据进行类型转换成float型。

df['add'] = ['AA','BB',"CC",'DD','EE']

直接追加一列数据叫做add的数据,好像只要不重名即可,右边为增加的数据。比如,测试集里可能没有标签列,我们直接加上一列标签列,再与训练集合并。

三、数据初步分析

画图能往往更直观表现数据的特点。因此我们需要借助一些工具。

3.1 一些绘图工具总结

3.1.1 heatmap

a = plt.subplots(figsize=(20, 12))#调整画布大小
a = sns.heatmap(train_corr, vmin=-1, vmax=1, annot=True, square=True)#画热力图   annot=True 显示系数

这里的train_corr,是上面讲到的数值型协方差,它作为绘制heatmap里需要导入的最重要的参数。

有时候,特征维度太多,heatmap看起来太复杂了。我们可以选择和标签相关度最高的前n个项,再绘制热力图。

# 寻找K个最相关的特征信息
k = 10 # number of variables for heatmap
cols = train_corr.nlargest(k, 'SalePrice')['SalePrice'].index
cm = np.corrcoef(train[cols].values.T)
sns.set(font_scale=1.5)
hm = plt.subplots(figsize=(20, 12))#调整画布大小
hm = sns.heatmap(cm, cbar=True, annot=True, square=True, fmt='.2f', annot_kws={'size': 10}, yticklabels=cols.values, xticklabels=cols.values)
#annot_kws,当annot为True时,可设置各个参数,包括大小size,颜色color,加粗,斜体字等
#fmt,格式设置 这里保留2位小数
plt.show()

1523719969456

颜色越深,说明相关度越低。

然后,heatmap的全部参数如下,大部分弄懂就能够绘制出自己想要的图像啦。
seaborn.heatmap(data, vmin=None, vmax=None, cmap=None, center=None, robust=False, annot=None, fmt='.2g', annot*kws=None, linewidths=0, linecolor='white', cbar=True, cbar*kws=None, cbar_ax=None, square=False, ax=None, xticklabels=True, yticklabels=True, mask=None, **kwargs)

关于heatmap的其他系数,这篇写的好,附上链接

3.1.2 柱状图

train[['Pclass','Survived']].groupby(['Pclass']).mean().plot.bar()

先按Pclass分类,然后统计Survived均值,并画出柱状图。其实就是在之前分组求玩平均值后,直接添加.plot.bar(),就能绘制出柱状图啦。

1523719031610

这里遇到的一个情况,是我在jupyter notebook里绘制图像,发现里面的中文是乱码,查了下原因,发现得加上下面这两行,愉快解决,记录一下。如果大家有一样的情况,请效仿。

#输入下段2行代码 否则输出的图内中文为乱码
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False

data_train.Survived.value_counts().plot(kind='bar')# 柱状图 
plt.title("获救情况 (1为获救)") # 标题
plt.ylabel("人数")  

这里是把bar,作为plot函数里参数的一种,直接绘制出柱状图,也是可以的。
按类统计人数,并绘制柱状图

1523719442747

3.1.3 普通的描点图

data_train.groupby(['Age'])['Survived'].mean().plot()

1523719239298

plot没有设置参数,默认是这样把各个点粗暴地连在一起,可视化效果比较差。这里显示是年龄和获救比例对应图,好像看不出太多信息。

data_train.Age[data_train.Pclass == 1].plot(kind='kde')   
data_train.Age[data_train.Pclass == 2].plot(kind='kde')
data_train.Age[data_train.Pclass == 3].plot(kind='kde')
plt.xlabel(u"年龄")# plots an axis lable
plt.ylabel(u"密度") 
plt.title(u"各等级的乘客年龄分布")
plt.legend((u'头等舱', u'2等舱',u'3等舱'),loc='best') # sets our legend for our graph.

1523719680584

按照年龄为横轴,并按Pclass分类,画图。
这里plot里的参数kind设定的是kde,密度曲线。从图中形象看出3种船舱里,年龄的分布,你看头等舱里油腻的中年人明显是比较多的~

3.1.4 多变量作图

#SalePrice 和相关变量之间的散点图
sns.set()
cols = ['SalePrice', 'OverallQual', 'GrLivArea','GarageCars', 'TotalBsmtSF', 'FullBath', 'YearBuilt']
sns.pairplot(train[cols], size = 2.5)
plt.show();

这个是我在别人code里发现的,画出两两变量之间的散点图,简直不要太屌!比如这里就是7x7的对比关系,竟恐怖如斯!好评。

1523720609269

3.1.5 其他与补充

其实还有个散点图scatter挺重要的,懒得画了,这里就提一下。

关于其他seaborn操作看这个链接吧。

关于plot更多参数,看这个链接吧。

对于其他很有用的数据预处理代码和绘图工具,请在下方评论,并给出代码,最好还有效果图,我会在上方添加,感谢。

四、参考资料:

https://blog.csdn.net/chixujo...

https://www.cnblogs.com/kylin...

https://blog.csdn.net/jinlong...

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值