kaggle 泰坦尼克LogisticRegression撸一遍

kaggle入门,跟着牛人博客撸模型
博客地址:
http://blog.csdn.net/han_xiaoyang/article/details/49797143
原文的代码有个小问题,边学边调,收获颇丰。

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
"""
第一步,看数据
1、查看数据基本摘要,知道都有些什么属性,大概是什么
2、通过画图,找关系,了解属性对结果的影响,找特征
"""
data_train = pd.read_csv('/Users/lee/Desktop/ml/titanic/train.csv')
data_test = pd.read_csv('/Users/lee/Desktop/ml/titanic/test.csv')

#1、查看数据摘要
#命令行输入或打印
#data_train.info() 

#2、画图,画各种可以想象到的图

fig1 = plt.figure(1) #创建画板,并且指向最后一张纸
fig1.set(alpha = 0.2) #color
plt.subplot2grid((4,2),(0,0)) #rows=2 clos=3 begin at (0,0)
#value_counts()是pandas中的顶级方法,用于任何数组或序列
data_train.Survived.value_counts().plot(kind='bar')
plt.title(u"survived") #标题 unic编码
plt.ylabel(u"number")
plt.subplot2grid((4,2),(0,1))
data_train.Pclass.value_counts().plot(kind='bar')

plt.title('Pclass')
plt.subplot2grid((4,2),(1,0))
data_train.Sex.value_counts().plot(kind='bar')
plt.title('Sex')
plt.subplot2grid((4,2),(1,1))
data_train.SibSp.value_counts().plot(kind='bar')
plt.title('SibSp')
plt.subplot2grid((4,2),(2,0))
data_train.Parch.value_counts().plot(kind='bar')
plt.title('Parch')

plt.subplot2grid((4,2),(2,1))
data_train.Fare.apply(np.round).value_counts().plot(kind='bar')
plt.title('Sex')
plt.subplot2grid((4,2),(3,0))
data_train.Embarked.value_counts().plot(kind='bar')
plt.title('Embarked')
#plt.xlabel(u"x轴")

"""
第二步 数据预处理(特征工程)
1、补全缺失数据
2、无量纲化
3、处理定性特征(哑编码)
特征工程在jasonfreak的博客里写的很多
博客地址:http://www.cnblogs.com/jasonfreak/p/5448385.html
另:要对traindata和testdata做同样的处理
我觉得这里写成函数会比较方便,下一次改进
"""

#1、补全缺失的年龄
from sklearn.preprocessing import Imputer
def set_age_fill(df):    
    AgeFill = Imputer(axis=1).fit_transform((df.index,df.Age))
    df.loc[:,'Age'] = AgeFill[1].T
    return df
AgeFill = set_age_fill(data_train)
AgeFill2 = set_age_fill(data_test)
#test 数据fare缺了一个值
def set_fare_fill(df):    
    AgeFill = Imputer(axis=1).fit_transform((df.index,df.Age))
    df.loc[:,'Fare'] = AgeFill[1].T
    return df
AgeFill2 = set_fare_fill(data_test)

#Cabin也有缺失,粗略的就用Yes表示有数据,No表示缺失
def set_Cabin_type(df):
    #df.loc() 根据标签选取列
    #参数为选取规则[行规则,列规则]
    df.loc[(df.Cabin.notnull()),'Cabin'] = 'Yes'
    df.loc[(df.Cabin.isnull()),'Cabin'] = 'No'
    return df
cabinFill = set_Cabin_type(AgeFill)
cabinFill2 = set_Cabin_type(AgeFill2)

# =============================================================================
# #2、哑编码
# from sklearn.preprocessing import OneHotEncoder
# one = OneHotEncoder().fit_transform(data_train)
# 这个方法单独试能运行,不过没在这里面用
# 这里用的另一种
# =============================================================================

#哑编码因子化
#get_dummies()将传入数组做OneHotEncoder
#prefix参数是输出列的名字
dummies_Cabin = pd.get_dummies(cabinFill['Cabin'],prefix='Cabin')
dummies_Embarked = pd.get_dummies(cabinFill['Embarked'],prefix='Embarked')
dummies_Sex = pd.get_dummies(cabinFill['Sex'],prefix='Sex')
dummies_Pclass = pd.get_dummies(cabinFill['Pclass'],prefix='Pclass')

dummies_Cabin2 = pd.get_dummies(cabinFill2['Cabin'],prefix='Cabin')
dummies_Embarked2 = pd.get_dummies(cabinFill2['Embarked'],prefix='Embarked')
dummies_Sex2 = pd.get_dummies(cabinFill2['Sex'],prefix='Sex')
dummies_Pclass2 = pd.get_dummies(cabinFill2['Pclass'],prefix='Pclass')

#合并函数
#axis=1 列拼接
#inplace=True, 直接修改原数组名的数据
df = pd.concat([cabinFill, dummies_Cabin,dummies_Embarked,dummies_Sex,dummies_Pclass],axis=1)
df.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'],axis=1,inplace=True)

df2 = pd.concat([cabinFill2, dummies_Cabin2,dummies_Embarked2,dummies_Sex2,dummies_Pclass2],axis=1)
df2.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'],axis=1,inplace=True)

#3、归一化
#还没弄明白为什么StandardScaler后面的参数不可以是一维数组
#这里原文代码运行不了,自己改成这样
from sklearn.preprocessing import StandardScaler

dd = pd.concat([cabinFill['Age'],cabinFill['Fare']],axis=1)
a = StandardScaler().fit_transform(dd)
#!!transform之后的数据是array没有index
#用concat操作之后的df没有叫Age的列
#df = pd.concat([df,a],axis=1)
df['Age'] = a[:,0]
df['Fare'] = a[:,1]

dd2 = pd.concat([cabinFill2['Age'],cabinFill2['Fare']],axis=1)
a2 = StandardScaler().fit_transform(dd2)
df2['Age'] = a2[:,0]
df2['Fare'] = a2[:,1]

"""
第三步、撸出一个Baseline
1、提取特征字段
2、用traindata训练模型
3、预测
这里用的Logistic Regression,这一步做出来的是BaseLine,作为后续改进的参考
"""

from sklearn.linear_model import LogisticRegression

#1、提取特征字段转换为numpy

#filter 参数regex 指用正则表达式筛选
train_df = df.filter(regex='Survived|Age|SibSp|Parch|Fare|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')

test_df = df2.filter(regex='Survived|Age|SibSp|Parch|Fare|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')

#转化为矩阵形式
train_np = train_df.as_matrix()
#y 存活结果
y = train_np[:,0]
#x 特征值
X = train_np[:,1:]

#2、训练模型
# 参数penalty 解决过拟合的惩罚项,默认l2
# C 正则化参数
# l1是在l2正则化之后还过拟合,或者想要让不重要的特征系数归零,让模型系数稀疏化的时候使用
# tol 容忍度
# solver 优化方法
# 1)liblinear:使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。 
# 2)lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。 
# 3)newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。 
# 4)sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度,适合于样本数据多的时候,SAG是一种线性收敛算法,这个速度远比SGD快。 
# 注:从上面的描述可以看出,newton-cg, lbfgs和sag这三种优化算法时都需要损失函数的一阶或者二阶连续导数,因此不能用于没有连续导数的L1正则化,只能用于L2正则化。而liblinear通吃L1正则化和L2正则化。
# http://blog.csdn.net/code_caq/article/details/72027012

clf = LogisticRegression(C=1.0,penalty='l1',tol=1e-6)
# clf 即为模型
clf.fit(X,y)

#3、预测
predictions = clf.predict(test_df)
result = pd.DataFrame({'PassengerId':data_test['PassengerId'].as_matrix(),'Survived':predictions.astype(np.int32)})
result.to_csv('/Users/lee/Desktop/ml/titanic/result.csv',index=False)


"""
第四步、评估Base Line
接下来要对Baseline进行升级,升级前要评估、检测
1、相关系数分析
2、交叉验证(重要)
3、分析badcase
4、过拟合、欠拟合检查
"""

#1、看相关系数
#命令行输入或者print
pd.DataFrame({'cloumns':list(train_df.columns)[1:],'coef':list(clf.coef_.T)})
#可能是我前面处理age和fare不一样,所以得到的系数和原文有差距,不过不大

#2、交叉验证
#通过交叉验证检查模型的准确度
#命令行输入或者print
#第一个参数是分类器,cv是不同的交叉验证方法,int对象用5
from sklearn import model_selection
model_selection.cross_val_score(clf,X,y,cv=5)

#3、数据分割,人工查看bad case
#从bad case和属性的实际意义出发,再找特征
#找到新特征,再来一遍一二三四

split_train, split_cv = model_selection.train_test_split(df,test_size=0.3,random_state=0)
train_df = split_train.filter(regex='Survived|Age|SibSp|Parch|Fare|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
#生成模型
clf = LogisticRegression(C=1.0,penalty='l1',tol=1e-6)
clf.fit(train_df.as_matrix()[:,1:],train_df.as_matrix()[:,0])
#预测
cv_df = split_cv.filter(regex='Survived|Age|SibSp|Parch|Fare|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
predictions = clf.predict(cv_df.as_matrix()[:,1:])

origin_data = data_train
bad_cases = origin_data.loc[origin_data['PassengerId'].isin(split_cv[predictions != cv_df.as_matrix()[:,0]]['PassengerId'].values)]


#4、检验学习曲线,看交叉验证是否过拟合或者欠拟合
from sklearn.model_selection import learning_curve
#自定义函数
#计算training_score 和 cv_score 并把结果画图
def plot_learning_curve(estimator, title, X, y, ylim=None, cv = None, n_jobs=1,
                        train_sizes=np.linspace(.05,1.,20),verbose=0,plot=True):

#     画出data在某模型上的learning curve.
#     参数解释
#     ----------
#     estimator : 你用的分类器。
#     title : 表格的标题。
#     X : 输入的feature,numpy类型
#     y : 输入的target vector
#     ylim : tuple格式的(ymin, ymax), 设定图像中纵坐标的最低点和最高点
#     cv : 做cross-validation的时候,数据分成的份数,其中一份作为cv集,其余n-1份作为training(默认为3份)
#     n_jobs : 并行的的任务数(默认1)

    train_sizes, train_scores, test_scores = learning_curve(
            estimator, X,y,cv,n_jobs=n_jobs, train_sizes=train_sizes,verbose=verbose)
    train_scores_mean = np.mean(train_scores, axis=1)
    train_scores_std = np.std(train_scores, axis=1)
    test_scores_mean = np.mean(test_scores, axis=1)
    test_scores_std = np.std(test_scores, axis=1)
    if plot:
        plt.figure()
        plt.title(title)
        if ylim is not None:
            #*表示接受任意多个非关键字参数
            plt.ylim(*ylim)
        plt.xlabel('Samples')
        plt.ylabel('Score')
        #坐标轴反向
        plt.gca().invert_yaxis()
        plt.grid()
        
        plt.fill_between(train_sizes,train_scores_mean-train_scores_std,
                         train_scores_mean+train_scores_std,alpha=0.1,color='b')
        plt.fill_between(train_sizes,test_scores_mean-test_scores_std,
                         test_scores_mean+test_scores_std,alpha=0.1,color='r')
        plt.plot(train_sizes,train_scores_mean,'o-',color='b',label='trainScore')
        plt.plot(train_sizes,test_scores_mean,'o-',color='r',label='crossScore')
        #参数loc 调整legend的位置
        plt.legend(loc='best')
        plt.draw()
        plt.gca().invert_yaxis()
    #不理解这两个值是干嘛的
    midpoint = ((train_scores_mean[-1]+train_scores_std[-1])+(test_scores_mean[-1]-
                 test_scores_std[-1]))/2
    diff = (train_scores_mean[-1] + train_scores_std[-1]) - (test_scores_mean[-1] -
           test_scores_std[-1])
    return midpoint,diff

#midpoint,diff = plot_learning_curve(clf,u"学习曲线",X,y)   

"""
第五步、升级——模型融合(重要)
模型融合是指:采用多个模型进行预测,输出最靠谱的那一个
模型不够数据来凑,数据不够数学来凑
"""
#模型融合 ensemble
#当不会用多个模型的时候,可以通过数据
#不同的数据训练出来的模型不同
from sklearn.ensemble import BaggingRegressor

train_df = df.filter(regex='Survived|Age|SibSp|Parch|Fare|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
train_np = train_df.as_matrix()
y = train_np[:,0]
x = train_np[:,1:]
clf = LogisticRegression(C=1.0,penalty='l1',tol=1e-6)
#应用到BaggingRegressor中
#参数 n_estimators 子模型的个数
#max_samples 从x_train抽取去训练基估计器的样本数量。int 代表抽取数量,float代表抽取比例
#bootstrap  决定样本子集的抽样方式(有放回和不放回)
bagging_clf = BaggingRegressor(clf,n_estimators=20,max_samples=0.8,max_features=
                               1.0, bootstrap=True,bootstrap_features=False,n_jobs=1)
bagging_clf.fit(x,y)
test = df2.filter(regex='Age|SibSp|Parch|Fare|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
predictions = bagging_clf.predict(test)
result = pd.DataFrame({'PassengerId':data_test['PassengerId'].as_matrix(), 'Survived':predictions.astype(np.int32)})
result.to_csv('/Users/lee/Desktop/ml/titanic/ensemble.csv',index=False)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容