入门kaggle,开始机器学习应用之旅。

参看一些入门的博客,感觉pandas,sklearn需要熟练掌握,同时也学到了一些很有用的tricks,包括数据分析和机器学习的知识点。下面记录一些有趣的数据分析方法和一个自己撸的小程序。

1.Tricks

1) df.info():数据的特征属性,包括数据缺失情况和数据类型。

df.describe(): 数据中各个特征的数目,缺失值为NaN,以及数值型数据的一些分布情况,而类目型数据看不到。

缺失数据处理:缺失的样本占总数比例极高,则直接舍弃;缺失样本适中,若为非连续性特征则将NaN作为一个新类别加到类别特征中(0/1化),若为连续性特征可以将其离散化后把NaN作为新类别加入,或用平均值填充。

2)数据分析方法:将特征分为连续性数据:年龄、票价、亲人数目;类目数据:生存与否、性别、等级、港口;文本类数据:姓名、票名、客舱名

3)数据分析技巧(画图、求相关性)

  • 画图

类目特征分布图&&特征与生存情况关联柱状图:

  1. fig1 = plt.figure(figsize=(12,10)) # 设定大尺寸后使得图像标注不重叠
  2. fig1.set(alpha=0.2) # 设定图表颜色alpha参数
  3.  
  4. plt.subplot2grid((2,3),(0,0)) # 在一张大图里分列几个小图
  5. data_train.Survived.value_counts().plot(kind='bar')# 柱状图
  6. plt.title(u"获救情况 (1为获救)") # 标题
  7. plt.ylabel(u"人数")
  8.  
  9. plt.subplot2grid((2,3),(0,1))
  10. data_train.Pclass.value_counts().plot(kind="bar")
  11. plt.ylabel(u"人数")
  12. plt.title(u"乘客等级分布")
  13.  
  14. plt.subplot2grid((2,3),(0,2))
  15. plt.scatter(data_train.Survived, data_train.Age)
  16. plt.ylabel(u"年龄") # 设定纵坐标名称
  17. plt.grid(b=True, which='major', axis='y')
  18. plt.title(u"按年龄看获救分布 (1为获救)")
  19.  
  20. plt.subplot2grid((2,3),(1,0), colspan=2)
  21. data_train.Age[data_train.Pclass == 1].plot(kind='kde')
  22. data_train.Age[data_train.Pclass == 2].plot(kind='kde')
  23. data_train.Age[data_train.Pclass == 3].plot(kind='kde')
  24. plt.xlabel(u"年龄")# plots an axis lable
  25. plt.ylabel(u"密度")
  26. plt.title(u"各等级的乘客年龄分布")
  27. plt.legend((u'头等舱', u'2等舱',u'3等舱'),loc='best') # sets our legend for our graph.

                   

以上为3种在一张画布实现多张图的画法:

  1. ax1 = plt.subplot2grid((3,3), (0,0), colspan=3)
  2. ax2 = plt.subplot2grid((3,3), (1,0), colspan=2)
  3. ax3 = plt.subplot2grid((3,3), (1, 2), rowspan=2)
  4. ax4 = plt.subplot2grid((3,3), (2, 0))
  5. ax5 = plt.subplot2grid((3,3), (2, 1))
  6. plt.suptitle("subplot2grid")

                 

此外,还有两种方法等效:

  1. f=plt.figure()
  2. ax=fig.add_subplot(111)
  3. ax.plot(x,y)
  4.  
  5. plt.figure()
  6. plt.subplot(111)
  7. plt.plot(x,y)

连续性特征分布可以用直方图hist来实现(见上图-年龄分布直方图):

  1. figure1 = plt.figure(figsize=(6,6))
  2. value_age = train_data['Age']
  3. value_age.hist(color='b', alpha=0.5) # 年龄分布直方图
  4. plt.xlabel(u'年龄')
  5. plt.ylabel(u'人数')
  6. plt.title(u'年龄分布直方图')

类目特征与生存关系柱状图(见上图-各乘客等级的获救情况):

  1. fig2 = plt.figure(figsize=(6,5))
  2. fig2.set(alpha=0.2)
  3. Survived_0 = data_train.Pclass[data_train.Survived==0].value_counts()
  4. Survived_1 = data_train.Pclass[data_train.Survived==1].value_counts()
  5. df = pd.DataFrame({u'获救':Survived_1, u'未获救':Survived_0})
  6. df.plot(kind='bar', stacked=True) # stacked=False时不重叠
  7. plt.title(u"各乘客等级的获救情况")
  8. plt.xlabel(u"乘客等级")
  9. plt.ylabel(u"人数")
  10. plt.show()

各属性与生存率进行关联:

eg:舱位和性别 与存活率的关系:利用pandas中的groupby函数

  1. Pclass_Gender_grouped=dt_train_p.groupby(['Sex','Pclass']) #按照性别和舱位分组聚合
  2. PG_Survival_Rate=(Pclass_Gender_grouped.sum()/Pclass_Gender_grouped.count())['Survived'] #计算存活率
  3.  
  4. x=np.array([1,2,3])
  5. width=0.3
  6. plt.bar(x-width,PG_Survival_Rate.female,width,color='r')
  7. plt.bar(x,PG_Survival_Rate.male,width,color='b')
  8. plt.title('Survival Rate by Gender and Pclass')
  9. plt.xlabel('Pclass')
  10. plt.ylabel('Survival Rate')
  11. plt.xticks([1,2,3])
  12. plt.yticks(np.arange(0.0, 1.1, 0.1))
  13. plt.grid(True,linestyle='-',color='0.7')
  14. plt.legend(['Female','Male'])
  15. plt.show() #画图

可以看到,不管是几等舱位,都是女士的存活率远高于男士。

将连续性数据年龄分段后,画不同年龄段的分布以及存活率:

  1. age_train_p=dt_train_p[~np.isnan(dt_train_p['Age'])] #去除年龄数据中的NaN
  2. ages=np.arange(0,85,5) #0~85岁,每5岁一段(年龄最大80岁)
  3. age_cut=pd.cut(age_train_p.Age,ages)
  4. age_cut_grouped=age_train_p.groupby(age_cut)
  5. age_Survival_Rate=(age_cut_grouped.sum()/age_cut_grouped.count())['Survived'] #计算每年龄段的存活率
  6. age_count=age_cut_grouped.count()['Survived'] #计算每年龄段的总人数
  7.  
  8. ax1=age_count.plot(kind='bar')
  9. ax2=ax1.twinx() #使两者共用X轴
  10. ax2.plot(age_Survival_Rate.values,color='r')
  11. ax1.set_xlabel('Age')
  12. ax1.set_ylabel('Number')
  13. ax2.set_ylabel('Survival Rate')
  14. plt.title('Survival Rate by Age')
  15. plt.grid(True,linestyle='-',color='0.7')
  16. plt.show()

可以看到年龄主要在15~50岁左右,65~80岁死亡率较高,后面80岁存活率高是因为只有1人。

  • 相关性分析:

Parch、SibSp取值少,分布不均匀,不适合作为连续值来处理。可以将其分段化。这里分析一下Parch和SibSp与生存的关联性

  1. from sklearn.feature_selection import chi2
  2. print("Parch:", chi2(train_data.filter(["Parch"]), train_data['Survived']))
  3. print("SibSp:", chi2(train_data.filter(["SibSp"]), train_data['Survived']))
  4. # chi2(X,y) X.shape(n_samples, n_features_in) y.shape(n_samples,)
  5. # 返回 chi2 和 pval, chi2值描述了自变量与因变量之间的相关程度:chi2值越大,相关程度也越大,
  6. # http://guoze.me/2015/09/07/chi-square/
  7. # 可以看到Parch比SibSp的卡方校验取值大,p-value小,相关性更强。

4)数据预处理:

PassengerId 舍掉

Pclass为类目属性,3类。本身有序的,暂时不进行dummy coding

Name 为文本属性,舍掉,暂时不考虑

Sex为类目属性,2类。本身无序,进行dummy coding

Age为连续属性,确实较多可以用均值填充。幅度变化大。可以将其以5岁为step进行离散化或利用scaling将其归一化到[-1,1]之间

SibSp为连续属性,但比较离散,不适合按照连续值处理,暂时不用处理。或者可以按照其数量>3和<=3进行dummy coding

Parch为连续属性。但比较离散,不适合按照连续值处理,暂时不用处理。

Ticket为文本属性,舍掉,暂时不考虑

Fare为连续属性,幅度变化大,可以利用scaling将其归一化到[-1,1]之间

Cabin为类目属性,但缺失严重,可以按照是否缺失来0/1二值化,进行dummy coding

Embarked为类目属性,缺失值极少,先填充后进行dummy coding

综上,可用的数据特征有:Pclass,Sex,Age,SibSp,Parch,Fare,Cabin,Embarked

此外需注意的是,需对训练集和测试集的数据做同样的处理。

2.实例。

根据以上思路,一个小baseline诞生了:

  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from pandas import Series, DataFrame
  5. from sklearn.model_selection import train_test_split
  6. from sklearn.preprocessing import StandardScaler
  7. from sklearn.tree import DecisionTreeClassifier
  8. from sklearn.metrics import classification_report
  9. from learning_curve import *
  10. from pylab import mpl
  11. from sklearn.linear_model import LogisticRegression
  12. from sklearn.model_selection import cross_val_score
  13. mpl.rcParams['font.sans-serif'] = ['SimHei'] #使得plt操作可以显示中文
  14. from sklearn.feature_extraction import DictVectorizer
  15.  
  16. data_train = pd.read_csv('train.csv')
  17. data_test = pd.read_csv('test.csv')
  18.  
  19. feature = ['Pclass','Age','Sex','Fare','Cabin','Embarked','SibSp','Parch'] # 考虑的特征
  20.  
  21. X_train = data_train[feature]
  22. y_train = data_train['Survived']
  23.  
  24. X_test = data_test[feature]
  25.  
  26. X_train.loc[data_train['SibSp']<3, 'SibSp'] = 1 #按照人数3来划分
  27. X_train.loc[data_train['SibSp']>=3, 'SibSp'] = 0
  28. X_train['Age'].fillna(X_train['Age'].mean(), inplace=True)
  29. X_test.loc[data_test['SibSp']<3, 'SibSp']=1
  30. X_test.loc[data_test['SibSp']>=3, 'SibSp'] = 0
  31. X_test['Age'].fillna(X_test['Age'].mean(), inplace=True) # 缺失的年龄补以均值
  32. X_test['Fare'].fillna(X_test['Fare'].mean(), inplace=True)
  33. # X_train.loc[X_train['Age'].isnull(), 'Age'] = X_train['Age'].mean()
  34.  
  35. dummies_SibSp = pd.get_dummies(X_train['SibSp'], prefix='SibSp') #进行dummy coding
  36. dummies_Sex = pd.get_dummies(X_train['Sex'], prefix= 'Sex')
  37. dummies_Pclass = pd.get_dummies(X_train['Pclass'], prefix='Pclass')
  38. dummies_Emabrked = pd.get_dummies(X_train['Embarked'], prefix='Embarked')
  39.  
  40. ss=StandardScaler()
  41.  
  42. X_train.loc[X_train['Cabin'].isnull(), 'Cabin'] = 1
  43. X_train.loc[X_train['Cabin'].notnull(), 'Cabin'] = 0
  44. X_train['Age_new'] = (X_train['Age']/5).astype(int)
  45. X_train['Fare_new'] = ss.fit_transform(X_train.filter(['Fare']))
  46. X_train = pd.concat([X_train, dummies_Sex, dummies_Pclass, dummies_Emabrked, dummies_SibSp], axis=1)
  47. X_train.drop(['Age', 'Sex', 'Pclass', 'Fare','Embarked', 'SibSp'], axis=1, inplace=True)
  48.  
  49. dummies_SibSp = pd.get_dummies(X_test['SibSp'], prefix='SibSp')
  50. dummies_Sex = pd.get_dummies(X_test['Sex'], prefix= 'Sex')
  51. dummies_Pclass = pd.get_dummies(X_test['Pclass'], prefix='Pclass')
  52. dummies_Emabrked = pd.get_dummies(X_test['Embarked'], prefix='Embarked')
  53.  
  54. X_test['Age_new'] = (X_test['Age']/5).astype('int')
  55. X_test['Fare_new'] = ss.fit_transform(X_test.filter(['Fare']))
  56. X_test = pd.concat([X_test, dummies_Sex, dummies_Pclass, dummies_Emabrked, dummies_SibSp], axis=1)
  57. X_test.drop(['Age', 'Sex', 'Pclass', 'Fare','Embarked','SibSp'], axis=1, inplace=True)
  58. X_test.loc[X_test['Cabin'].isnull(), 'Cabin'] = 1
  59. X_test.loc[X_test['Cabin'].notnull(), 'Cabin'] = 0
  60.  
  61. dec = LogisticRegression() # logistic回归
  62. dec.fit(X_train, y_train)
  63. y_pre = dec.predict(X_test)
  64.  
  65. # 交叉验证
  66. all_data = X_train.filter(regex='Cabin|Age_.*|Fare_.*|Sex.*|Pclass_.*|Embarked_.*|SibSp_.*_Parch')
  67. X_cro = all_data.as_matrix()
  68. y_cro = y_train.as_matrix()
  69. est = LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
  70. print(cross_val_score(dec, X_cro, y_cro, cv=5))
  71.  
  72. # 保存结果
  73. # result = pd.DataFrame({'PassengerId':data_test['PassengerId'].as_matrix(), 'Survived':y_pre.astype(np.int32)})
  74. # result.to_csv("my_logisticregression_1.csv", index=False)
  75.  
  76. # 学习曲线
  77. plot_learning_curve(dec, u"学习曲线", X_train, y_train)
  78.  
  79. # 查看各个特征的相关性
  80. columns = list(X_train.columns)
  81. plt.figure(figsize=(8,8))
  82. plot_df = pd.DataFrame(dec.coef_.ravel(), index=columns)
  83. plot_df.plot(kind='bar')
  84. plt.show()
  85.  
  86. # 分析SibSp
  87. # survived_0 = data_train.SibSp[data_train['Survived']==0].value_counts()
  88. # survived_1 = data_train.SibSp[data_train['Survived']==1].value_counts()
  89. # df = pd.DataFrame({'获救':survived_1, '未获救':survived_0})
  90. # df.plot(kind='bar', stacked=True)
  91. # plt.xlabel('兄妹个数')
  92. # plt.ylabel('获救情况')
  93. # plt.title('兄妹个数与获救情况')
  94.  
  95. # 不加SibSp [ 0.70 0.80446927 0.78651685 0.76966292 0.79661017]
  96. # 加上SibSp [ 0.70 0.78212291 0.80337079 0.79775281 0.81355932]
  97.  
  98. # logistic:[ 0.78212291 0.80446927 0.78651685 0.76966292 0.80225989] why?

3.结果分析与总结

1)学习曲线函数:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from sklearn.model_selection import learning_curve
  4.  
  5. # 用sklearn的learning_curve得到training_score和cv_score,使用matplotlib画出learning curve
  6. def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None, n_jobs=1,
  7. train_sizes=np.linspace(.05, 1., 20), verbose=0, plot=True):
  8. """
  9. 画出data在某模型上的learning curve.
  10. 参数解释
  11. ----------
  12. estimator : 你用的分类器。
  13. title : 表格的标题。
  14. X : 输入的feature,numpy类型
  15. y : 输入的target vector
  16. ylim : tuple格式的(ymin, ymax), 设定图像中纵坐标的最低点和最高点
  17. cv : 做cross-validation的时候,数据分成的份数,其中一份作为cv集,其余n-1份作为training(默认为3份)
  18. n_jobs : 并行的的任务数(默认1)
  19. """
  20. train_sizes, train_scores, test_scores = learning_curve(
  21. estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes, verbose=verbose)
  22.  
  23. train_scores_mean = np.mean(train_scores, axis=1)
  24. train_scores_std = np.std(train_scores, axis=1)
  25. test_scores_mean = np.mean(test_scores, axis=1)
  26. test_scores_std = np.std(test_scores, axis=1)
  27.  
  28. if plot:
  29. plt.figure(1)
  30. plt.title(title)
  31. if ylim is not None:
  32. plt.ylim(*ylim)
  33. plt.xlabel(u"训练样本数")
  34. plt.ylabel(u"得分")
  35. plt.gca().invert_yaxis()
  36. plt.grid()
  37.  
  38. plt.fill_between(train_sizes, train_scores_mean - train_scores_std, train_scores_mean + train_scores_std,
  39. alpha=0.1, color="b")
  40. plt.fill_between(train_sizes, test_scores_mean - test_scores_std, test_scores_mean + test_scores_std,
  41. alpha=0.1, color="r")
  42. plt.plot(train_sizes, train_scores_mean, 'o-', color="b", label=u"训练集上得分")
  43. plt.plot(train_sizes, test_scores_mean, 'o-', color="r", label=u"交叉验证集上得分")
  44.  
  45. plt.legend(loc="best")
  46.  
  47. plt.draw()
  48. plt.show()
  49. plt.gca().invert_yaxis()
  50.  
  51. midpoint = ((train_scores_mean[-1] + train_scores_std[-1]) + (test_scores_mean[-1] - test_scores_std[-1])) / 2
  52. diff = (train_scores_mean[-1] + train_scores_std[-1]) - (test_scores_mean[-1] - test_scores_std[-1])
  53. return midpoint, diff

learning_curve.py

见下图:将learning_curve画出可以看到两者在0.8左右趋于平行,但是正确率不够高,应该是属于欠拟合。所以可以考虑加入新的特征,再对特征进行更深的挖掘 。

2)特征相关性分析图

  1. columns = list(X_train.columns)
  2. plt.figure(figsize=(8,8))
  3. plot_df = pd.DataFrame(dec.coef_.ravel(), index=columns)
  4. plot_df.plot(kind='bar')
  5. plt.show()

结果见下图:通过logistic学到的参数权重

性别、等级和亲属相关性较强,而亲属在前面已经了解到相关性并不强,所以可以对这一特征加以优化,例如将Parch+SibSp作为一个新特征。

其他特征或正相关或负相关,但都不太明显。

cabin怎么没有相关性呢?

3)交叉验证

  1. # 交叉验证
  2. all_data = X_train.filter(regex='Cabin|Age_.*|Fare_.*|Sex.*|Pclass_.*|Embarked_.*|SibSp_.*_Parch')
  3. X_cro = all_data.as_matrix()
  4. y_cro = y_train.as_matrix()
  5. est = LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
  6. print(cross_val_score(dec, X_cro, y_cro, cv=5))

每次通过训练集学习到参数后进行分类,但是怎么评价结果的好坏呢,可以利用交叉验证来实现,根据交叉验证的结果大致可以知道运用于测试集的结果。

这是本次测试的交叉验证结果:  [ 0.78212291 0.80446927 0.78651685 0.76966292 0.80225989]

实际提交到Kaggle上时候准确率为0.7751

参考

机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾

机器学习笔记(1)-分析框架-以Kaggle Titanic问题为例

机器学习一小步:Kaggle上的练习Titanic: Machine Learning from Disaster(一)

Kaggle 泰坦尼克的更多相关文章

  1. Kaggle泰坦尼克数据科学解决方案

    原文地址如下: https://www.kaggle.com/startupsci/titanic-data-science-solutions --------------------------- ...

  2. 逻辑回归应用之Kaggle泰坦尼克之灾(转)

    正文:14pt 代码:15px 1 初探数据 先看看我们的数据,长什么样吧.在Data下我们train.csv和test.csv两个文件,分别存着官方给的训练和测试数据. import pandas ...

  3. pytorch kaggle 泰坦尼克生存预测

    也不知道对不对,就凭着自己的思路写了一个 数据集:https://www.kaggle.com/c/titanic/data import torch import torch.nn as nn im ...

  4. python__画图表可参考(转自:寒小阳 逻辑回归应用之Kaggle泰坦尼克之灾)

    出处:http://blog.csdn.net/han_xiaoyang/article/details/49797143 2.背景 2.1 关于Kaggle 我是Kaggle地址,翻我牌子 亲,逼格 ...

  5. Kaggle泰坦尼克-Python(建模完整流程,小白学习用)

    参考Kernels里面评论较高的一篇文章,整理作者解决整个问题的过程,梳理该篇是用以了解到整个完整的建模过程,如何思考问题,处理问题,过程中又为何下那样或者这样的结论等! 最后得分并不是特别高,只是到 ...

  6. 逻辑回归应用之Kaggle泰坦尼克之灾

    机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾 标签: 机器学习应用 2015-11-12 13:52 3688人阅读 评论(15) 收藏 举报 本文章已收录于:  机器学习知识库  分类 ...

  7. Kaggle_泰坦尼克乘客存活预测

    转载 逻辑回归应用之Kaggle泰坦尼克之灾 此转载只为保存!!! ————————————————版权声明:本文为CSDN博主「寒小阳」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附 ...

  8. kaggle之泰坦尼克的沉没

    Titanic 沉没 参见:https://github.com/lijingpeng/kaggle 这是一个分类任务,特征包含离散特征和连续特征,数据如下:Kaggle地址.目标是根据数据特征预测一 ...

  9. 利用python进行泰坦尼克生存预测——数据探索分析

    最近一直断断续续的做这个泰坦尼克生存预测模型的练习,这个kaggle的竞赛题,网上有很多人都分享过,而且都很成熟,也有些写的非常详细,我主要是在牛人们的基础上,按照数据挖掘流程梳理思路,然后通过练习每 ...

随机推荐

  1. startSSL 申请免费的SSL证书

    打开网址https://www.startssl.com/?app=12,选择Sign-up注册. 输入个人注册信息 需注意以下几点:(1)地址必须详细,否则你会收到这样的邮件: Please pro ...

  2. 「THUSCH 2017」大魔法师 解题报告

    「THUSCH 2017」大魔法师 狗体面太长,帖链接了 思路,维护一个\(1\times 4\)的答案向量表示\(A,B,C,len\),最后一个表示线段树上区间长度,然后每次的操作都有一个转移矩阵 ...

  3. [luogu2114][起床困难综合症]

    luogu2114 思路 因为位运算对于每一位是独立的,所以对每一位都对这n个数进行操作,然后观察最后得出的是1还是0.并且保证每一位拼起来之后要比m小. 代码 #include<cstdio& ...

  4. springboot集成druid连接池

    使用druid连接池主要有几步: 1.添加jar和依赖 <groupId>org.mybatis.spring.boot</groupId> <artifactId> ...

  5. 在kubernetes中运行单节点有状态MySQL应用

    Deploy MySQL https://kubernetes.io/docs/tasks/run-application/run-single-instance-stateful-applicati ...

  6. Java需要强制捕获的异常

    Java编译器要求我们强制捕获Excetion,但不包括RuntimeException 不强制要求捕获Error和RuntimeException是因为,这两种异常我们程序一般无能为力,而其他Exc ...

  7. Python全栈问答小技巧_1

    Python全栈测试题 作者:尹正杰 声明:答案如有偏差,欢迎指正!欢迎加入高级运维工程师之路:598432640 本文答题用的Python版本是:Python 3.5.2,请知晓! 1.执行 Pyt ...

  8. Nginx的alias的用法及与root的区别

    以前只知道Nginx的location块中的root用法,用起来总是感觉满足不了自己的一些想法.然后终于发现了alias这个东西. 先看toot的用法 location /request_path/i ...

  9. 如何下载网易云音乐APP里的MV和短视频?

    本人:网易云音乐死粉,朋友圈大多都用的是云音乐,因为推荐功能牛逼 然后:发现云音乐APP里越来越多吸引我的短视频,经常看到好的就想保存到相册,然后微信发给朋友 但是:不知道怎么下载网易云音乐的短视频, ...

  10. SQL记录-PLSQL基本语法与数据类型

    PL/SQL基本语法 PL/SQL是一种块结构的语言,这意味着PL/SQL程序被划分和编写代码的逻辑块.每块由三个子部分组成: S.N. 段和说明 1 声明 此部分开头使用关键字DECLARE.它是一 ...