完整代码: https://github.com/cindycindyhi/kaggle-Titanichtml
特征工程系列:git
Titanic系列之原始数据分析和数据处理github
缺失值填充以后,就要对其余格式有问题的属性进行处理了。好比Sex Embarked这些属性的值都是字符串类型的,而scikit learn中的模型都只能处理数值型的数据,须要将这些原始的字符串类型的数据转为数值型数据。全部数据一般能够分红两种类型:定量与定性。定量的属性(数值属性)一般蕴涵着可排序性,好比在泰坦尼克号数据集中,年龄就是一个定量属性。定性属性(标称 序数 二元属性)的值是一些符号或事务的名称,每一个值表明某种类别编码或状态,不是可测量量,是不具备排序意义的,好比Embarked(登船地点)。ide
一 定性属性的数据变换函数
对于字符串型的定性属性转换,若是单纯的用数字来代替的化,好比对于Embarked的三个值S Q C分别用1 2 3来代替,模型会把它当成是有顺序的数值属性,对于一些根据距离来肯定分类的算法来讲,就不能准确运行啦。那么应该怎么将定性属性转为数字呢?编码
(1)dummy varibles(不知道中文应该说成啥。。虚设属性?)spa
什么是dummy呢,举个栗子,Emarked属性的取值有三个S Q C,分别表明三个上船地点。dummy这个属性呢,就是向数据集里再加入三个属性暂且命名为Embarked_S Embarkde_Q 和Embarked_C,若是一我的是在S地点上船的,那么这三个属性的值就是(1,0,0),在Q点上船的就是(0,1,0),每一个属性都是二元属性,1表明是,0表明否。因此dummy适用于值范围相对较少的属性。code
1 import pandas as pd
#creat dummy varibles from raw data 2 dummies_df = pd.get_dummies(df.Embarked) 3 #remana the columns to Embarked_S... 4 dummies_df = dummies_df.rename(columns=lambda x:'Embarked_'+str(x)) 5 df = pd.concat([df,dummies_df],axis=1)
这样就会3个dummy属性加到数据集里啦,用df.info()看一下:
(2)factorizing(因子分解?)
用dummy能够处理像Embarked这样的值域范围较小的标称属性。对于Cabin(船舱号,A43 B55这种)这种标称属性,用dummy就很差处理了。pandas提供了一个factorize()函数,用以将标称属性的字符串值映射为一个数字,相同的字符串映射为同一个数字。不一样于dummy,这种映射最后只生成一个属性。对于Cabin属性,咱们能够将其分红两部分,字符串+数字,新建两个属性。对于字符串(A-E & U),能够用factorize()将其处理成数字。
1 import re 2 df['CabinLetter'] = df['Cabin'].map( lambda x: re.compile("([a-zA-Z]+)").\ 3 search(x).group() ) 4 df['CabinLetter'] = pd.factorize(df.CabinLetter)[0]
上一步呢,只是把Cabin船舱号前面的字母提出来做为一个新的属性,船舱号中的数字固然也要提出来做为一个新的属性啦。
1 #plus one for laplace assumption 2 df['CabinNumber'] = df['Cabin'].map( lambda x: getCabinNumber(x) ).\ 3 astype(int) +1 4 def getCabinNumber(cabin): 5 match = re.compile("([0-9]+)").search(cabin) 6 if match: 7 return match.group() 8 else: 9 return 0
二 定量属性的数据变换
(1)数据规范化
数据规范化经过将数据压缩到一个范围内(一般是0-1或者-1-1)赋予全部属性相等的权重。对于涉及神经网络的分类算法或者基于距离度量的分类和聚类,规范化特别有用。规范化方法有多种,如rescaling logarithmic normalize等,能够在这里找到各类规范化方法的具体实现。可是有些时候并不须要规范化,好比算法使用类似度函数而不是距离函数的时候,好比随机森林,它从不比较一个特征与另外一个特征,所以也不准要规范化,关于这个问题,详细信息能够参考这篇文章www.faqs.org/faqs/ai-faq/neural-nets/part2/section-16.html
若是对Age属性进行规范化的话(看最后分类算法使用哪一种再肯定要不要规范化,若是要规范化的话,其余属性也要处理),代码以下:
1 if keep_scaled: 2 scaler = preprocessing.StandardScaler() 3 df['Age_Scaled'] = scaler.fit_transform(df['Age'])
StandardScaler将数值压缩到[-1,1]区间,计算公式为(2x - max(x) - min(x)) / (max(x) - min(x)).
(2)Binning
就像直方图的bin将数据划分红几块同样,咱们也能够将数值属性划分红几个bin,这是一种连续数据离散化的处理方式。咱们使用pandas.qcut()函数来离散化连续数据,它使用分位数对数据进行划分,能够获得大小基本相等的bin。如下以Fare(船票价格)为例,对于其余连续属性如Age SibSp等也能够划分红bin。
1 def processFare(): 2 global df 3 df['Fare'][df.Fare.isnull()] = df.Fare.dropna().mean() 4 #zero values divide -- laplace 5 df['Fare'][np.where(df['Fare']==0)[0]] = df['Fare'][df.Fare.\ 6 nonzero()[0] ].min() / 10 7 df['Fare_bin'] = pd.qcut(df.Fare, 4)
这样产生的df['Fare_bin']的值是这样的,
0 [0.401, 7.91] 3 (31, 512.329]
1 (31, 512.329] 4 (7.91, 14.454]
2 (7.91, 14.454] 5 (7.91, 14.454]
由于是bin,因此属性都是一个个区间,表明这个数据属于哪一个区间。对于这样的数据,咱们须要factorize下,转为数值型数据。
1 df['Fare_bin_id'] = pd.factorize(df.Fare_bin)[0]+1 2 scaler = preprocessing.StandardScaler() 3 df['Fare_bin_id_scaled'] = scaler.fit_transform(df.Fare_bin_id)