机器学习-Kaggle竞赛-Titanic

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/maple1149/article/details/46940607

1912.04.15 泰坦尼克号沉没,成为人类历史上重大海难事件之一。
……
没有足够的救生船,以及部分船没有载满就离开了。导致了大量的游客遇难。
根据幸存者的信息,试图寻找哪些人更容易逃生~~

信息解读

train.csv test.csv
首先下载2个数据文件。
这里写图片描述

  • PassengerId//游客id
  • Survived//1幸存
  • Pclass//1 2 3 表示社会地位
  • Name//姓名
  • Sex//性别
  • Age//年龄
  • SibSp//同船上的兄弟、姐妹数量
  • Parch//父母 子女数量
  • Ticket//船票号码
  • Fare//花费金额
  • Cabin//船舱号码
  • Embarked//S C Q 上船地点

特征工程

这里的数据有很多是缺失的,比如Age、Fare,用其他游客的平均值来填充。不过是按照 Pclass 分开来填充。这些操作是在excel中完成的。
首先我们假设这里影响逃生的因素有,Pclass,Sex,Age,SibSp,Parch,Fare.
对这些字段进行归一化处理~

def Sex(sex):
    if sex == 'male':
        return -1
    return 1
def Age(age):
    if float(age)<15:
        return 1
    elif float(age)<35:
        return 2
    elif float(age)<60:
        return 3
    else:
        return 4
def Fare(fare):
    if fare == '':
        return 2
    if float(fare)<10:
        return 1
    elif float(fare)<20:
        return 2
    elif float(fare)<30:
        return 3
    else:
        return 4

对于这里的SibSp,Parch,累加在一起作为新的 FamilySize字段。

Logistic regression(逻辑回归)

尝试使用逻辑回归算法预测~~
code

def preprocess(data,istest=False):#数据预处理
    dat = np.mat(data)
    dat = np.delete(dat,0,0)#delete head line
    for i in range(len(dat)):
        if dat[i,5] == '':
            dat[i,5]=0
    tt=dat[:,5].astype(float)
    surval=''    
    if istest:
        surval=''
    else:
        surval = dat[:,1].astype(int).transpose().tolist()[0]
    #surval = list(dat[:,1].astype(int))
    avrage=tt[np.nonzero(tt)].mean()
    #avrage = dat[:,5][np.nonzero(dat[:,5])].astype(float).mean()
    ret = np.zeros((dat.shape[0],6))
    for i in range(len(dat)):
        ret[i,0]=dat[i,2].astype(int)#Pclass
        ret[i,1]=Sex(dat[i,4])#Sex
        age = dat[i,5]
        if age =='':
            ret[i,2]=Age(avrage)
        else:
            ret[i,2]=Age(age)
        ret[i,3]=FamilyCount(float(dat[i,6])+float(dat[i,7]))
        ret[i,4]=Fare(dat[i,9])
        if Sympol_id(dat[i,3]):
            ret[i,5]=1
    return ret,surval

def sigmod(x):
    return 1/(1+exp(-x))

def classfy0(datamat,weight):
    if sigmod(datamat*weight)>0.5:
        return True
    return False

def stocalcgrand(dataMatin,labelMatin):
    m,n=np.shape(dataMatin)
    alpha=0.01
    weight=np.ones(n)
    for i in range(m):
        h=sigmod(sum(dataMatin[i]*weight))
        error=labelMatin[i]-h
        weight=weight+alpha*error*dataMatin[i]
    return weight

def testlogre():
    dat=loadcsv('train.csv')
    ret,surval=preprocess(dat)
    we=stocalcgrand(ret,surval)
    test=loadcsv('test.csv')
    testret,surval=preprocess(test,True)
    testret=np.mat(testret)
    we=np.mat(we).transpose()
    for i in range(len(testret)):
        if classfy0(testret[i],we):
            print '1'
        else:
            print '0'

这么小段代码改了好几遍。从0.736840.77990~每次提升一点点都好难~。不过这个成绩并不理想~

优化

网上看到有人把名字信息也用起来了,因为名字里有很多的称号,比如 爵位,军衔等。(titanic-getting-started-with-r-part-4-feature)
提取名字信息代码:

def splitname(data):
    ret={}
    for v in data:
        tmp=re.split('[,.]',v)#第一个",."之后就是称号了
        if len(tmp)<2:
            continue
        key=tmp[1].strip()
        ret[key]=ret.get(key,0)+1
    print ret

这里能看到有很多的称呼,但是哪些称呼表示地位显赫,更能逃生呢,这个就要一个一个来看,好在特殊的称号不多,大多是Mr.Mrs。。。
我这里选取了部分称号,认为地位显赫~~~~

def Sympol_id(name):
    ret={'Sir': 1, 'Major': 2, 'the Countess': 1, 'Mlle': 2, 'Capt':1, 'Dr': 7, 'Lady': 1, 'Master': 40, 'Mme': 1,}
    tmp=re.split('[,.]',name)
    if len(tmp)<2:
        return False
    key=tmp[1].strip()
    if ret.has_key(key):
        return True
    return False

Sir:爵士
the Countess:伯爵夫人
Dr:博士,医生

那么添加这么一个特征之后,确实提升了一点点
0.77990–>0.78469
人肉看到了下,修正了2个值~~ 不容易啊。
大家如果有更好的特征处理,算法优化建议,可以留言一起学习下~~ -.-

参考

https://www.kaggle.com/c/titanic
http://trevorstephens.com/post/73461351896/titanic-getting-started-with-r-part-4-feature

没有更多推荐了,返回首页