本文共 5100 字,大约阅读时间需要 17 分钟。
最近想要把学的机器学习算法用起来,所以开始看看kaggle上的比赛。看了两个新人入门赛泰坦尼克号生还预测和房屋价格预测。总结一下看代码的一些经验吧。
总体感觉是,在建立特征工程上耗费的时间,要远远大于训练模型和调参的过程。可见特征的重要性。而且,在数据科学的比赛中,用xgboost方法的占到大多数,这里再次膜拜一下陈天奇大神······pandas
和numpy
数据的一般格式都是.csv文件,处理用的包是pandas
。其基本的数据结构为dataframe
和series
.import pandas as pdimport numpy as np#创建dataframe对象df1 = pd.DataFrame({ 'col1':[1,3],'col2':[2,4]},index = ['a','b'])df2 = pd.DataFrame(np.array([[1,3,5],[2,4,6]]),columns = ['col1','col2'])#大小2*3#如果不加index,默认行索引为0,1,2...数字#创建dataframe对象的数据可以为列表,字典,数组。
#基本操作:#1.索引操作df1.index#行df2.columns#列df1.loc['a']#索引这一行的数据#df.loc[]与df.iloc[]的区别:.loc[]索引的是行名,.iloc[]索引的是行数字df2['col1']#访问列数据#支持组合选择df2[['col1','col2']]#行列索引df2.iloc[2]['a']#2.数据合并#三种方法:join,concat,append,mergepd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)#concat可横向,可纵向,axis = 0,表示横向,axis=1,表示纵向。#join:{inner,outer}:合并方式,默认为outer,表示并集,inner表示交集#ignore_index:{False,True},是否忽略原index,默认为不忽略#keys:为原始dataframe添加一个键,默认为无df1 = df1.append(df2)#横向和纵向同时扩充df1.join(df2,how = 'inner')#3.丢弃数据#drop方法df1 = df1.drop('a',axis = 1)#丢掉列
matplotlib,seaborn
用于数据的可视化scipy
统计模块
from scipy import statsfrom scipy.stats import skew, normfrom scipy.special import boxcox1pfrom scipy.stats.stats import pearsonr#皮尔森相关系数矩阵
pd.read_csv(filename)
concat
方法,把训练集和数据集连接在一起处理。# First of all, save the length of the training and test data for use laterntrain = train.shape[0]ntest = test.shape[0]# Also save the target value, as we will remove thisy_train = train.SalePrice.values# concatenate training and test data into all_dataall_data = pd.concat((train, test)).reset_index(drop=True)all_data.drop(['SalePrice'], axis=1, inplace=True)
主要两种处理方法,要不就删去,要不就补全。所以要观察缺失值缺的是啥,为什么会缺失。
比如:大量的缺失,可能是因为这个不重要,或者大多数不存在,所以可以酌情删除这个特征。如果缺失的数量较少,那么观察这个数值类型,是数值型还是标签类型。是不是可以用众数、中位数、或者均值来进行填充。异常值处理(outlier)
可以通过plot的方式,看看是否存在明显的异常值或者离群值,然后手动剔除就行。常用方法
data.groupby()
:groupby可以通过传入需要分组的参数实现对数据的分组.groupby之后的数据并不是DataFrame格式的数据,而是特殊的groupby类型,此时,可以通过size()方法返回分组后的记录数目统计结果,该结果是Series类型.通过groupby完成对数据的分组后,可以通过get_group方法来获取某一制定分组的结果 data.isnull()
:判断是否包含空值。可再使用sum方法计算空值数量。data.isnull().sum()
统计出来的结果是每一列的空值总数。 data.fillna()
:填充空值 接下来到了重要且费时的部分了。分析数据之间的关系,通过去除或合并冗余特征,降维等方式,建立特征工程。选择到一组好的特征,即使与别人用相同的学习方法,也能得到秒杀众人的结果。所以在数据科学的比赛中,我感觉特征是第一重要,其次才是机器学习方法和参数。
通过前面的处理,把缺失值补全,而且异常值也去除。接下来,首先对所有数据之间的相关性进行总体的预览。这就用到了计算相关系数的方法。DataFrame.corr(method='pearson', min_periods=1)
Compute pairwise correlation of columns, excluding NA/null values.这里默认用pearson相关系数
然后可以用seaborn的热力图进行显示。sns.heatmap(corr, cmap="RdYlBu", vmax=1, vmin=-0.6, center=0.2, square=True, linewidths=0, cbar_kws={ "shrink": .5}, annot = True);
也可以用seaborn的pairplot
方法:
seaborn.pairplot(data, hue=None, hue_order=None, palette=None, vars=None, x_vars=None, y_vars=None, kind='scatter', diag_kind='hist', markers=None, size=2.5, aspect=1, dropna=True, plot_kws=None, diag_kws=None, grid_kws=None)¶
有了对数据之间的相关性的初步了解,接下来就是建立特征工程了。这一部分比较方法比较个性化感觉,但大概意思应该是一一分析,两两之间通过画图直观观察可能有怎样的相关性,是线性关系,平方关系还是什么的。最终确定应用到学习算法中的数据有哪些。
这里常用到的一些方法总结如下:sns.boxplot()sns.stripplot()sns.barplot()sns.regplot()
pandas.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)#for example>>> pd.cut(np.array([.2, 1.4, 2.5, 6.2, 9.7, 2.1]),... 3, labels=["good", "medium", "bad"])... >>> [good, good, good, medium, bad, good]Categories (3, object): [good < medium < bad]
pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None)#for examples = pd.Series(list('abca'))>>> pd.get_dummies(s) a b c0 1 0 01 0 1 02 0 0 13 1 0 0
Convert categorical variable into dummy/indicator variables.
在很多数据处理中,我们都需要对数据进行哑变量处理。例如,某个数据中的月份用1-12进行表示,但是月份的值本身并没有数值上的意义,比方说2月份比1月份多,这显然是不合理的。 对目标变量的处理: 这里主要是对目标变量分布所做的一点变换。因为大部分机器学习算法在正态分布上可能应用的更好/但是通过观察数据的频率分布直方图,可以看出他们是偏态分布,此时需要做一点变换,使之与正态分布相近,这样可以的到更好的预测效果。但是,需要注意的是,当做出变换之后,在最后的时候,还要变换回来。这里以房价预测中所应用的方法为例:g = sns.distplot(train['SalePrice'], fit=norm, label = "Skewness : %.2f"%(train['SalePrice'].skew()));#观察到分布为正偏态。#We use the numpy fuction log1p which applies log(1+x) to all elements of the columntrain["SalePrice"] = np.log1p(train["SalePrice"])
以上为对目标变量的变换。
对于数值类型为数值的特征变量,也需要进行类似的变换。通过统计每一变量的skew值(偏度/偏态值,越接近0,越符合正态分布。大于0为正偏态,小于0为负偏态),对绝对值大于0.5的进行boxcox变换。 box - cox变换 可以使线性回归模型满足线性性、独立性、方差齐性以及正态性的同时,又不丢失信息,此种变换称之为Box—Cox变换。这种变换是对变量y进行变换 误差与y相关,不服从正态分布,于是给线性回归的最小二乘估计系数的结果带来误差 使用Box-Cox变换族一般都可以保证将数据进行成功的正态变换,但在二分变量或较少水平的等级变量的情况下,不能成功进行转换,此时,我们可以考虑使用广义线性模型,如LOGUSTICS模型、Johnson转换等。 Box-Cox变换后,残差可以更好的满足正态性、独立性等假设前提,降低了伪回归的概率scipy里面的变换公式为:y=xλ−1λ,λ!=0;y=xλ−1λ,λ!=0;
y=log(x),λ==0y=log(x),λ==0其中 x 代表需要变换的数据,y代表数据变换后的结果
此处先按下不表,以后再详细写
将dataframe
生成.csv
文件,然后提交就OK啦!
dataframe.to_csv('final_submission.csv',index=False)