kaggle实战之Titanic (1)-预处理

数据挖掘的知识可知,数据预处理包括:
(1) 数据清理:填写缺失值,光滑噪声数据等等。
(2) 数据集成:将多个数据源合成一个数据源。此处只有1个csv文件,过
(3) 数据变换:平滑聚集,数据概化等。
(4) 数据规约: 目的是减小数据量,同时又不影响结果。此处数据共891<1000行,暂不处理

PassengerId 旅客ID
Survived 是否活下来了,1:yes 0:no
Pclass 旅客等级 1 2 3 依据某博客的分析可以基本认为与票价Fare正相关
Name 名字
Sex 性别
Age 年龄
SibSp 有多少兄弟姐妹/配偶同船
Parch 有多少父母/子女同船
Ticket 船票号码
Fare 船票收费
Cabin 所在小屋
Embarked 登船城市 C Q S 分别代表不同的城市
对该实际问题,妇女、儿童和上层阶级更容易幸存,而年龄代表身体素质,父母兄弟可以互助,但此处父母对于儿童是“正”,对于中青年是“负”,房间位置与碰撞时的角度有关也影响存活率,而以下将会重点对这几项进行处理。

1、数据清理
首先通过excel表格发现Age, Cabin, Embarked字段有空值需要填充:Age属性考虑使用平均值29.69911765记为30,Cabin房间号的值各不相同,观察所有幸存者并未发现明显规律,只好暂不使用该“幸运”因素。Embarked直观上与存活率关系不大,观察发现S市644人,空白2人,以多数填充方式处理
以上直接在csv文件中处理
2、数据变换
SibSp 8=7 5=5 4=18 3=16 2=28 共74个 < 100看做一类 记 0,1,2
Parch 2、3、4、5、6共95个也看做一类 记 0,1,2
Age 以[0:16), [16:40),[40:99)离散化处理
Fare 票价与Pclass和Parch、SibSp相关,亲朋通常会入住同一房间
Embarked S计0,C记1,Q记2
Sex 男记1,女记2

至此,共Pclass,Sex, Age , SibSp, Parch, Embarked 6类特征,加上Survived为target,提取如下:

#读文件
def load_data(filename):
    csvfile = file(filename, 'rb')
    reader = csv.reader(csvfile)
    datafile = []
    for line in reader:
        datafile.append(line)
        #print line
    csvfile.close()
    return datafile

#预处理
def data_clean(datafile):
    l = len(datafile)
    print l
    target = [0 for i in range(l)]
    datamat = [[0 for j in range(6)] for i in range(l)]
    for i in range(l):
        datamat[i][0] = int(datafile[i][1]) #C
        if(datafile[i][3] == 'male'):
             datamat[i][1] = 1
        else:
            datamat[i][1] = 2#m
        t5 = int(datamat[i][4])
        if((0 < t5) and (t5 < 15)):
            datamat[i][1] = 0
        elif(15<=t5 and t5<40):
            datamat[i][1] = 1 
        elif(40<=t5 and t5<100):
            datamat[i][1] = 2 #A
        if(datafile[i][5]>=2):
             datamat[i][3] = 2
        else:
             datamat[i][3] = datafile[i][5]#S
        if(datafile[i][6]>=2):
             datamat[i][4] = 2
        else:
             datamat[i][4] = datafile[i][6]#P
        if(datafile[i][10] == 'S'):
             datamat[i][5] = 0
        elif(datafile[i][10] == 'C'):
            datamat[i][5] = 1
        else:
            datamat[i][5] = 2#E
        target[i] = datafile[i][11]
        #print target[i], datamat[i]
    return target, datamat

粗略实现后提交,准确率0.77,排名。。。还需提高

补充:

采用不同分类器发现效果并没有太大提升,重新考虑特征提取:
1、房间所在位置 应当是重要因素,但从房间号并未发现明显特征;
2、添加新特征家庭成员数量=S+P+1,感觉无效
3、添加是否是带婴母亲:female、parch!=1、age>20&<50 (粗略)
4、添加是否是儿童:parch!=1、age<18
5、年龄使用平均值太简陋,考虑使用决策树填充,训练过程与上面相似,从略
6、参考高分答案添加title属性,从姓名中提取该数据的称谓“Mr\Mrs..”;

最终定格在0.789左右,蛋疼。。。

def data_clean(datafile):
    l = len(datafile)
    print l
    target = [0 for i in range(l)]
    datamat = [[0 for j in range(10)] for i in range(l)]
    for i in range(l):
        #Pclass
        datamat[i][0] = int(datafile[i][1])
        #male
        if(datafile[i][3] == 'male'):
            datamat[i][1] = 1
        else:
            datamat[i][1] = 2
        t5 = int(datamat[i][4])
        #Age
        if((0 < t5) and (t5 < 16)):
            datamat[i][1] = 0
        elif(16<=t5 and t5<40):
            datamat[i][1] = 1
        elif(40<=t5 and t5<100):
            datamat[i][1] = 2 
        #S
        if(datafile[i][5]>=2):
             datamat[i][3] = 2
        else:
             datamat[i][3] = datafile[i][5]
        #P
        if(datafile[i][6]>=2):
             datamat[i][4] = 2
        else:
             datamat[i][4] = datafile[i][6]
        #E
        if(datafile[i][10] == 'S'):
             datamat[i][5] = 0
        elif(datafile[i][10] == 'C'):
            datamat[i][5] = 1
        else:
            datamat[i][5] = 2
        ###
        #mother
        if(datafile[i][3] == 'female' and 20<=t5 and t5<50 and datafile[i][6] > 0):
             datamat[i][6] = 1
        else:
             datamat[i][6] = 0
        #FamilySize
        datamat[i][7] = int(datafile[i][5]) + int(datafile[i][6]) + 1
        #Child
        if(t5 < 16 and datafile[i][6] > 0):
             datamat[i][8] = 1
        else:
             datamat[i][8] = 0
        #Title from Name
        datamat[i][9] = replace_titles(datafile[i][3],txt_wrap_by(',','.',datafile[i][2]))
        target[i] = datafile[i][11]
        #print target[i], datamat[i]
    return target, datamat

def replace_titles(s,title):
        if title in ['Mr', 'Don', 'Major', 'Capt', 'Jonkheer', 'Rev', 'Col']:
            return 1#'Mr'
        elif title in ['Master']:
            return 4#'Master'
        elif title in ['Countess', 'Mme','Mrs']:
            return 2#'Mrs'
        elif title in ['Mlle', 'Ms','Miss']:
            return 3#'Miss'
        elif title == 'Dr':
            if s == 'male':
                return 1#'Mr'
            else:
                return 2#'Mrs'
        else:
            if s == 'male':
                return 4#'Master'
            else:
                return 3#'Miss'

def txt_wrap_by(start_str, end, html):
    start = html.find(start_str)
    if start >= 0:
        start += len(start_str)
        end = html.find(end, start)
        if end >= 0:
            return html[start:end].strip()

你可能感兴趣的:(Kaggle,数据竞赛)