热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

kaggle数据挖掘竞赛初步--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 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问题,可以用计算这些特征的皮尔逊相关系数,筛选相关性特征。如果用随机森林模型训练的话,可以不需要这个步骤。

三 用PCA进行维归约

通过上面三个部分的处理,我们得到了具有大量特征的维度很高的数据集,特征较多不能直接用来作为模型输入,一是因为这些特征间具有多重共线性,可能 会导致空间的不稳定;二是因为高维空间本身具有稀疏性,一维正态分布有68%的值落于正负标准差之间,而在十维空间上只有0.02%;三是由于过多的属性 会使挖掘需要很长时间。对于一些模型来说,比如使用L1(Lasso),当有大量属性时效果很好,因为它可以有效忽略掉噪声变量。而一些模型则容易过拟 合。

数据归约技术可以用来得到数据集的规约表示,它小得多,但仍接近于保持原始数据的完整性。也就是说,在归约后的数据集上进行数据挖掘将更加有效,仍然产生几乎相同的数据分析结果。

PCA(主成份分析)是一种维归约的方法,它搜索k个最能代表数据的n维正交向量,将原始数据投影到一个小的多的空间上,导致维归约。PCA通过创建一个替换的较小的变量集组合属性的基本要素。具体原理及python的实现过程可以参考这篇blogImplementing a Principal Component Analysis (PCA) in Python step by step

我们可以直接使用scikit-learn的PCA函数进行维规约

1     X = df.values[:, 1::]
2 y = df.values[:, 0]
3 variance_pct = .99
4 # Create PCA object
5 pca = PCA(n_compOnents=variance_pct)
6 # Transform the initial features
7 X_transformed = pca.fit_transform(X,y)
8 # Create a data frame from the PCA'd data
9 pcaDataFrame = pd.DataFrame(X_transformed)

实验发现,PCA对于线性模型(不使用Lasso)非常有效,但是对于随机森林模型没有提高。


推荐阅读
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
author-avatar
红烧大青虫
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有