这场比赛中给出了二分类的数据集和一首藏头诗,这首诗中暗藏的玄机我们会在接下来的分析当中逐渐给出说明。比赛的数据集依旧是老三样:训练集(train.csv)、测试集合(test.csv)以及结果提交模版(submission.csv)。
Silly column names abound,
but the test set is a mystery.
Careful how you pick and slice,
or be left behind by history.
这次比赛不同于之前比赛的一点是在commit时,系统会运行一次你的程序,并且test.csv只用到了public部分的数据。而在你选择文件提交的时候,系统会再一次运行你的程序,这时用到的test.csv包括public和private两部分的数据集,并且只显示public部分的得分。而在最后比赛截止的时候,会使用private部分的分数进行排名,这里的public和private数据集的样本数量相同。ps:本篇blog回顾了做比赛的心路历程,在本地IDE中重新跑了一遍code并进行截图(po主比较喜欢用spyder)。其中的发现一部分是博主自己的思考,一部分来自队友男票,一部分来自kaggle的kernal区及discussion区的大神。
首先,要熟悉实验数据。
import numpy as np
import pandas as pd
import matplotlib. pyplot as plt
import seaborn as sns
train=pd.read_csv('../input/train.csv')
test=pd.read_csv('../input/test.csv')
# observe columns names in train.csv
name_list=train.columns.tolist()
#observe train set
train.head()
导出训练数据集train.csv的列名,除了列id
和target
之外的列均由四个英文单词构成,看起来目前无法从列名中得到一些有用的信息。
从train文件的前五行能够看出,train由columnid
,columntarget
和256个特征组成。
接下来,看一下训练集train.target 的情况,我们发现这个数据集的分布比较均匀,且columnid
那一列的名字让我们有理由认为这可能是人造数据。
下面观察一下features的分布情况。从图中我们发现,除了'wheezy-copper-turtle-magic'
特征之外的其他255个特征都近似于normal distribution。
这特殊的一列值得我们的注意,而且也呼应了举办方给出的藏头诗的第一句:Silly column names abound,
那么是否可以认为我们找到了一个silly column.这一列数据的最小值是0,最大值是511,在spyder中将train.csv文件的这一列选出,这一列数据和旁边的数据比起来一看还是比较辣眼睛的。
其实我特别想说,在当时我第一遍作出这些数据这些图的时候,我除了觉得有时候图比较好看,并没有什么直觉说哪些数据可能是magic。可能是做的多了之后,看到数据呈现某些状态就有哪些直觉了吧。不过因为博主最近也在看李航大神的《统计学习方法》EM算法和高斯混合模型的部分,而且恰好这次比赛的特征制图也比较像Gauss Distribution,所以我直觉上会对觉得高斯混合模型有特别的感觉,然而并没什么卵用,因为我还在各种扒kernal区大神的代码,看discussion,跟着炒一些kernal区爆出来的高分代码。
下面我也得画一下test.csv的图吧。
plt.figure()
fig,ax=plt.subplots(6,6,figsize=(14,14))
for j in range(1,37):
testname[j]in namelist
plt.subplot(6,6,j)
plt.hist(test[namelist[j]].values,bins=100)
plt.title(testname[j],fontsize=7)
plt.xlabel('Value',fontsize=7)
plt.ylabel('Target',fontsize=7)
plt.show()
test.describe()
target
的分布是比较balanced;magic
特征可以继续研究。下面就可以对特征对相关性进行一下研究:
magic='wheezy-copper-turtle-magic'
train_corr=train.drop(['target',magic],axis=1).corr()
test_corr=test.drop(magic,axis=1).corr()
train_corr_flat = train_corr.values.flatten()
train_corr_flat = train_corr_flat[train_corr_flat != 1]
test_corr_flat = test_corr.values.flatten()
test_corr_flat = test_corr_flat[test_corr_flat != 1]
fig, ax = plt.subplots(1,2,figsize=(20,5))
sns.distplot(train_corr_flat, ax=ax[0], color="tomato")
sns.distplot(test_corr_flat, ax=ax[1], color="limegreen");
ax[0].set_title("Off-diagonal train corr \n distribution")
ax[1].set_title("Off-diagonal test corr \n distribution");
ax[0].set_xlabel("feature correlation value")
ax[1].set_xlabel("feature correlation value");
plt.figure(figsize=(25,25))
sns.heatmap(train_corr, vmin=-0.016, vmax=0.016, cmap="RdYlBu_r");
sns.heatmap(test_corr,vmin=-0.016,vmax=0.016,cmap="RdYlBu_r")
仔细观察能够发现,一些相邻的特征之间可能存在一些相关性,这可能对后续的研究有一些影响。同时在train特征图的右下角能够看到后两个特征之间有一定的相关性,但是在test图中这种相关性就不存在了。也就是说,在相关性分析来看,训练集和测试集的特征分布有一定的差异。
下面我们将对列名进行一些研究,看能否得到一些exciting的结论。
names=list(train.drop(['id','target'],axis=1).columns.values)
first_name=[]
second_name=[]
third_name=[]
fourth_name=[]
for name in names:
words=name.split('-')
first_name.append(words[0])
second_name.append(words[1])
third_name.append(words[2])
fourth_name.append(words[3])
print(len(first_name),len(np.unique(first_name)))
print(len(second_name), len(np.unique(second_name)))
print(len(third_name), len(np.unique(third_name)))
print(len(fourth_name), len(np.unique(fourth_name)))
feature_names=pd.DataFrame(index=train.drop(["target", "id"], axis=1).columns.values, data=first_name, columns=["kind"])
feature_names["color"] = second_name
feature_names["animal"] = third_name
feature_names["goal"] = fourth_name
feature_names.head()
plt.figure(figsize=(20,5))
sns.countplot(x="kind", data=feature_names, order=feature_names.kind.value_counts().index, palette="Greens_r")
plt.xticks(rotation=90);
plt.figure(figsize=(20,5))
sns.countplot(x="animal", data=feature_names, order=feature_names.animal.value_counts().index, palette="Oranges_r")
plt.xticks(rotation=90);
plt.figure(figsize=(20,5))
sns.countplot(x="goal", data=feature_names, order=feature_names.goal.value_counts().index, palette="Reds_r")
plt.xticks(rotation=90);
plt.figure(figsize=(20,5))
sns.countplot(x="color", data=feature_names, order=feature_names.color.value_counts().index, palette="Purples_r")
plt.xticks(rotation=90);
当时因为四句藏头诗对dataset产生无限对遐想,就像猜灯谜一样。做了一些图和分析,大概就是找到了一个magic特征,找到了数据分布的一些特点。另外就是数据可能是来自于人工合成,sklearn 里面有一个数据合成方法make_classification()
。以往有大神找到了kaggle合成数据的随机种子,造出了同分布数据。但对于一个新手来说,虽然我有很多的想法,但大多时间都在调参选模型跟高分kernel,希望以后有时间能够在做比赛的过程一一实现自己的想法吧。