您的位置:首页 > 其它

机器学习-Kaggle竞赛-Titanic

2015-07-18 11:55 387 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: