Kagle Titanic: Machine Learning from Disaster 特征工程+PCA+SVM 前17%


https://www.kaggle.com/c/titanic


特征工程

鉴于自己后来的模型融合的尝试,发现特征工程还是最最有效的手段,这里主要是用到离散化的处理。

  • Name特征
    提取出Mr,Miss等称呼特征,直接离散化。虽然还可以根据它的条件概率或其他一些文化特征再进行归类,但是当时没有进行后续处理,只是简单的提出然后离散。
    #处理Name信息
    name = df.values[:, 3].astype(str)
    for i in range(len(name)) :
        temp = name[i].split(",")[1]
        name[i] = temp.split(".")[0]
    a_set = []
    for i in range(len(name)):
        if name[i] in a_set: pass
        else:
            a_set.append(name[i])
    refer = {}
    for i in range(len(a_set)):
        refer[a_set[i]] = i
    for i in range(len(name)):
        name[i] = int(refer[name[i]])
    name = name.astype(int)
  • Pclass特征
    这个特征没有缺失值,而且比较简单直白,数据之间有大小关系,没什么要处理的
#处理Pclass属性,[1, 2, 3]
pclass = df.values[:, 2].astype(int)
  • Sex特征
    也是直接离散处理
    #处理Sex属性,[0 : male, 1 : female]
    refer = {'male':0, 'female':1}
    sex = df.values[:, 4]
    for i in range(891) :
        sex[i] = refer[sex[i]]
  • Age特征
    先可视化,这样比较直白
    可视化的代码如下:
#联合散点图
def col_scatter(survived, p1, p2, s1, s2) :
    scatter1_x = []
    scatter1_y = []

    scatter0_x = []
    scatter0_y = []
    for i in range(891) :
        if survived[i] == 0 :
            scatter0_x.append(p1[i])
            scatter0_y.append(p2[i])
        else :
            scatter1_x.append(p1[i])
            scatter1_y.append(p2[i])

    plt.scatter(scatter0_x, scatter0_y, marker='+', color='r')
    plt.scatter(scatter1_x, scatter1_y, marker='+', color='c')
    plt.xlabel(s1)
    plt.ylabel(s2)
    plt.show()

结果图:
sex_sex.png
可见大概15,65是个分界点
处理代码:

    #处理age信息
    age = pd.DataFrame(df.values[:, 5])
    age = age.fillna(age.mean()).astype(int)
    for i in range(len(age)):
        if age[0][i] < 15:
            age[0][i] = 0
        elif age[0][i] > 65 :
            age[0][i] = 2
        else :
            age[0][i] = 1
  • Slibsp特征
    先查看对应特征的条件概率,即对应特征属性的存活率
# slibsp各属性的条件概率
# 0:    0.3453
# 1:    0.5358
# 2:    0.4642
# 3:    0.25
# 4:    0.1666
# 5:    0.0
# 8:    0.0
def show_sibsp(df) :
    content = [0, 1, 2, 3, 4, 5, 8]
    for i in range(len(content)) :
        print(df.SibSp[(df.SibSp==content[i])&(df.Survived==1)].size / df.SibSp[df.SibSp==content[i]].size)

因为比较小白,所以根据存活率手动归类

    #处理SibSp信息
    #message.show_slibsp(df)
    refer = {
        '0': 1,
        '1': 2,
        '2': 2,
        '3': 1,
        '4': 1,
        '5': 0,
        '8': 0,
    }
    sibsp = df.values[:, 6]
    for i in range(891) :
        sibsp[i] = refer[str(sibsp[i])]

后面预测的时候会出现一些在训练集不会出现的属性,但根据规律可以把它归在最小的一类

  • Parch特征
    处理方法类似sibsp
# parch各属性的条件概率
# 0:    0.3436
# 1:    0.5508
# 2:    0.5
# 3:    0.6
# 4:    0.0
# 5:    0.2
# 6:    0.0
def show_parch(df) :
    content = [0, 1, 2, 3, 4, 5, 6]
    for i in range(len(content)) :
        print(df.Parch[(df.Parch==content[i])&(df.Survived==1)].size / df.Parch[df.Parch==content[i]].size)
    #处理Parch信息
    #message.show_parch(df)
    refer = {
        '0': 1,
        '1': 2,
        '2': 2,
        '3': 2,
        '4': 0,
        '5': 1,
        '6': 0,
    }
    parch = df.values[:, 7]
    for i in range(891) :
        parch[i] = refer[str(parch[i])]
  • Fare特征
    跟Age处理方法类似,这里不累述
    能得到一个大概6和80的分界

  • Embarked特征
    如果是简单的离散化,例如0,1,2的连续特征,但是这些特征之间并没有大小关系,模型可能会学习到他们之间的关系(我猜的)。所以用另外一种方法,叫什么虚拟参数来着,就是离散成(0,0,1),(0,1,0)类似的,这样就不会学到大小的特征

  • Cabin特征
    依稀记得这个特征值缺失值比较多,参考别人的想法可能工作人员没有具体的房间,所以用另外的值统一替代。

模型

  • 用GBDT,n=100,结果大概是0.78947
  • 用PCA加SVM(‘mle’),结果大概是0.80383

总结

1.刚开始以为GBDT是最好的解决方法,但是可能特征处理的时候太离散化了,所以有PCA加svm的效果竟然比GBDT跟好。
2.后续的进步方法:处理ticket中的隐藏信息,可能一些数字的排列方法或者字母会隐含一些其它的有用信息。
3.后续的进步方法:还有就是做特征派生,就是特征之间的组合或相乘等运算,这个还没学到。

补充代码:(因为前后用了两个模型,可能代码有点没有完全注释掉,不过应该可以看出来。还有就是message是另外用来处理训练集和测试集的函数,是上面代码片段的组合吧)

import pandas as pd 
import numpy as np 
import math
import message
import re
from sklearn.cross_validation import cross_val_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.decomposition import PCA
from sklearn import svm

df1 = pd.read_csv('train.csv', header=0)
df2 = pd.read_csv('test.csv')

survived = df1.values[:, 1].astype(int)

train = message.normal_train(df1)
test = message.normal_test(df2)
testId = df2.values[:, 0].astype(int)

clf = GradientBoostingClassifier(n_estimators=100)
pca = PCA('mle')
newtrain = pca.fit_transform(train, survived)
clf = svm.SVC().fit(newtrain, survived)

score = cross_val_score(clf, newtrain, survived)
print(score)
# clf.fit(train, survived)
newtest = pca.transform(test)
result = clf.predict(newtest)

np.savetxt('submission_pca_gbdt.csv', np.c_[testId, result], 
    delimiter=',', header='PassengerId,Survived', comments='', fmt='%d')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值