首页 > 其他 > 详细

kaggle数据挖掘竞赛初步--Titanic<派生属性>

时间:2015-03-22 22:10:20      阅读:284      评论:0      收藏:0      [点我收藏+]

特征工程系列:

Titanic系列之原始数据分析和数据处理

Titanic系列之数据变换

什么是派生属性呢?派生属性就是从原始数据中得到的一些属性,比如上一节从Age属性经过Factorize得到的Age_bin属性就是一个派生属性,当然这种派生只是非常简单的派生。为什么要对这些属性做各种各样的统计和处理呢,这其实是特征工程的一部分,先构建足够多可能会对结果有意义的属性,然后再从这些候选集中选择我们想要的特征。特征工程非常繁琐,但是对数据挖掘非常重要,一般来说,做一个数据挖掘项目,百分之八十的努力要用在特征工程上。除了基本的转换和interaction属性,我们也要创造性的从原始属性中发现新属性。比如电话号码,可以从中提取出来国家和区域特征。

一 研究业务逻辑提取特征

Titanic的数据集相对较为简单,但是对于一些字符串类型的属性,比如Name我们可以从中提取出来一些可以揭示其社会地位的称号。

技术分享

名字的长度也会代表一个人的社会地位,社会地位高的人可能会更容易得到救生船。

1 df[Names] = df[Name].map(lambda x: len(re.split( ,x)))

对于名字中间的爵位,可以看到称号有Mr Mrs Master等,经过统计可以看到有以下几种称号:

技术分享

这些称号有法语还有英语,需要依据当时的文化环境将其归类,如何将其归类可以参考这篇文章trevorstephens.com/post/73461351896/titanic-getting-started-with-r-part-4-feature

1     df[Title] = df[Name].map(lambda x: re.compile(",(.*?)\.").findall(x)[0])
2     df[Title][df.Title==Jonkheer] = Master
3     df[Title][df.Title.isin([Ms,Mlle])] = Miss
4     df[Title][df.Title == Mme] = Mrs
5     df[Title][df.Title.isin([Capt, Don, Major, Col, Sir])] = Sir
6     df[Title][df.Title.isin([Dona, Lady, the Countess])] = Lady
7     df[Title_id] = pd.factorize(df.Title)[0]+1

对于Ticket属性也需要处理,可以看到Ticket字段有的全是数字有的是字母和数字的集合,进一步对数据分析发现约25%的数据有前缀,前缀共有45种,如果把 . 和 / 去掉的话还剩29种,数字部分也有一定的规律:以1开头的一般是一等舱2开头的是二等舱3开头的是三等舱,4-9开头的大都是三等舱。以上这些数据告诉我们处理Ticket是有意义的,能够发现其内部蕴涵的信息。

 1 def processTicket():
 2     global df
 3     df[TicketPrefix] = df[Ticket].map(lambda x: getTicketPrefix(x.upper()))
 4     df[TicketPrefix] = df[TicketPrefix].map(lambda x: re.sub 5                             ([\.?\/?],‘‘,x))
 6     df[TicketPrefix] = df[TicketPrefix].map(lambda x:re.sub 7                                                 (STON,SOTON,x))
 8     df[TicketPrefix] = pd.factorize(df[TicketPrefix])[0]
 9     df[TicketNumber] = df[Ticket].map(lambda x: getTicketNumber(x) )
10     df[TicketNumberLength] = df[TicketNumber].map(lambda x: len(x)).11                                astype(int)
12     df[TicketNumberStart] = df[TicketNumber].map(lambda x: x[0:1]).13                               astype(int)
14     df[TicketNumber] = df[TicketNumber].astype(int)
15 def getTicketPrefix(ticket):
16     match = re.compile("([a-zA-Z\.\/]+)").search(ticket)
17     if match:
18         return match.group()
19     else:
20         return U
21 def getTicketNumber(ticket):
22     match = re.compile("([0-9]+$)").search(ticket)
23     if match:
24         return match.group()
25     else:
26         return 0

二 简单组合属性提取特征

一些属性可以从它本身的数据里提取一些信息,有些属性则需要和其他属性组合来产生信息。比如对淘宝上的一个商品来说,购买数/点击率可以反应商品的转化率,也是商品的一个非常重要的特征。

对于Titanic来说,我们用Age*Pclass组合产生一个属性,虽然没有一个名词来解释它,但是从结果数据上来看,我们增大了年纪大的人的权重也提高了高等舱的权重,从最后幸存的结果上看,这个组合还是有意义的。除了这两个属性之外,我们还可以对其他数值属性进行数学运算,以得到更大的候选特征集。

 1     numerics = df.loc[:, [Age_scaled, Fare_scaled, Pclass_scaled, Parch_scaled, SibSp_scaled, 
 2                           Names_scaled, CabinNumber_scaled, Age_bin_id_scaled, Fare_bin_id_scaled]]
 3     print "\nFeatures used for automated feature generation:\n", numerics.head(10)
 4     
 5     new_fields_count = 0
 6     for i in range(0, numerics.columns.size-1):
 7         for j in range(0, numerics.columns.size-1):
 8             if i <= j:
 9                 name = str(numerics.columns.values[i]) + "*" + str(numerics.columns.values[j])
10                 df = pd.concat([df, pd.Series(numerics.iloc[:,i] * numerics.iloc[:,j], name=name)], axis=1)
11                 new_fields_count += 1
12             if i < j:
13                 name = str(numerics.columns.values[i]) + "+" + str(numerics.columns.values[j])
14                 df = pd.concat([df, pd.Series(numerics.iloc[:,i] + numerics.iloc[:,j], name=name)], axis=1)
15                 new_fields_count += 1
16             if not i == j:
17                 name = str(numerics.columns.values[i]) + "/" + str(numerics.columns.values[j])
18                 df = pd.concat([df, pd.Series(numerics.iloc[:,i] / numerics.iloc[:,j], name=name)], axis=1)
19                 name = str(numerics.columns.values[i]) + "-" + str(numerics.columns.values[j])
20                 df = pd.concat([df, pd.Series(numerics.iloc[:,i] - numerics.iloc[:,j], name=name)], axis=1)
21                 new_fields_count += 2
22       
23     print "\n", new_fields_count, "new features generated"

这个过程自动产生大量的特征,这里用了9个特征产生了176个特征,可能这些特征有些过于多了,但是它只是一个候选集,我们可以通过一些处理筛选掉一些特征。当然有些模型也很适合大量特征的训练集,比如随机森林(有论文验证,随机森林是分类算法中表现最好的模型)。

产生的这些特征可能高度相关于原始特征,线性模型处理这类特征时会产生multicollinearity问题,可以用计算这些特征的皮尔逊相关系数,筛选相关性特征。如果用随机森林模型训练的话,可以不需要这个步骤。

kaggle数据挖掘竞赛初步--Titanic<派生属性>

原文:http://www.cnblogs.com/north-north/p/4358084.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!