大数据分析-快速指南

笔记列表:

大数据分析-快速指南

大数据分析-概述

在过去的十年中,必须处理的数据量激增至不可思议的水平,与此同时,数据存储的价格也有系统地降低了。私人公司和研究机构从其手机,汽车等设备中捕获有关其用户交互,业务,社交媒体以及传感器的TB级数据。这个时代的挑战是要了解这片海量的数据。这是大数据分析应运而生的地方

大数据分析主要涉及从不同来源收集数据,以使其可以被分析师使用的方式处理数据,最后提供对组织业务有用的数据产品。

企业组织

从不同来源检索到的大量非结构化原始数据转换为对组织有用的数据产品的过程,构成了大数据分析的核心。

大数据分析-数据生命周期

传统数据挖掘生命周期

为了提供一个框架来组织组织所需的工作并从大数据中获得清晰的见解,将其视为一个具有不同阶段的循环是很有用的。它绝不是线性的,这意味着所有阶段都是相互关联的。此循环与CRISP方法中描述的更传统的数据挖掘循环有表面上的相似之处

CRISP-DM方法论

代表跨行业数据挖掘标准过程CRISP-DM方法论是一个周期,描述了数据挖掘专家用来解决传统BI数据挖掘问题的常用方法。传统的BI数据挖掘团队仍在使用它。

看一下下图。它显示了CRISP-DM方法所描述的周期的主要阶段以及它们之间的相互关系。

生命周期

CRISP-DM于1996年构思,第二年作为ESPRIT资助计划下的欧洲联盟项目而进行。该项目由五家公司牵头:SPSS,Teradata,戴姆勒公司,NCR公司和OHRA(保险公司)。该项目最终被并入SPSS。该方法在如何指定数据挖掘项目方面非常详细。

现在让我们学习一下CRISP-DM生命周期中涉及的每个阶段的更多信息-

  • 业务理解-这个初始阶段的重点是从业务角度理解项目目标和需求,然后将这些知识转换为数据挖掘问题定义。初步计划旨在实现这些目标。可以使用决策模型,尤其是使用决策模型和表示法标准构建的决策模型。

  • 数据理解-数据理解阶段从初始数据收集开始,然后进行一些活动,以便熟悉数据,识别数据质量问题,发现对数据的初步见解或检测有趣的子集以形成隐藏的假设信息。

  • 数据准备-数据准备阶段涵盖了从初始原始数据构建最终数据集(将被馈送到建模工具的数据)的所有活动。数据准备任务可能会多次执行,而不是按任何规定的顺序执行。任务包括表,记录和属性选择以及建模工具的数据转换和清理。

  • 建模-在此阶段,选择并应用了各种建模技术,并将它们的参数校准为最佳值。通常,对于相同的数据挖掘问题类型,有多种技术。一些技术对数据形式有特定要求。因此,通常需要退回到数据准备阶段。

  • 评估-在项目的此阶段,从数据分析的角度来看,您已经构建了一个看起来高质量的模型。在继续进行模型的最终部署之前,重要的是要彻底评估模型并查看为构建模型而执行的步骤,以确保模型能够正确实现业务目标。

    一个关键目标是确定是否存在一些尚未被充分考虑的重要业务问题。在此阶段结束时,应就数据挖掘结果的使用做出决定。

  • 部署-模型的创建通常不是项目的结束。即使模型的目的是增加数据知识,所获得的知识也需要以对客户有用的方式进行组织和呈现。

    根据需求,部署阶段可以像生成报告一样简单,也可以像实现可重复的数据评分(例如,段分配)或数据挖掘过程一样复杂。

在许多情况下,执行部署步骤的将是客户而不是数据分析师。即使分析师部署了该模型,对于客户来说,也必须预先了解要实际使用所创建的模型所需执行的操作,这一点很重要。

SEMMA方法论

SEMMA是SAS为数据挖掘建模开发的另一种方法。它代表着小号充足,ē Xplore数据库,中号odify,中号奥德尔,和一个小规模企业。这是其阶段的简要说明-

  • 样本-该过程从数据采样开始,例如,选择要建模的数据集。数据集应足够大以包含足以检索的信息,但又应足够小以有效使用。此阶段还涉及数据分区。

  • 探索-此阶段通过数据可视化帮助发现变量之间的预期和意外关系以及异常,从而涵盖了对数据的理解。

  • 修改-修改阶段包含选择,创建和转换变量的方法,以准备进行数据建模。

  • 模型-在模型阶段,重点是对准备好的变量应用各种建模(数据挖掘)技术,以创建可能提供所需结果的模型。

  • 评估-对建模结果的评估显示了所创建模型的可靠性和有用性。

CRISM-DM与SEMMA之间的主要区别在于SEMMA专注于建模方面,而CRISP-DM在建模之前更重视周期的各个阶段,例如了解要解决的业务问题,理解和预处理要处理的数据。用作输入,例如机器学习算法。

大数据生命周期

在当今的大数据环境中,以前的方法要么不完整,要么不理想。例如,SEMMA方法论完全忽略了不同数据源的数据收集和预处理。这些阶段通常构成成功的大数据项目中的大部分工作。

大数据分析周期可以通过以下阶段来描述-

  • 业务问题定义
  • 研究
  • 人力资源评估
  • 数据采集
  • 数据整理
  • 数据存储
  • 探索性数据分析
  • 建模和评估的数据准备
  • 造型
  • 执行

在本节中,我们将介绍大数据生命周期的每个阶段。

业务问题定义

这是传统BI和大数据分析生命周期中常见的一点。通常,定义问题并正确评估组织可能获得多少潜在收益是大数据项目的重要阶段。提到这一点似乎很明显,但是必须评估该项目的预期收益和成本是多少。

研究

分析其他公司在相同情况下所做的事情。这涉及寻找适合您公司的解决方案,即使涉及使其他解决方案适应您公司的资源和要求也是如此。在此阶段,应定义未来阶段的方法。

人力资源评估

确定问题后,有理由继续分析当前员工是否能够成功完成项目。传统的BI团队可能无法为所有阶段提供最佳解决方案,因此,如果需要外包项目的一部分或雇用更多的人,则应在开始项目之前考虑它。

数据采集

本节是大数据生命周期中的关键。它定义了交付结果数据产品所需的配置文件类型。数据收集是该过程的重要步骤。它通常涉及从不同来源收集非结构化数据。举个例子,它可能涉及编写搜寻器以从网站检索评论。这涉及到处理文本,也许使用不同的语言,通常需要大量时间才能完成。

数据整理

例如,从Web检索数据后,就需要以易于使用的格式存储数据。为了继续审阅示例,我们假设数据是从不同的站点检索的,每个站点的数据显示方式都不相同。

假设一个数据源根据星级进行评论,因此可以将其作为响应变量y∈{1,2,3,4,5}的映射来读取另一个数据源使用两个箭头系统提供评论,一个用于赞成投票,另一个用于反对投票。这意味着形式为y∈{positive,negative}的响应变量

为了合并两个数据源,必须做出决定以使这两个响应表示形式相等。这可能涉及将第一个数据源响应表示形式转换为第二种形式,将一颗恒星视为负数,将五颗恒星视为正数。此过程通常需要大量时间才能以高质量交付。

数据存储

处理完数据后,有时需要将其存储在数据库中。关于这一点,大数据技术提供了许多替代方案。最常见的替代方法是使用Hadoop文件系统进行存储,该存储为用户提供了有限版本的SQL,称为HIVE查询语言。从用户的角度来看,这允许大多数分析任务以与传统BI数据仓库中类似的方式完成。其他要考虑的存储选项是MongoDB,Redis和SPARK。

就人力资源知识实施不同体系结构的能力而言,该周期的这一阶段与人力资源知识有关。传统数据仓库的修改版本仍在大规模应用中使用。例如,teradata和IBM提供了可以处理TB级数据的SQL数据库。诸如postgreSQL和MySQL之类的开源解决方案仍在用于大型应用程序。

尽管不同存储在后台的工作方式有所不同,但从客户端来看,大多数解决方案都提供了SQL API。因此,对SQL的深入了解仍然是大数据分析的一项关键技能。

先验阶段似乎是最重要的话题,实际上,这是不正确的。它甚至不是必不可少的阶段。可以实现一个可以处理实时数据的大数据解决方案,因此,在这种情况下,我们只需要收集数据来开发模型,然后就可以实时实现它。因此,根本不需要正式存储数据。

探索性数据分析

一旦数据以可以从中获取见解的方式被清理和存储,则数据探索阶段是必不可少的。此阶段的目的是了解数据,通常使用统计技术完成此工作并绘制数据。这是评估问题定义是否有意义或可行的一个好阶段。

建模和评估的数据准备

此阶段涉及重塑先前获取的清理数据,并对缺失值进行归因,离群值检测,归一化,特征提取和特征选择使用统计预处理。

造型

前一个阶段应该已经生成了一些用于训练和测试的数据集,例如,预测模型。这个阶段涉及尝试不同的模型,并期待解决眼前的业务问题。实际上,通常希望模型能够对业务有所了解。最后,选择最佳模型或模型组合以评估其在遗漏数据集上的性能。

执行

在此阶段,开发的数据产品将在公司的数据管道中实施。这涉及在数据产品运行时设置验证方案,以跟踪其性能。例如,在实施预测模型的情况下,此阶段将涉及将模型应用于新数据,并在响应可用后评估模型。

大数据分析-方法论

在方法论方面,大数据分析与实验设计的传统统计方法大不相同。分析从数据开始。通常,我们以解释响应的方式对数据建模。这种方法的目的是预测响应行为或了解输入变量与响应之间的关系。通常,在统计实验设计中,开发实验并作为结果检索数据。这允许以统计模型可以使用的方式生成数据,其中某些假设成立,例如独立性,正态性和随机性。

在大数据分析中,我们将获得数据。我们无法设计满足我们最喜欢的统计模型的实验。在分析的大规模应用中,仅需要清理数据就需要大量工作(通常需要80%的工作量),因此机器学习模型可以使用它。

在实际的大型应用程序中,我们没有遵循的独特方法。通常,一旦定义了业务问题,就需要研究阶段来设计要使用的方法。但是,一般性准则值得一提,并且适用于几乎所有问题。

大数据分析中最重要的任务之一是统计建模,这意味着有监督和无监督的分类或回归问题。一旦数据经过清洗和预处理(可用于建模),则应谨慎评估具有合理损失指标的不同模型,然后在实施模型后,应报告进一步的评估和结果。预测建模中的一个常见陷阱是仅实现模型而从不衡量其性能。

大数据分析-核心交付成果

如大数据生命周期中所述,在大多数情况下,开发大数据产品所产生的数据产品包括:

  • 机器学习实现-这可以是分类算法,回归模型或细分模型。

  • 推荐系统-目标是开发一种系统,该系统根据用户行为来推荐选择。Netflix是此数据产品的典型示例,其中根据用户的评级推荐其他电影。

  • 仪表板-业务通常需要使用工具来可视化聚合数据。仪表板是使这些数据可访问的图形机制。

  • 即席分析-通常的业务领域有疑问,假设或可回答做与数据即席分析神话。

大数据分析-主要利益相关者

在大型组织中,为了成功开发大数据项目,需要让管理人员备份该项目。这通常涉及寻找一种方法来显示项目的业务优势。对于为项目寻找赞助商的问题,我们没有独特的解决方案,但是下面给出了一些指导原则-

  • 检查与您感兴趣的其他项目相似的其他项目的发起人和发起人。

  • 在关键管理职位上建立个人联系会有所帮助,因此,如果项目有希望,则可以触发任何联系。

  • 谁将从您的项目中受益?一旦项目按计划进行,谁将是您的客户?

  • 制定一个简单,清晰,可行的建议,并与组织中的主要参与者共享。

为项目寻找赞助者的最佳方法是了解问题以及一旦实施该数据产品将是什么。这种理解将在说服大数据项目重要性管理方面发挥优势。

大数据分析-数据分析师

数据分析师具有面向报告的配置文件,具有使用SQL从传统数据仓库中提取和分析数据的经验。他们的任务通常在数据存储方面或在报告一般业务结果方面。数据仓库绝非简单,它与数据科学家所做的只是不同。

许多组织都在努力寻找市场上合格的数据科学家。但是,最好选择潜在的数据分析师,并教给他们相关的技能,以成为数据科学家。这绝不是一项琐碎的任务,通常会涉及在定量领域获得硕士学位的人,但这绝对是一个可行的选择。以下是胜任的数据分析人员必须具备的基本技能-

  • 业务了解
  • SQL程序设计
  • 报告设计与实施
  • 仪表板开发

大数据分析-数据科学家

数据科学家的角色通常与诸如预测建模,开发细分算法,推荐系统,A / B测试框架之类的任务相关联,并且经常与原始的非结构化数据一起工作。

他们的工作性质要求对数学,应用统计和编程有深入的了解。数据分析师和数据科学家之间有一些共同的技能,例如查询数据库的能力。两者都可以分析数据,但是数据科学家的决定可以对组织产生更大的影响。

这是数据科学家通常需要具备的一组技能-

  • 使用统计数据包(例如R,Python,SAS,SPSS或Julia)进行编程
  • 能够清理,提取和探索来自不同来源的数据
  • 统计模型的研究,设计和实施
  • 深入的统计,数学和计算机科学知识

在大数据分析中,人们通常会将数据科学家的角色与数据架构师的角色混淆。实际上,区别很简单。数据架构师定义了存储数据的工具和架构,而数据科学家则使用该架构。当然,如果临时项目需要,数据科学家应该能够设置新工具,但是基础结构定义和设计不应成为他的任务的一部分。

大数据分析-问题定义

通过本教程,我们将开发一个项目。本教程的后续各章在“微型项目”部分中讨论了较大项目的一部分。认为这是一个实用的教程部分,它将提供对实际问题的了解。在这种情况下,我们将从项目的问题定义开始。

项目介绍

该项目的目的是开发一种机器学习模型,以使用其履历(CV)文本作为输入来预测人们的时薪。

使用上面定义的框架,很容易定义问题。我们可以将X = {x 1,x 2,…,x n }定义为用户的简历,其中每个功能都可以以最简单的方式表示该单词出现的次数。然后,响应才是真正有价值的,我们正在尝试以美元为单位预测个人的小时工资。

这两个考虑因素足以得出结论,可以使用监督回归算法解决存在的问题。

问题定义

问题定义可能是大数据分析管道中最复杂,最被忽略的阶段之一。为了定义数据产品可以解决的问题,必须具备经验。在这一阶段,大多数数据科学家有抱负的经验很少或没有经验。

大多数大数据问题可以按以下方式分类-

  • 监督分类
  • 有监督的回归
  • 无监督学习
  • 学习排名

现在让我们详细了解这四个概念。

监督分类

给定特征矩阵X = {x 1,x 2,…,x n },我们开发了一个模型M来预测定义为y = {c 1,c 2,…,c n }的不同类别例如:给定保险公司中客户的交易数据,可以开发一个模型来预测客户是否流失。后者是一个二元分类问题,其中存在两个类别或目标变量:搅动而不是搅动。

其他问题涉及预测一个以上的类,我们可能会对数字识别感兴趣,因此响应矢量将定义为:y = {0,1,2,3,4,4,5,6,7,8,9},最先进的模型将是卷积神经网络,特征矩阵将定义为图像的像素。

监督回归

在这种情况下,问题的定义与前面的示例非常相似。差异取决于响应。在回归问题中,响应y∈ℜ,这意味着该响应是实数值。例如,我们可以开发一个模型来预测给定其简历的个人的时薪。

无监督学习

管理人员通常渴望获得新的见解。细分模型可以提供这种见解,以便营销部门针对不同的细分市场开发产品。开发细分模型而不是思考算法的一种好方法是选择与所需细分相关的特征。

例如,在一家电信公司中,根据客户的手机使用情况对其进行细分很有趣。这将涉及忽略与分割目标无关的特征,而仅包括那些与分割目标无关的特征。在这种情况下,这将选择功能,例如一个月中使用的SMS数量,入站和出站分钟数等。

学习排名

该问题可以看作是回归问题,但是它具有特定的特征,值得单独处理。该问题涉及给定的文档集合,我们试图在给定查询的情况下找到最相关的顺序。为了开发监督学习算法,需要给定查询标记排序的相关性。

值得注意的是,为了开发监督学习算法,需要标记训练数据。这意味着,为了训练一个模型,该模型将例如识别图像中的数字,我们需要手工标记大量示例。有些Web服务可以加快此过程,并且通常用于此任务,例如Amazon Mechanical Turk。事实证明,学习算法在提供更多数据时会提高其性能,因此在监督学习中标记大量的示例实际上是必不可少的。

大数据分析-数据收集

数据收集在大数据周期中扮演着最重要的角色。互联网为各种主题提供了几乎无限的数据源。该领域的重要性取决于业务类型,但是传统行业可以获取多种外部数据源,并将其与交易数据相结合。

例如,假设我们要构建一个推荐餐厅的系统。第一步是收集数据,在这种情况下,是来自不同网站的餐厅评论,并将其存储在数据库中。由于我们对原始文本感兴趣,并将其用于分析,因此用于存储模型开发数据的位置并不重要。这听起来可能与大数据主要技术相矛盾,但是为了实现大数据应用程序,我们只需要使其实时工作即可。

Twitter的迷你项目

定义问题后,接下来的阶段是收集数据。以下微型项目的想法是致力于从Web上收集数据并将其构造为在机器学习模型中使用。我们将使用R编程语言从twitter rest API中收集一些推文。

首先创建一个Twitter帐户,然后按照twitteR插图中的说明创建一个Twitter开发者帐户。这是这些说明的摘要-

  • 转到https://twitter.com/apps/new并登录。

  • 填写基本信息后,转到“设置”选项卡,然后选择“读取,写入和访问直接消息”。

  • 完成此操作后,请确保单击“保存”按钮。

  • 在“详细信息”标签中,记下您的消费者密钥和消费者秘密

  • 在您的R会话中,您将使用API​​密钥和API机密值

  • 最后运行以下脚本。将从其在github上的存储库安装twitteR软件包。

install.packages(c("devtools", "rjson", "bit64", "httr"))  

# Make sure to restart your R session at this point 
library(devtools) 
install_github("geoffjentry/twitteR") 

我们有兴趣获取包含字符串“ big mac”的数据,并找出与此相关的主题。为此,第一步是从Twitter收集数据。以下是我们的R脚本,用于从Twitter收集所需的数据。此代码也可在bda / part1 / collect_data / collect_data_twitter.R文件中找到。

rm(list = ls(all = TRUE)); gc() # Clears the global environment
library(twitteR)
Sys.setlocale(category = "LC_ALL", locale = "C")

### Replace the xxx’s with the values you got from the previous instructions

# consumer_key = "xxxxxxxxxxxxxxxxxxxx"
# consumer_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# access_token = "xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# access_token_secret= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# Connect to twitter rest API
setup_twitter_oauth(consumer_key, consumer_secret, access_token, access_token_secret)

# Get tweets related to big mac
tweets <- searchTwitter(’big mac’, n = 200, lang = en’)
df <- twListToDF(tweets)

# Take a look at the data
head(df)

# Check which device is most used
sources <- sapply(tweets, function(x) x$getStatusSource())
sources <- gsub("</a>", "", sources)
sources <- strsplit(sources, ">")
sources <- sapply(sources, function(x) ifelse(length(x) > 1, x[2], x[1]))
source_table = table(sources)
source_table = source_table[source_table > 1]
freq = source_table[order(source_table, decreasing = T)]
as.data.frame(freq)

#                       Frequency
# Twitter for iPhone       71
# Twitter for Android      29
# Twitter Web Client       25
# recognia                 20

大数据分析-清理数据

一旦收集了数据,我们通常会获得具有不同特征的各种数据源。最直接的步骤是使这些数据源齐整,并继续开发我们的数据产品。但是,这取决于数据的类型。我们应该问自己,对数据进行均质化是否可行。

也许数据源是完全不同的,如果将数据源同质化,信息损失将很大。在这种情况下,我们可以考虑其他选择。一个数据源可以帮助我建立一个回归模型,另一个可以帮助我建立一个分类模型吗?是否可以利用异质性来发挥我们的优势,而不仅仅是丢失信息?做出这些决定是使分析变得有趣和具有挑战性的原因。

对于审阅,可以为每个数据源使用一种语言。同样,我们有两个选择-

  • 同质化-它涉及将不同的语言翻译成我们拥有更多数据的语言。转换服务的质量是可以接受的,但是如果我们想使用API​​转换大量数据,那么代价将是巨大的。有可用于此任务的软件工具,但这也很昂贵。

  • 异构化-是否有可能为每种语言开发解决方案?由于检测语料库的语言很简单,因此我们可以为每种语言开发推荐器。在根据可用语言的数量调整每个推荐器方面,这将涉及更多工作,但是如果我们有几种语言可用,那么绝对是一个可行的选择。

Twitter的迷你项目

在当前情况下,我们需要先清理非结构化数据,然后将其转换为数据矩阵,以便对其应用主题建模。通常,从Twitter获取数据时,至少在数据清理过程的第一阶段,会有几个我们不希望使用的字符。

例如,获得鸣叫后,我们得到以下奇怪的字符:“ <ed> <U + 00A0> <U + 00BD> <ed> <U + 00B8> <U + 008B>”。这些可能是表情符号,因此为了清除数据,我们将使用以下脚本将其删除。此代码也可在bda / part1 / collect_data / cleaning_data.R文件中找到。

rm(list = ls(all = TRUE)); gc() # Clears the global environment
source('collect_data_twitter.R')
# Some tweets
head(df$text)

[1] "I’m not a big fan of turkey but baked Mac &
cheese <ed><U+00A0><U+00BD><ed><U+00B8><U+008B>"
[2] "@Jayoh30 Like no special sauce on a big mac. HOW"
### We are interested in the text - Let’s clean it!

# We first convert the encoding of the text from latin1 to ASCII
df$text <- sapply(df$text,function(row) iconv(row, "latin1", "ASCII", sub = ""))

# Create a function to clean tweets
clean.text <- function(tx) {
  tx <- gsub("htt.{1,20}", " ", tx, ignore.case = TRUE)
  tx = gsub("[^#[:^punct:]]|@|RT", " ", tx, perl = TRUE, ignore.case = TRUE)
  tx = gsub("[[:digit:]]", " ", tx, ignore.case = TRUE)
  tx = gsub(" {1,}", " ", tx, ignore.case = TRUE)
  tx = gsub("^\\s+|\\s+$", " ", tx, ignore.case = TRUE)
  return(tx)
}  

clean_tweets <- lapply(df$text, clean.text)

# Cleaned tweets
head(clean_tweets)
[1] " WeNeedFeminlsm MAC s new make up line features men woc and big girls "
[1] " TravelsPhoto What Happens To Your Body One Hour After A Big Mac "

数据清理迷你项目的最后一步是清理文本,我们可以将其转换为矩阵并对其应用算法。clean_tweets向量中存储的文本中,我们可以轻松地将其转换为一袋单词矩阵,并应用无监督的学习算法。

大数据分析-汇总数据

报告在大数据分析中非常重要。每个组织都必须定期提供信息以支持其决策过程。这项任务通常由具有SQL和ETL(提取,传输和加载)经验的数据分析人员处理。

负责此任务的团队负责将大数据分析部门产生的信息传播到组织的不同区域。

以下示例演示了数据汇总的含义。导航到bda / part1 / summarize_data文件夹,然后在该文件夹内,双击打开summary_data.Rproj文件。然后,打开summary_data.R脚本并看一下代码,然后按照给出的说明进行操作。

# Install the following packages by running the following code in R. 
pkgs = c('data.table', 'ggplot2', 'nycflights13', 'reshape2') 
install.packages(pkgs)

GGPLOT2包是伟大的数据可视化。data.table包是一个很好的选择,以做快速和高效存储技术综述[R 最新的基准测试表明,它甚至比用于类似任务的python库pandas还要快

基准

使用以下代码查看数据。此代码也可在bda / part1 / summarize_data / summarize_data.Rproj文件中找到。

library(nycflights13) 
library(ggplot2) 
library(data.table) 
library(reshape2)  

# Convert the flights data.frame to a data.table object and call it DT 
DT <- as.data.table(flights)  

# The data has 336776 rows and 16 columns 
dim(DT)  

# Take a look at the first rows 
head(DT) 

#   year    month  day   dep_time  dep_delay  arr_time  arr_delay  carrier 
# 1: 2013     1     1      517       2         830         11       UA 
# 2: 2013     1     1      533       4         850         20       UA 
# 3: 2013     1     1      542       2         923         33       AA 
# 4: 2013     1     1      544      -1        1004        -18       B6 
# 5: 2013     1     1      554      -6         812        -25       DL 
# 6: 2013     1     1      554      -4         740         12       UA  

#     tailnum  flight  origin   dest    air_time   distance    hour   minute 
# 1:  N14228   1545     EWR      IAH      227        1400       5       17 
# 2:  N24211   1714     LGA      IAH      227        1416       5       33 
# 3:  N619AA   1141     JFK      MIA      160        1089       5       42 
# 4:  N804JB    725     JFK      BQN      183        1576       5       44 
# 5:  N668DN    461     LGA      ATL      116        762        5       54 
# 6:  N39463   1696     EWR      ORD      150        719        5       54

以下代码有一个数据汇总的示例。

### Data Summarization
# Compute the mean arrival delay  
DT[, list(mean_arrival_delay = mean(arr_delay, na.rm = TRUE))] 
#        mean_arrival_delay 
# 1:           6.895377  
# Now, we compute the same value but for each carrier 
mean1 = DT[, list(mean_arrival_delay = mean(arr_delay, na.rm = TRUE)), 
   by = carrier] 
print(mean1) 
#      carrier    mean_arrival_delay 
# 1:      UA          3.5580111 
# 2:      AA          0.3642909 
# 3:      B6          9.4579733 
# 4:      DL          1.6443409 
# 5:      EV         15.7964311 
# 6:      MQ         10.7747334 
# 7:      US          2.1295951 
# 8:      WN          9.6491199 
# 9:      VX          1.7644644 
# 10:     FL         20.1159055 
# 11:     AS         -9.9308886 
# 12:     9E          7.3796692
# 13:     F9         21.9207048 
# 14:     HA         -6.9152047 
# 15:     YV         15.5569853 
# 16:     OO         11.9310345

# Now let’s compute to means in the same line of code 
mean2 = DT[, list(mean_departure_delay = mean(dep_delay, na.rm = TRUE), 
   mean_arrival_delay = mean(arr_delay, na.rm = TRUE)), 
   by = carrier] 
print(mean2) 

#       carrier    mean_departure_delay   mean_arrival_delay 
# 1:      UA            12.106073          3.5580111 
# 2:      AA             8.586016          0.3642909 
# 3:      B6            13.022522          9.4579733 
# 4:      DL             9.264505          1.6443409 
# 5:      EV            19.955390         15.7964311 
# 6:      MQ            10.552041         10.7747334 
# 7:      US             3.782418          2.1295951 
# 8:      WN            17.711744          9.6491199 
# 9:      VX            12.869421          1.7644644 
# 10:     FL            18.726075         20.1159055 
# 11:     AS             5.804775         -9.9308886 
# 12:     9E            16.725769          7.3796692 
# 13:     F9            20.215543         21.9207048 
# 14:     HA             4.900585         -6.9152047 
# 15:     YV            18.996330         15.5569853 
# 16:     OO            12.586207         11.9310345

### Create a new variable called gain 
# this is the difference between arrival delay and departure delay 
DT[, gain:= arr_delay - dep_delay]  

# Compute the median gain per carrier 
median_gain = DT[, median(gain, na.rm = TRUE), by = carrier] 
print(median_gain)

大数据分析-数据探索

探索性数据分析是约翰·塔克(John Tuckey,1977)提出的一个概念,它基于统计学的新观点。Tuckey的想法是,在传统统计中,数据不是以图形方式进行探索,而是仅用于检验假设。开发工具的第一次尝试是在斯坦福进行的,该项目称为prim9该工具能够在九个维度上可视化数据,因此能够提供数据的多元视角。

近年来,探索性数据分析是必须的,并且已包含在大数据分析生命周期中。强大的EDA功能促进了在组织中发现见解并进行有效沟通的能力。

根据Tuckey的想法,贝尔实验室开发了S编程语言,以便提供进行统计的交互式界面。S的想法是通过一种易于使用的语言提供广泛的图形功能。在当今世界中,在大数据的背景下,基于S编程语言的R最受欢迎的分析软件。

顶级分析软件包

以下程序演示了探索性数据分析的用法。

以下是探索性数据分析的示例。该代码在part1 / eda / exploratory_data_analysis.R文件中也可用

library(nycflights13) 
library(ggplot2) 
library(data.table) 
library(reshape2)  

# Using the code from the previous section 
# This computes the mean arrival and departure delays by carrier. 
DT <- as.data.table(flights) 
mean2 = DT[, list(mean_departure_delay = mean(dep_delay, na.rm = TRUE), 
   mean_arrival_delay = mean(arr_delay, na.rm = TRUE)), 
   by = carrier]  

# In order to plot data in R usign ggplot, it is normally needed to reshape the data 
# We want to have the data in long format for plotting with ggplot 
dt = melt(mean2, id.vars = ’carrier’)  

# Take a look at the first rows 
print(head(dt))  

# Take a look at the help for ?geom_point and geom_line to find similar examples 
# Here we take the carrier code as the x axis 
# the value from the dt data.table goes in the y axis 

# The variable column represents the color 
p = ggplot(dt, aes(x = carrier, y = value, color = variable, group = variable)) +
   geom_point() + # Plots points 
   geom_line() + # Plots lines 
   theme_bw() + # Uses a white background 
   labs(list(title = 'Mean arrival and departure delay by carrier', 
      x = 'Carrier', y = 'Mean delay')) 
print(p)  

# Save the plot to disk 
ggsave('mean_delay_by_carrier.png', p,  
   width = 10.4, height = 5.07)

该代码应产生如下图像:

平均延迟

大数据分析-数据可视化

为了理解数据,通常将其可视化很有用。通常,在大数据应用程序中,人们的兴趣在于寻找见识,而不仅仅是做出漂亮的图。以下是使用图解理解数据的不同方法的示例。

要开始分析航班数据,我们可以先检查数字变量之间是否存在相关性。此代码也可在bda / part1 / data_visualization / data_visualization.R文件中找到。

# Install the package corrplot by running
install.packages('corrplot')  

# then load the library 
library(corrplot)  

# Load the following libraries  
library(nycflights13) 
library(ggplot2) 
library(data.table) 
library(reshape2)  

# We will continue working with the flights data 
DT <- as.data.table(flights)  
head(DT) # take a look  

# We select the numeric variables after inspecting the first rows. 
numeric_variables = c('dep_time', 'dep_delay',  
   'arr_time', 'arr_delay', 'air_time', 'distance')

# Select numeric variables from the DT data.table 
dt_num = DT[, numeric_variables, with = FALSE]  

# Compute the correlation matrix of dt_num 
cor_mat = cor(dt_num, use = "complete.obs")  

print(cor_mat) 
### Here is the correlation matrix 
#              dep_time   dep_delay   arr_time   arr_delay    air_time    distance 
# dep_time   1.00000000  0.25961272 0.66250900  0.23230573 -0.01461948 -0.01413373 
# dep_delay  0.25961272  1.00000000 0.02942101  0.91480276 -0.02240508 -0.02168090 
# arr_time   0.66250900  0.02942101 1.00000000  0.02448214  0.05429603  0.04718917 
# arr_delay  0.23230573  0.91480276 0.02448214  1.00000000 -0.03529709 -0.06186776 
# air_time  -0.01461948 -0.02240508 0.05429603 -0.03529709  1.00000000  0.99064965 
# distance  -0.01413373 -0.02168090 0.04718917 -0.06186776  0.99064965  1.00000000  

# We can display it visually to get a better understanding of the data 
corrplot.mixed(cor_mat, lower = "circle", upper = "ellipse")  

# save it to disk 
png('corrplot.png') 
print(corrplot.mixed(cor_mat, lower = "circle", upper = "ellipse")) 
dev.off()

此代码生成以下相关矩阵可视化-

相关性

我们可以从图中看出,数据集中的某些变量之间存在很强的相关性。例如,到达延迟和离开延迟似乎高度相关。我们可以看到这一点,因为椭圆显示出两个变量之间几乎呈线性关系,但是,从该结果中查找因果关系并不容易。

我们不能说因为两个变量是相关的,所以一个对另一个有影响。我们还可以在图中发现空中时间与距离之间有很强的相关性,可以预期,随着距离的增加,飞行时间会增加。

我们还可以对数据进行单变量分析。可视化分布的一种简单有效的方法是箱形图以下代码演示了如何使用ggplot2库生成箱形图和格子图。此代码也可在bda / part1 / data_visualization / boxplots.R文件中找到。

source('data_visualization.R') 
### Analyzing Distributions using box-plots  
# The following shows the distance as a function of the carrier 

p = ggplot(DT, aes(x = carrier, y = distance, fill = carrier)) + # Define the carrier 
   in the x axis and distance in the y axis 
   geom_box-plot() + # Use the box-plot geom 
   theme_bw() + # Leave a white background - More in line with tufte's 
      principles than the default 
   guides(fill = FALSE) + # Remove legend 
   labs(list(title = 'Distance as a function of carrier', # Add labels 
      x = 'Carrier', y = 'Distance')) 
p   
# Save to disk 
png(‘boxplot_carrier.png’) 
print(p) 
dev.off()   

# Let's add now another variable, the month of each flight 
# We will be using facet_wrap for this 
p = ggplot(DT, aes(carrier, distance, fill = carrier)) + 
   geom_box-plot() + 
   theme_bw() + 
   guides(fill = FALSE) +  
   facet_wrap(~month) + # This creates the trellis plot with the by month variable
   labs(list(title = 'Distance as a function of carrier by month', 
      x = 'Carrier', y = 'Distance')) 
p   
# The plot shows there aren't clear differences between distance in different months  

# Save to disk 
png('boxplot_carrier_by_month.png') 
print(p) 
dev.off()

大数据分析-R简介

本节专门向用户介绍R编程语言。R可以从下载CRAN网站对于Windows用户,安装rtoolsrstudio IDE很有用

R背后的一般概念是用作以编译语言(例如C,C ++和Fortran)开发的其他软件的接口,并为用户提供用于分析数据的交互式工具。

导航至书籍zip文件bda / part2 / R_introduction的文件夹,然后打开R_introduction.Rproj文件。这将打开一个RStudio会话。然后打开01_vectors.R文件。逐行运行脚本,并遵循代码中的注释。为了学习的另一个有用的选择是只键入代码,这将帮助您习惯R语法。在R中,注释用#符号书写。

为了在书中显示运行R代码的结果,在对代码进行评估之后,对R返回的结果进行注释。这样,您可以将代码复制粘贴到书中,然后直接在R中尝试部分代码。

# Create a vector of numbers 
numbers = c(1, 2, 3, 4, 5) 
print(numbers) 

# [1] 1 2 3 4 5  
# Create a vector of letters 
ltrs = c('a', 'b', 'c', 'd', 'e') 
# [1] "a" "b" "c" "d" "e"  

# Concatenate both  
mixed_vec = c(numbers, ltrs) 
print(mixed_vec) 
# [1] "1" "2" "3" "4" "5" "a" "b" "c" "d" "e"

让我们分析一下先前代码中发生的情况。我们可以看到可以创建带有数字和字母的向量。我们不需要事先告诉R我们想要哪种数据类型。最后,我们能够创建包含数字和字母的向量。向量mixed_vec已将数字强制转换为字符,我们可以通过可视化值在引号内的打印方式来看到这一点。

以下代码显示了由函数类返回的不同向量的数据类型。通常使用类函数“询问”对象,询问他的类是什么。

### Evaluate the data types using class

### One dimensional objects 
# Integer vector 
num = 1:10 
class(num) 
# [1] "integer"  

# Numeric vector, it has a float, 10.5 
num = c(1:10, 10.5) 
class(num) 
# [1] "numeric"  

# Character vector 
ltrs = letters[1:10] 
class(ltrs) 
# [1] "character"  

# Factor vector 
fac = as.factor(ltrs) 
class(fac) 
# [1] "factor"

R也支持二维对象。在以下代码中,有R中使用的两种最流行的数据结构的示例:matrix和data.frame。

# Matrix
M = matrix(1:12, ncol = 4) 
#      [,1] [,2] [,3] [,4] 
# [1,]    1    4    7   10 
# [2,]    2    5    8   11 
# [3,]    3    6    9   12 
lM = matrix(letters[1:12], ncol = 4) 
#     [,1] [,2] [,3] [,4] 
# [1,] "a"  "d"  "g"  "j"  
# [2,] "b"  "e"  "h"  "k"  
# [3,] "c"  "f"  "i"  "l"   

# Coerces the numbers to character 
# cbind concatenates two matrices (or vectors) in one matrix 
cbind(M, lM) 
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] 
# [1,] "1"  "4"  "7"  "10" "a"  "d"  "g"  "j"  
# [2,] "2"  "5"  "8"  "11" "b"  "e"  "h"  "k"  
# [3,] "3"  "6"  "9"  "12" "c"  "f"  "i"  "l"   

class(M) 
# [1] "matrix" 
class(lM) 
# [1] "matrix"  

# data.frame 
# One of the main objects of R, handles different data types in the same object.  
# It is possible to have numeric, character and factor vectors in the same data.frame  

df = data.frame(n = 1:5, l = letters[1:5]) 
df 
#   n l 
# 1 1 a 
# 2 2 b 
# 3 3 c 
# 4 4 d 
# 5 5 e 

如前面的示例所示,可以在同一对象中使用不同的数据类型。通常,这就是数据在数据库中的呈现方式,API的一部分是文本或字符向量以及其他数字。分析人员的工作是确定要分配的统计数据类型,然后为其使用正确的R数据类型。在统计中,我们通常认为变量具有以下类型-

  • 数字
  • 名义的或绝对的
  • 序数

在R中,向量可以属于以下类别-

  • 数值-整数
  • 因素
  • 有序因子

R为变量的每种统计类型提供一种数据类型。但是,排序因数很少使用,但可以由功能因数创建或排序。

下一节讨论索引的概念。这是一个非常常见的操作,处理选择对象的各个部分并对其进行转换的问题。

# Let's create a data.frame
df = data.frame(numbers = 1:26, letters) 
head(df) 
#      numbers  letters 
# 1       1       a 
# 2       2       b 
# 3       3       c 
# 4       4       d 
# 5       5       e 
# 6       6       f 

# str gives the structure of a data.frame, it’s a good summary to inspect an object 
str(df) 
#   'data.frame': 26 obs. of  2 variables: 
#   $ numbers: int  1 2 3 4 5 6 7 8 9 10 ... 
#   $ letters: Factor w/ 26 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ...  

# The latter shows the letters character vector was coerced as a factor. 
# This can be explained by the stringsAsFactors = TRUE argumnet in data.frame 
# read ?data.frame for more information  

class(df) 
# [1] "data.frame"  

### Indexing
# Get the first row 
df[1, ] 
#     numbers  letters 
# 1       1       a  

# Used for programming normally - returns the output as a list 
df[1, , drop = TRUE] 
# $numbers 
# [1] 1 
#  
# $letters 
# [1] a 
# Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z  

# Get several rows of the data.frame 
df[5:7, ] 
#      numbers  letters 
# 5       5       e 
# 6       6       f 
# 7       7       g  

### Add one column that mixes the numeric column with the factor column 
df$mixed = paste(df$numbers, df$letters, sep = ’’)  

str(df) 
# 'data.frame': 26 obs. of  3 variables: 
# $ numbers: int  1 2 3 4 5 6 7 8 9 10 ...
# $ letters: Factor w/ 26 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ... 
# $ mixed  : chr  "1a" "2b" "3c" "4d" ...  

### Get columns 
# Get the first column 
df[, 1]  
# It returns a one dimensional vector with that column  

# Get two columns 
df2 = df[, 1:2] 
head(df2)  

#      numbers  letters 
# 1       1       a 
# 2       2       b 
# 3       3       c 
# 4       4       d 
# 5       5       e 
# 6       6       f  

# Get the first and third columns 
df3 = df[, c(1, 3)] 
df3[1:3, ]  

#      numbers  mixed 
# 1       1     1a
# 2       2     2b 
# 3       3     3c  

### Index columns from their names 
names(df) 
# [1] "numbers" "letters" "mixed"   
# This is the best practice in programming, as many times indeces change, but 
variable names don’t 
# We create a variable with the names we want to subset 
keep_vars = c("numbers", "mixed") 
df4 = df[, keep_vars]  

head(df4) 
#      numbers  mixed 
# 1       1     1a 
# 2       2     2b 
# 3       3     3c 
# 4       4     4d 
# 5       5     5e 
# 6       6     6f  

### subset rows and columns 
# Keep the first five rows 
df5 = df[1:5, keep_vars] 
df5 

#      numbers  mixed 
# 1       1     1a 
# 2       2     2b
# 3       3     3c 
# 4       4     4d 
# 5       5     5e  

# subset rows using a logical condition 
df6 = df[df$numbers < 10, keep_vars] 
df6 

#      numbers  mixed 
# 1       1     1a 
# 2       2     2b 
# 3       3     3c 
# 4       4     4d 
# 5       5     5e 
# 6       6     6f 
# 7       7     7g 
# 8       8     8h 
# 9       9     9i 

大数据分析-SQL简介

SQL代表结构化查询语言。它是从传统数据仓库和大数据技术中的数据库中提取数据的最广泛使用的语言之一。为了演示SQL的基础知识,我们将使用示例。为了专注于语言本身,我们将在R内部使用SQL。就编写SQL代码而言,这与在数据库中所做的完全相同。

SQL的核心是三个语句:SELECT,FROM和WHERE。以下示例利用了SQL的最常见用例。导航到bda / part2 / SQL_introduction文件夹,然后打开SQL_introduction.Rproj文件。然后打开01_select.R脚本。为了在R中编写SQL代码,我们需要安装sqldf软件包,如以下代码所示。

# Install the sqldf package
install.packages('sqldf')  

# load the library 
library('sqldf') 
library(nycflights13)  

# We will be working with the fligths dataset in order to introduce SQL  

# Let’s take a look at the table 
str(flights) 
# Classes 'tbl_d', 'tbl' and 'data.frame': 336776 obs. of  16 variables: 

# $ year     : int  2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ... 
# $ month    : int  1 1 1 1 1 1 1 1 1 1 ... 
# $ day      : int  1 1 1 1 1 1 1 1 1 1 ... 
# $ dep_time : int  517 533 542 544 554 554 555 557 557 558 ... 
# $ dep_delay: num  2 4 2 -1 -6 -4 -5 -3 -3 -2 ... 
# $ arr_time : int  830 850 923 1004 812 740 913 709 838 753 ... 
# $ arr_delay: num  11 20 33 -18 -25 12 19 -14 -8 8 ...
# $ carrier  : chr  "UA" "UA" "AA" "B6" ... 

# $ tailnum  : chr  "N14228" "N24211" "N619AA" "N804JB" ... 
# $ flight   : int  1545 1714 1141 725 461 1696 507 5708 79 301 ... 
# $ origin   : chr  "EWR" "LGA" "JFK" "JFK" ... 
# $ dest     : chr  "IAH" "IAH" "MIA" "BQN" ... 
# $ air_time : num  227 227 160 183 116 150 158 53 140 138 ... 
# $ distance : num  1400 1416 1089 1576 762 ... 
# $ hour     : num  5 5 5 5 5 5 5 5 5 5 ... 
# $ minute   : num  17 33 42 44 54 54 55 57 57 58 ...

select语句用于从表中检索列并对其进行计算。最简单的SELECT语句在ej1中进行了演示我们还可以创建新变量,如ej2所示

### SELECT statement
ej1 = sqldf(" 
   SELECT  
   dep_time 
   ,dep_delay 
   ,arr_time 
   ,carrier 
   ,tailnum 
   FROM 
   flights
")  

head(ej1) 
#    dep_time   dep_delay  arr_time  carrier  tailnum 
# 1      517         2      830      UA       N14228 
# 2      533         4      850      UA       N24211 
# 3      542         2      923      AA       N619AA 
# 4      544        -1     1004      B6       N804JB 
# 5      554        -6      812      DL       N668DN 
# 6      554        -4      740      UA       N39463  

# In R we can use SQL with the sqldf function. It works exactly the same as in 
a database 

# The data.frame (in this case flights) represents the table we are querying 
and goes in the FROM statement  
# We can also compute new variables in the select statement using the syntax: 

# old_variables as new_variable 
ej2 = sqldf(" 
   SELECT 
   arr_delay - dep_delay as gain, 
   carrier 
   FROM 
   flights
")  

ej2[1:5, ] 
#    gain   carrier 
# 1    9      UA 
# 2   16      UA 
# 3   31      AA 
# 4  -17      B6 
# 5  -19      DL

SQL的最常用功能之一是group by语句。这允许为另一个变量的不同组计算一个数值。打开脚本02_group_by.R。

### GROUP BY      

# Computing the average 
ej3 = sqldf(" 
  SELECT 
   avg(arr_delay) as mean_arr_delay, 
   avg(dep_delay) as mean_dep_delay, 
   carrier 
   FROM 
   flights 
   GROUP BY 
   carrier 
")  

#    mean_arr_delay   mean_dep_delay carrier 
# 1       7.3796692      16.725769      9E 
# 2       0.3642909       8.586016      AA 
# 3      -9.9308886       5.804775      AS 
# 4       9.4579733      13.022522      B6 
# 5       1.6443409       9.264505      DL 
# 6      15.7964311      19.955390      EV 
# 7      21.9207048      20.215543      F9 
# 8      20.1159055      18.726075      FL 
# 9      -6.9152047       4.900585      HA 
# 10     10.7747334      10.552041      MQ
# 11     11.9310345      12.586207      OO 
# 12      3.5580111      12.106073      UA 
# 13      2.1295951       3.782418      US 
# 14      1.7644644      12.869421      VX 
# 15      9.6491199      17.711744      WN 
# 16     15.5569853      18.996330      YV  

# Other aggregations 
ej4 = sqldf(" 
   SELECT 
   avg(arr_delay) as mean_arr_delay, 
   min(dep_delay) as min_dep_delay, 
   max(dep_delay) as max_dep_delay, 
   carrier 
   FROM  
   flights 
   GROUP BY 
   carrier 
")  

# We can compute the minimun, mean, and maximum values of a numeric value 
ej4 
#      mean_arr_delay    min_dep_delay   max_dep_delay   carrier 
# 1       7.3796692           -24           747          9E 
# 2       0.3642909           -24          1014          AA 
# 3      -9.9308886           -21           225          AS 
# 4       9.4579733           -43           502          B6
# 5       1.6443409           -33           960         DL 
# 6      15.7964311           -32           548         EV 
# 7      21.9207048           -27           853         F9 
# 8      20.1159055           -22           602         FL 
# 9      -6.9152047           -16          1301         HA 
# 10     10.7747334           -26          1137         MQ 
# 11     11.9310345           -14           154         OO 
# 12      3.5580111           -20           483         UA 
# 13      2.1295951           -19           500         US 
# 14      1.7644644           -20           653         VX 
# 15      9.6491199           -13           471         WN 
# 16     15.5569853           -16           387         YV  

### We could be also interested in knowing how many observations each carrier has  
ej5 = sqldf(" 
   SELECT 
   carrier, count(*) as count 
   FROM  
   flights 
   GROUP BY 
   carrier 
")  

ej5 
#      carrier  count 
# 1       9E    18460
# 2       AA   32729 
# 3       AS   714 
# 4       B6   54635 
# 5       DL   48110 
# 6       EV   54173 
# 7       F9   685 
# 8       FL   3260 
# 9       HA   342 
# 10      MQ   26397 
# 11      OO   32 
# 12      UA   58665 
# 13      US   20536 
# 14      VX   5162 
# 15      WN   12275 
# 16      YV   601 

SQL最有用的功能是联接。联接表示我们要使用一列将一个表中的表A和表B组合在一起,以匹配两个表的值。实际上,有几种不同类型的联接开始使用,它们将是最有用的:内部联接和左外部联接。

# Let’s create two tables: A and B to demonstrate joins.
A = data.frame(c1 = 1:4, c2 = letters[1:4]) 
B = data.frame(c1 = c(2,4,5,6), c2 = letters[c(2:5)])  

A 
# c1 c2 
# 1  a 
# 2  b 
# 3  c 
# 4  d  

B 
# c1 c2 
# 2  b 
# 4  c 
# 5  d 
# 6  e  

### INNER JOIN 
# This means to match the observations of the column we would join the tables by.   
inner = sqldf(" 
   SELECT 
   A.c1, B.c2 
   FROM 
   A INNER JOIN B 
   ON A.c1 = B.c1 
")  

# Only the rows that match c1 in both A and B are returned 
inner 
# c1 c2 
#  2  b 
#  4  c  

### LEFT OUTER JOIN
# the left outer join, sometimes just called left join will return the  
# first all the values of the column used from the A table  
left = sqldf(" 
  SELECT 
   A.c1, B.c2 
  FROM 
   A LEFT OUTER JOIN B 
   ON A.c1 = B.c1 
")  

# Only the rows that match c1 in both A and B are returned 
left 
#   c1    c2 
#    1  <NA> 
#    2    b 
#    3  <NA> 
#    4    c 

大数据分析-图表

分析数据的第一种方法是对数据进行可视化分析。这样做的目的通常是寻找变量与变量的单变量描述之间的关系。我们可以将这些策略划分为-

  • 单变量分析
  • 多元分析

单变量图形方法

单变量是一个统计术语。实际上,这意味着我们要独立于其余数据来分析变量。允许有效地做到这一点的情节是-

箱线图

箱形图通常用于比较分布。这是一种直观检查分布之间是否存在差异的好方法。我们可以看到不同切割的钻石价格之间是否存在差异。

# We will be using the ggplot2 library for plotting
library(ggplot2)  
data("diamonds")  

# We will be using the diamonds dataset to analyze distributions of numeric variables 
head(diamonds) 

#    carat   cut       color  clarity  depth  table   price    x     y     z 
# 1  0.23    Ideal       E      SI2    61.5    55     326     3.95  3.98  2.43 
# 2  0.21    Premium     E      SI1    59.8    61     326     3.89  3.84  2.31 
# 3  0.23    Good        E      VS1    56.9    65     327     4.05  4.07  2.31 
# 4  0.29    Premium     I      VS2    62.4    58     334     4.20  4.23  2.63 
# 5  0.31    Good        J      SI2    63.3    58     335     4.34  4.35  2.75 
# 6  0.24    Very Good   J      VVS2   62.8    57     336     3.94  3.96  2.48 

### Box-Plots
p = ggplot(diamonds, aes(x = cut, y = price, fill = cut)) + 
   geom_box-plot() + 
   theme_bw() 
print(p)

我们可以从图中看到,不同类型的切割中钻石价格的分布存在差异。

箱形图

直方图

source('01_box_plots.R')

# We can plot histograms for each level of the cut factor variable using 
facet_grid 
p = ggplot(diamonds, aes(x = price, fill = cut)) + 
   geom_histogram() + 
   facet_grid(cut ~ .) + 
   theme_bw() 

p  
# the previous plot doesn’t allow to visuallize correctly the data because of 
the differences in scale 
# we can turn this off using the scales argument of facet_grid  

p = ggplot(diamonds, aes(x = price, fill = cut)) + 
   geom_histogram() + 
   facet_grid(cut ~ ., scales = 'free') + 
   theme_bw() 
p  

png('02_histogram_diamonds_cut.png') 
print(p) 
dev.off()

上面的代码输出如下:

直方图

多元图形方法

探索性数据分析中的多元图形方法旨在发现不同变量之间的关系。通常有两种方法可以实现此目的:绘制数值变量的相关矩阵或简单地将原始数据绘制为散点图矩阵。

为了证明这一点,我们将使用Diamonds数据集。要遵循该代码,请打开脚本bda / part2 / charts / 03_multivariate_analysis.R

library(ggplot2)
data(diamonds) 

# Correlation matrix plots  
keep_vars = c('carat', 'depth', 'price', 'table') 
df = diamonds[, keep_vars]  
# compute the correlation matrix 
M_cor = cor(df) 

#          carat       depth      price      table 
# carat 1.00000000  0.02822431  0.9215913  0.1816175 
# depth 0.02822431  1.00000000 -0.0106474 -0.2957785 
# price 0.92159130 -0.01064740  1.0000000  0.1271339 
# table 0.18161755 -0.29577852  0.1271339  1.0000000  

# plots 
heat-map(M_cor)

该代码将产生以下输出-

热图

这是一个总结,它告诉我们价格和插入号之间有很强的相关性,而其他变量之间的相关性不大。

当我们有大量变量时,相关矩阵可能会很有用,在这种情况下,绘制原始数据将不切实际。如上所述,还可以显示原始数据-

library(GGally)
ggpairs(df) 

我们可以从图中看出,热图上显示的结果已得到确认,价格和克拉变量之间存在0.922的相关性。

散点图

可以在散点图矩阵的(3,1)索引中的价格克拉散点图中可视化此关系。

大数据分析-数据分析工具

有多种工具可让数据科学家有效地分析数据。通常,数据分析的工程方面侧重于数据库,数据科学家侧重于可以实现数据产品的工具。下一节将讨论不同工具的优势,重点是数据科学家在实践中最常使用的统计软件包。

R程式设计语言

R是一种开放源代码编程语言,专注于统计分析。就统计功能而言,它与SAS,SPSS等商业工具具有竞争力。它被认为是与其他编程语言(例如C,C ++或Fortran)的接口。

R的另一个优点是有大量可用的开源库。在CRAN中,可以免费下载6000多个软件包,在Github中,可以使用各种各样的R软件包。

在性能方面,考虑到大量可用的库,R慢于密集操作,而慢速代码部分则用编译语言编写。但是,如果您打算执行需要深层编写for循环的操作,那么R并不是您的最佳选择。为了进行数据分析,有一些不错的库,例如data.table,glmnet,ranger,xgboost,ggplot2,caret,它们可以将R用作更快的编程语言的接口。

用于数据分析的Python

Python是一种通用的编程语言,它包含大量致力于数据分析的库,例如pandas,scikit-learn,theano,numpyscipy

R中可用的大多数功能也可以在Python中完成,但是我们发现R更易于使用。如果您使用的是大型数据集,通常使用Python是比R更好的选择。Python可以非常有效地用于逐行清理和处理数据。在R中可以做到这一点,但在编写脚本任务方面不如Python高效。

对于机器学习,scikit-learn是一个很好的环境,它提供了大量算法,可以毫无问题地处理中等大小的数据集。与R的等效库(脱字符号)相比,scikit-learn具有更简洁,更一致的API。

茱莉亚(Julia)

Julia是用于技术计算的高级,高性能动态编程语言。它的语法与R或Python非常相似,因此,如果您已经在使用R或Python,那么在Julia中编写相同的代码应该非常简单。该语言是一种相当新的语言,并且在最近几年中有了很大的发展,因此目前绝对是一种选择。

我们建议使用Julia作为计算密集型的原型算法,例如神经网络。这是一个很好的研究工具。在生产中实现模型方面,Python可能有更好的选择。但是,由于Web服务可以用R,Python和Julia来实现模型的工程设计,因此这已不再是一个问题。

SAS

SAS是一种商业语言,仍在用于商业智能。它具有允许用户对各种应用程序进行编程的基本语言。它包含许多商业产品,这些非商业用户可以无需编程即可使用复杂的工具,例如神经网络库。

除了商业工具的明显缺点之外,SAS不能很好地扩展到大型数据集。即使是中型数据集,SAS也将出现问题,并使服务器崩溃。仅当您使用小型数据集并且用户不是专家数据科学家时,才建议使用SAS。对于高级用户,R和Python提供了一个更高产的环境。

SPSS

SPSS,当前是IBM用于统计分析的产品。它主要用于分析调查数据,对于无法编程的用户,它是一种不错的选择。它可能和SAS一样简单,但是就实现模型而言,它更简单,因为它提供了对模型进行评分的SQL代码。这段代码通常效率不高,但这只是一个开始,而SAS出售的产品会分别为每个数据库评分模型。对于小数据和缺乏经验的团队,SPSS和SAS一样是一个不错的选择。

但是,软件相当有限,使用R或Python,有经验的用户将提高效率几个数量级。

Matlab,八度

还有其他可用的工具,例如Matlab或其开放源代码版本(Octave)。这些工具主要用于研究。就功能而言,R或Python可以完成Matlab或Octave中可用的所有功能。仅当您对产品提供的支持感兴趣时,才购买该产品的许可证。

大数据分析-统计方法

分析数据时,可以采用统计方法。进行基本分析所需的基本工具是-

  • 相关分析
  • 方差分析
  • 假设检验

在处理大型数据集时,它不会带来任何问题,因为除了“相关分析”之外,这些方法的计算量并不大。在这种情况下,始终可以取样,并且结果应该可靠。

相关分析

关联分析试图找到数值变量之间的线性关系。这可以在不同的情况下使用。探索数据分析是一种常见的用法,该书的16.0.2节提供了这种方法的一个基本示例。首先,在上述示例中使用的相关度量基于皮尔森系数但是,还有另一种有趣的相关度量,不受异常值的影响。该度量称为斯皮尔曼相关性。

Spearman相关度量是更稳健的对异常值比Pearson法的存在,并给出数值变量之间的线性关系的更好的估计,当数据不是正态分布。

library(ggplot2)

# Select variables that are interesting to compare pearson and spearman 
correlation methods. 
x = diamonds[, c('x', 'y', 'z', 'price')]  

# From the histograms we can expect differences in the correlations of both 
metrics.  
# In this case as the variables are clearly not normally distributed, the 
spearman correlation 

# is a better estimate of the linear relation among numeric variables. 
par(mfrow = c(2,2)) 
colnm = names(x) 
for(i in 1:4) { 
   hist(x[[i]], col = 'deepskyblue3', main = sprintf('Histogram of %s', colnm[i])) 
} 
par(mfrow = c(1,1)) 

从下图中的直方图,我们可以预期两个指标的相关性会有所不同。在这种情况下,由于变量显然不是正态分布的,因此,斯皮尔曼相关性是对数字变量之间线性关系的更好估计。

非正态分布

为了计算R中的相关性,请打开包含此代码段的文件bda / part2 / statistical_methods / correlation / correlation.R

## Correlation Matrix - Pearson and spearman
cor_pearson <- cor(x, method = 'pearson') 
cor_spearman <- cor(x, method = 'spearman')  

### Pearson Correlation 
print(cor_pearson) 
#            x          y          z        price 
# x      1.0000000  0.9747015  0.9707718  0.8844352 
# y      0.9747015  1.0000000  0.9520057  0.8654209 
# z      0.9707718  0.9520057  1.0000000  0.8612494 
# price  0.8844352  0.8654209  0.8612494  1.0000000  

### Spearman Correlation 
print(cor_spearman) 
#              x          y          z      price 
# x      1.0000000  0.9978949  0.9873553  0.9631961 
# y      0.9978949  1.0000000  0.9870675  0.9627188 
# z      0.9873553  0.9870675  1.0000000  0.9572323 
# price  0.9631961  0.9627188  0.9572323  1.0000000 

卡方检验

卡方检验允许我们检验两个随机变量是否独立。这意味着每个变量的概率分布不会影响另一个变量。为了评估R中的测试,我们首先需要创建一个列联表,然后将该表传递给chisq.test R函数。

例如,让我们检查变量之间是否存在关联:钻石数据集中的切割和颜色。该测试正式定义为-

  • H0:可变切割和钻石是独立的
  • H1:可变切割和钻石不是独立的

我们假设这两个变量的名称之间存在关联,但是测试可以给出一个客观的“规则”,说明该结果是否有意义。

在下面的代码片段中,我们发现测试的p值为2.2e-16,实际上该值几乎为零。然后,在运行测试并进行了蒙特卡洛模拟后,我们发现p值为0.0004998,仍然远远低于阈值0.05。该结果意味着我们拒绝零假设(H0),因此我们认为cutcolor变量不是独立的。

library(ggplot2)

# Use the table function to compute the contingency table 
tbl = table(diamonds$cut, diamonds$color) 
tbl  

#              D    E    F    G    H    I    J 
# Fair       163  224  312  314  303  175  119 
# Good       662  933  909  871  702  522  307 
# Very Good 1513 2400 2164 2299 1824 1204  678 
# Premium   1603 2337 2331 2924 2360 1428  808 
# Ideal     2834 3903 3826 4884 3115 2093  896  

# In order to run the test we just use the chisq.test function. 
chisq.test(tbl)  

# Pearson’s Chi-squared test 
# data:  tbl 
# X-squared = 310.32, df = 24, p-value < 2.2e-16
# It is also possible to compute the p-values using a monte-carlo simulation 
# It's needed to add the simulate.p.value = TRUE flag and the amount of 
simulations 
chisq.test(tbl, simulate.p.value = TRUE, B = 2000)  

# Pearson’s Chi-squared test with simulated p-value (based on 2000 replicates) 
# data:  tbl 
# X-squared = 310.32, df = NA, p-value = 0.0004998

T检验

t检验的思想是评估名义变量的不同组之间的数字变量#分布是否存在差异。为了证明这一点,我将选择因子变量cut的“公平”和“理想”水平,然后将这两个组中的数字变量的值进行比较。

data = diamonds[diamonds$cut %in% c('Fair', 'Ideal'), ]

data$cut = droplevels.factor(data$cut) # Drop levels that aren’t used from the 
cut variable 
df1 = data[, c('cut', 'price')]  

# We can see the price means are different for each group 
tapply(df1$price, df1$cut, mean) 
# Fair    Ideal  
# 4358.758 3457.542

t测试在R中使用t.test函数实现。t.test的公式接口是使用它的最简单方法,其思想是数字变量由组变量解释。

例如:t.test(numeric_variable〜group_variable,data = data)在前面的示例中,numeric_variableprice,而group_variablecut

从统计角度来看,我们正在测试两组之间数字变量的分布是否存在差异。形式上,假设检验用无效(H0)假设和替代假设(H1)进行描述。

  • H0:“公平”和“理想”群体之间的价格变量分布没有差异

  • H1在公平群体和理想群体之间,价格变量的分布存在差异

可以使用以下代码在R中实现以下内容-

t.test(price ~ cut, data = data)

# Welch Two Sample t-test 
#  
# data:  price by cut 
# t = 9.7484, df = 1894.8, p-value < 2.2e-16 
# alternative hypothesis: true difference in means is not equal to 0 
# 95 percent confidence interval: 
#   719.9065 1082.5251 
# sample estimates: 
#   mean in group Fair mean in group Ideal  
#   4358.758            3457.542   

# Another way to validate the previous results is to just plot the 
distributions using a box-plot 
plot(price ~ cut, data = data, ylim = c(0,12000),  
   col = 'deepskyblue3') 

我们可以通过检查p值是否小于0.05来分析测试结果。在这种情况下,我们保留替代假设。这意味着我们发现了两个削减系数水平之间的价格差异。通过级别的名称,我们可以预期会出现此结果,但是我们不会期望Fail组中的平均价格会高于Ideal组中的平均价格。通过比较每个因素的均值,我们可以看到这一点。

情节命令产生的曲线图,显示了价格和切变量之间的关系。这是箱形图;我们已经在16.0.1节中介绍了该图,但是它基本上显示了我们正在分析的两个削减级别的价格变量分布。

不同级别的削减

方差分析

方差分析(ANOVA)是一种统计模型,用于通过比较每个组的均值和方差来分析组分布之间的差异,该模型是由Ronald Fisher开发的。ANOVA提供了几组均值是否相等的统计检验,因此将t检验推广到了两组以上。

方差分析可用于比较三个或更多组的统计显着性,因为进行多个两次样本t检验会增加犯下I类统计错误的机会。

在提供数学解释方面,需要以下内容来理解测试。

x ij = x +(x i − x)+(x ij − x)

这导致以下模型-

x ij =μ+ αi + ∈ij

其中μ是总平均值和α是第i个组平均值。该误差项IJ假定从正常的分布是独立同分布的。测试的原假设是-

α 12 = … =α ķ

在计算测试统计量方面,我们需要计算两个值-

  • 组间差的平方和-

小号小号d=一世ķĴñX一世¯¯X¯2个

  • 组内的平方和

小号小号dw ^=一世ķĴñX一世Ĵ¯¯X一世¯¯2个

其中SSD B的自由度为k-1,而SSD W的自由度为Nk。然后,我们可以定义每个指标的均方差。

MS B = SSD B /(k-1)

MS w = SSD w /(N-k)

最后,将方差分析中的检验统计量定义为以上两个量之比

F = MS B / MS w

下面一个F-分布K-1第N-k自由度的如果零假设成立,则F可能接近1。否则,组间均方MSB可能很大,从而导致F值很大。

基本上,ANOVA检查总方差的两个来源,看看哪个部分贡献更大。这就是为什么它被称为方差分析的原因,尽管其目的是比较组均值。

就计算统计量而言,在R中实际上很简单。下面的示例将演示如何进行统计并绘制结果。

library(ggplot2)
# We will be using the mtcars dataset 

head(mtcars) 
#                    mpg  cyl disp  hp drat  wt  qsec   vs am  gear carb 
# Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4 
# Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4 
# Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1 
# Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1 
# Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2 
# Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1  

# Let's see if there are differences between the groups of cyl in the mpg variable. 
data = mtcars[, c('mpg', 'cyl')]  
fit = lm(mpg ~ cyl, data = mtcars) 
anova(fit)  

# Analysis of Variance Table 
# Response: mpg 
#           Df Sum Sq Mean Sq F value    Pr(>F)     
# cyl        1 817.71  817.71  79.561 6.113e-10 *** 
# Residuals 30 308.33   10.28 
# Signif. codes:  0 *** 0.001 ** 0.01 * 0.05 . 
# Plot the distribution 
plot(mpg ~ as.factor(cyl), data = mtcars, col = 'deepskyblue3')

该代码将产生以下输出-

方差分析

我们在示例中获得的p值显着小于0.05,因此R返回符号“ ***”来表示这一点。这意味着我们拒绝原假设,并且发现cyl的不同组之间的mpg均值之间存在差异变量

机器学习进行数据分析

机器学习是计算机科学的一个子领域,它处理诸如模式识别,计算机视觉,语音识别,文本分析之类的任务,并且与统计和数学优化有着紧密的联系。应用包括搜索引擎,垃圾邮件过滤,光学字符识别(OCR)等的开发。数据挖掘,模式识别和统计学习领域之间的界限不明确,基本上都涉及类似的问题。

机器学习可以分为两种任务-

  • 监督学习
  • 无监督学习

监督学习

监督学习是指一种问题,其中有一个定义为矩阵X的输入数据,我们对预测响应y感兴趣其中X = {x 1,x 2,…,x n }具有n个预测变量,并且具有两个值y = {c 1,c 2 }

一个示例应用程序是使用人口统计特征作为预测变量来预测网络用户点击广告的可能性。通常称为预测点击率(CTR)。然后y = {click,not-click},预测变量可以是使用的IP地址,他进入站点的日期,用户所在的城市,国家/地区以及其他可用的功能。

无监督学习

无监督学习处理的问题是找到彼此相似的组而无需上课。有几种方法可用于学习从预测变量到找到在每个组中共享相似实例且彼此不同的组的映射。

无监督学习的一个示例应用是客户细分。例如,在电信行业中,一项常见的任务是根据用户提供给手机的使用情况对用户进行细分。这样一来,营销部门就可以针对每个群体使用不同的产品。

大数据分析-朴素贝叶斯分类器

朴素贝叶斯是一种用于构造分类器的概率技术。朴素贝叶斯分类器的特征假设是考虑给定类变量,特定特征的值独立于任何其他特征的值。

尽管前面提到的假设过于简单,但朴素的贝叶斯分类器在复杂的实际情况下仍具有良好的结果。朴素贝叶斯的一个优点是只需要少量训练数据即可估计分类所需的参数,并且可以逐步训练分类器。

朴素贝叶斯是一个条件概率模型:给定要分类的问题实例,用代表某些n个特征(独立变量)的向量x =(x 1,…,x n)表示,它为K中的每一个分配此实例概率可能的结果或类别。

pCķ|X1个Xñ

上述公式的问题在于,如果特征的数量n很大,或者特征可以具有大量的值,那么将这种模型基于概率表是不可行的。因此,我们重新制定了模型以使其更简单。使用贝叶斯定理,条件概率可以分解为-

pCķ|X=pCķpX|CķpX

这意味着在上述独立性假设下,类变量C的条件分布为-

pCķ|X1个Xñ=1个žpCķ一世=1个ñpX一世|Cķ

其中证据Z = p(x)是仅取决于x 1,…,x n的比例因子,如果特征变量的值已知,则该常数为常数。一个普遍的规则是选择最可能的假设。这称为最大后验或MAP决策规则。相应的分类器(贝叶斯分类器)是分配类标签的函数

ÿ^=Cķ

对于一些k如下-

ÿ^=一种[RG一种XpCķ一世=1个ñpX一世|Cķ

在R中实现算法是一个简单的过程。以下示例演示了如何训练朴素贝叶斯分类器并将其用于垃圾邮件过滤问题中的预测。

bda / part3 / naive_bayes / naive_bayes.R文件中提供了以下脚本

# Install these packages 
pkgs = c("klaR", "caret", "ElemStatLearn") 
install.packages(pkgs)  
library('ElemStatLearn') 
library("klaR") 
library("caret")  

# Split the data in training and testing 
inx = sample(nrow(spam), round(nrow(spam) * 0.9)) 
train = spam[inx,] 
test = spam[-inx,]  

# Define a matrix with features, X_train 
# And a vector with class labels, y_train 
X_train = train[,-58] 
y_train = train$spam  
X_test = test[,-58] 
y_test = test$spam  
# Train the model 
nb_model = train(X_train, y_train, method = 'nb',  
   trControl = trainControl(method = 'cv', number = 3)) 

# Compute  
preds = predict(nb_model$finalModel, X_test)$class 
tbl = table(y_test, yhat = preds) 
sum(diag(tbl)) / sum(tbl) 
# 0.7217391 

从结果可以看出,朴素贝叶斯模型的准确性为72%。这意味着模型可以正确分类72%的实例。

大数据分析-K-Means聚类

k均值聚类旨在将n个观察值划分为k个聚类,其中每个观察值均属于具有最均值的聚类,作为聚类的原型。这导致将数据空间划分为Voronoi单元。

给定一组观测值(x 1,x 2,…,x n,其中每个观测值都是d维实矢量,k均值聚类旨在将n个观测值划分为k个组G = {G 1,G 2,…,G k },以最小化如下定义的集群内平方和(WCSS)-

一种[RG一世ñ一世=1个ķX小号一世Xμ一世2个

后面的公式显示了最小化的目标函数,以便在k均值聚类中找到最佳原型。该公式的直觉是,我们希望找到彼此不同的组,并且每个组的每个成员应该与每个群集的其他成员相似。

以下示例演示了如何在R中运行k-means聚类算法。

library(ggplot2)
# Prepare Data 
data = mtcars  

# We need to scale the data to have zero mean and unit variance 
data <- scale(data)  

# Determine number of clusters 
wss <- (nrow(data)-1)*sum(apply(data,2,var)) 
for (i in 2:dim(data)[2]) { 
   wss[i] <- sum(kmeans(data, centers = i)$withinss) 
}  

# Plot the clusters 
plot(1:dim(data)[2], wss, type = "b", xlab = "Number of Clusters", 
   ylab = "Within groups sum of squares")

为了找到一个合适的K值,我们可以绘制K值不同的组内平方和。绘制此度量通常会随着添加更多组而减小,我们想找到一个点,其中K组内的平方和的减小的平方开始缓慢减小。在图中,该值最好用K = 6表示。

数字簇

现在已经定义了K的值,需要使用该值运行算法。

# K-Means Cluster Analysis
fit <- kmeans(data, 5) # 5 cluster solution 

# get cluster means  
aggregate(data,by = list(fit$cluster),FUN = mean) 

# append cluster assignment 
data <- data.frame(data, fit$cluster) 

大数据分析-关联规则

I = i 1,i 2,…,i n是一组称为项的n个二进制属性。D = t 1,t 2,…,t m是称为数据库的一组事务。D中的每个事务都有唯一的事务ID,并包含I中项的子集。规则定义为X⇒Y的形式,其中X,Y⊆I和X∩Y =∅。

项目集(对于短项目集)X和Y被称为规则的前项(左侧或LHS)和结果(右侧或RHS)。

为了说明这些概念,我们使用超市领域的一个小例子。项目集为I = {牛奶,面包,黄油,啤酒},下表显示了一个包含这些项目的小型数据库。

交易编号 项目
1个 牛奶,面包
2个 牛油面包
3 啤酒
4 牛奶,面包,黄油
5 牛油面包

超级市场的​​一个示例规则可以是{牛奶,面包}⇒{黄油},这意味着如果购买了牛奶和面包,顾客也会购买黄油。为了从所有可能规则的集合中选择有趣的规则,可以使用对重要性和兴趣的各种度量的约束。最著名的限制条件是支持和信心的最低阈值。

项目集X的支持supp(X)定义为包含该项目集的数据集中的交易比例。在表1的示例数据库中,项目集{牛奶,面包}支持2/5 = 0.4,因为它发生在所有事务的40%(5个事务中的2个)中。查找频繁的项目集可以看作是无监督学习问题的简化。

规则的置信度定义为conf(X⇒Y)= supp(X∪Y)/ supp(X)。例如,规则{牛奶,面包}⇒{黄油}在表1的数据库中的置信度为0.2 / 0.4 = 0.5,这意味着对于50%的包含牛奶和面包的交易,该规则是正确的。置信度可以解释为概率P(Y | X)的估计,概率P(Y | X)是在交易中也包含LHS的情况下在交易中找到规则的RHS的概率。

在位于bda / part3 / apriori.R中的脚本中,可以找到实现apriori算法的代码

# Load the library for doing association rules
# install.packages(’arules’) 
library(arules)  

# Data preprocessing 
data("AdultUCI") 
AdultUCI[1:2,]  
AdultUCI[["fnlwgt"]] <- NULL 
AdultUCI[["education-num"]] <- NULL  

AdultUCI[[ "age"]] <- ordered(cut(AdultUCI[[ "age"]], c(15,25,45,65,100)), 
   labels = c("Young", "Middle-aged", "Senior", "Old")) 
AdultUCI[[ "hours-per-week"]] <- ordered(cut(AdultUCI[[ "hours-per-week"]], 
   c(0,25,40,60,168)), labels = c("Part-time", "Full-time", "Over-time", "Workaholic")) 
AdultUCI[[ "capital-gain"]] <- ordered(cut(AdultUCI[[ "capital-gain"]], 
   c(-Inf,0,median(AdultUCI[[ "capital-gain"]][AdultUCI[[ "capitalgain"]]>0]),Inf)), 
   labels = c("None", "Low", "High")) 
AdultUCI[[ "capital-loss"]] <- ordered(cut(AdultUCI[[ "capital-loss"]], 
   c(-Inf,0, median(AdultUCI[[ "capital-loss"]][AdultUCI[[ "capitalloss"]]>0]),Inf)), 
   labels = c("none", "low", "high"))

为了使用先验算法生成规则,我们需要创建一个交易矩阵。以下代码显示了如何在R中执行此操作。

# Convert the data into a transactions format
Adult <- as(AdultUCI, "transactions") 
Adult 
# transactions in sparse format with 
# 48842 transactions (rows) and 
# 115 items (columns)  

summary(Adult)  
# Plot frequent item-sets 
itemFrequencyPlot(Adult, support = 0.1, cex.names = 0.8)  

# generate rules 
min_support = 0.01 
confidence = 0.6 
rules <- apriori(Adult, parameter = list(support = min_support, confidence = confidence))

rules 
inspect(rules[100:110, ]) 
# lhs                             rhs                      support     confidence  lift
# {occupation = Farming-fishing} => {sex = Male}        0.02856148  0.9362416   1.4005486
# {occupation = Farming-fishing} => {race = White}      0.02831579  0.9281879   1.0855456
# {occupation = Farming-fishing} => {native-country     0.02671881  0.8758389   0.9759474
                                       = United-States} 

大数据分析-决策树

决策树是用于监督学习问题(例如分类或回归)的算法。决策树或分类树是其中每个内部(非叶子)节点都标记有输入要素的树。来自标记有特征的节点的弧线会标记有该特征的每个可能值。树的每个叶子都标记有一个类别或类别上的概率分布。

通过基于属性值测试将源集划分为子集,可以“学习”树。此过程在每个派生子集上以称为递归分区的递归方式重复进行当节点上的子集具有目标变量的所有相同值时,或者当拆分不再为预测增加值时,递归完成。这种自上而下的决策树归纳过程是贪婪算法的一个示例,它是学习决策树的最常见策略。

数据挖掘中使用的决策树有两种主要类型-

  • 分类树-当响应是名义变量时,例如,电子邮件是否为垃圾邮件。

  • 回归树-可以将预测结果视为实数时(例如,工人的薪水)。

决策树是一种简单的方法,因此存在一些问题。问题之一是决策树产生的结果模型的高方差。为了减轻这个问题,开发了决策树的集成方法。当前有两组广泛使用的合奏方法-

  • 打包决策树-通过反复替换替换训练数据并对树投票以达成共识预测,这些树可用于构建多个决策树。该算法被称为随机森林。

  • 提升决策树-梯度提升结合了弱学习者;在这种情况下,决策树将以迭代的方式成为一个强大的学习者。它使弱树适合数据,并反复保持适合弱学习者,以纠正先前模型的错误。

# Install the party package
# install.packages('party') 
library(party) 
library(ggplot2)  

head(diamonds) 
# We will predict the cut of diamonds using the features available in the 
diamonds dataset. 
ct = ctree(cut ~ ., data = diamonds) 

# plot(ct, main="Conditional Inference Tree") 
# Example output 
# Response:  cut  
# Inputs:  carat, color, clarity, depth, table, price, x, y, z  

# Number of observations:  53940  
#  
# 1) table <= 57; criterion = 1, statistic = 10131.878 
#   2) depth <= 63; criterion = 1, statistic = 8377.279 
#     3) table <= 56.4; criterion = 1, statistic = 226.423 
#       4) z <= 2.64; criterion = 1, statistic = 70.393 
#         5) clarity <= VS1; criterion = 0.989, statistic = 10.48 
#           6) color <= E; criterion = 0.997, statistic = 12.829 
#             7)*  weights = 82  
#           6) color > E  

#Table of prediction errors 
table(predict(ct), diamonds$cut) 
#            Fair  Good Very Good Premium Ideal 
# Fair       1388   171        17       0    14 
# Good        102  2912       499      26    27 
# Very Good    54   998      3334     249   355 
# Premium      44   711      5054   11915  1167 
# Ideal        22   114      3178    1601 19988 
# Estimated class probabilities 
probs = predict(ct, newdata = diamonds, type = "prob") 
probs = do.call(rbind, probs) 
head(probs)

大数据分析-Logistic回归

Logistic回归是一种分类模型,其中的响应变量是分类的。它是一种来自统计的算法,用于监督分类问题。在逻辑回归中,我们试图在以下等式中找到参数矢量β,以最小化成本函数。

ØG一世Ťp一世=ñp一世1个p一世=β0+β1个X1个一世++βķXķ一世

以下代码演示了如何在R中拟合逻辑回归模型。在这里,我们将使用垃圾邮件数据集来演示逻辑回归,这一点与Naive Bayes所使用的相同。

从准确性方面的预测结果来看,我们发现回归模型在测试集中的准确性达到了92.5%,相比之下,朴素贝叶斯分类器的准确性达到了72%。

library(ElemStatLearn)
head(spam) 

# Split dataset in training and testing 
inx = sample(nrow(spam), round(nrow(spam) * 0.8)) 
train = spam[inx,] 
test = spam[-inx,]  

# Fit regression model 
fit = glm(spam ~ ., data = train, family = binomial()) 
summary(fit)  

# Call: 
#   glm(formula = spam ~ ., family = binomial(), data = train) 
#  

# Deviance Residuals:  
#   Min       1Q   Median       3Q      Max   
# -4.5172  -0.2039   0.0000   0.1111   5.4944
# Coefficients: 
# Estimate Std. Error z value Pr(>|z|)     
# (Intercept) -1.511e+00  1.546e-01  -9.772  < 2e-16 *** 
# A.1         -4.546e-01  2.560e-01  -1.776 0.075720 .   
# A.2         -1.630e-01  7.731e-02  -2.108 0.035043 *   
# A.3          1.487e-01  1.261e-01   1.179 0.238591     
# A.4          2.055e+00  1.467e+00   1.401 0.161153     
# A.5          6.165e-01  1.191e-01   5.177 2.25e-07 *** 
# A.6          7.156e-01  2.768e-01   2.585 0.009747 **  
# A.7          2.606e+00  3.917e-01   6.652 2.88e-11 *** 
# A.8          6.750e-01  2.284e-01   2.955 0.003127 **  
# A.9          1.197e+00  3.362e-01   3.559 0.000373 *** 
# Signif. codes:  0 *** 0.001 ** 0.01 * 0.05 . 0.1  1  

### Make predictions 
preds = predict(fit, test, type = ’response’) 
preds = ifelse(preds > 0.5, 1, 0) 
tbl = table(target = test$spam, preds) 
tbl 

#         preds 
# target    0   1 
# email   535  23 
# spam     46 316 
sum(diag(tbl)) / sum(tbl) 
# 0.925

大数据分析-时间序列分析

时间序列是按日期或时间戳索引的分类或数字变量的观测序列。时间序列数据的一个明显例子是股价的时间序列。在下表中,我们可以看到时间序列数据的基本结构。在这种情况下,每小时记录一次观察结果。

时间戳记 股票价格
2015-10-11 09:00:00 100
2015-10-11 10:00:00 110
2015-10-11 11:00:00 105
2015-10-11 12:00:00 90
2015-10-11 13:00:00 120

通常,时间序列分析的第一步是绘制序列,通常使用折线图完成。

时间序列分析的最常见应用是使用数据的时间结构来预测数值的未来值。这意味着,可用的观测值将用于预测未来的价值。

数据的时间顺序意味着传统的回归方法没有用。为了建立可靠的预测,我们需要考虑数据时间顺序的模型。

时间序列分析中使用最广泛的模型称为自回归移动平均值(ARMA)。该模型由两部分组成,即自回归(AR)部分和移动平均值(MA)部分。该模型通常称为ARMA(p,q)模型,其中p是自回归部分的阶数,q是移动平均部分的阶数。

自回归模型

AR(p)读为p阶的自回归模型。从数学上讲,它写为-

XŤ=C+一世=1个Pϕ一世XŤ一世+εŤ

其中{φ 1,…,φ p }将被估计的参数,c为常数,ε随机变量表示白噪声。参数值需要一些约束,以使模型保持稳定。

移动平均线

符号MA(Q)指令的移动平均模型q

XŤ=μ+εŤ+一世=1个qθ一世εŤ一世

其中θ 1,……,θ q是该模型的参数,μ是X的期望值,和ε,ε吨- 1,…是,白噪声误差项。

自回归移动平均线

ARMA(P,Q)模型结合p自回归项和q移动平均而言。在数学上,该模型用以下公式表示-

XŤ=C+εŤ+一世=1个Pϕ一世XŤ1个+一世=1个qθ一世εŤ一世

我们可以看到ARMA(p,q)模型是AR(p)MA(q)模型的组合。

为了使模型更直观,请考虑方程的AR部分试图估计X t-i观测值的参数,以便预测X t中变量的值最后,它是过去值的加权平均值。MA部分使用相同的方法,但存在先前观测值εt − i的误差因此,最后,模型的结果是加权平均值。

以下代码段演示了如何在R中实现ARMA(p,q)

# install.packages("forecast")
library("forecast")  

# Read the data 
data = scan('fancy.dat') 
ts_data <- ts(data, frequency = 12, start = c(1987,1)) 
ts_data  
plot.ts(ts_data)

绘制数据通常是找出数据中是否存在时间结构的第一步。从图中可以看出,每年年底都有强劲的峰值。

时间序列图

以下代码使ARMA模型适合该数据。它可以运行几种模型组合,并选择误差较小的模型。

# Fit the ARMA model
fit = auto.arima(ts_data) 
summary(fit) 

# Series: ts_data  
# ARIMA(1,1,1)(0,1,1)[12]                     
#    Coefficients: 
#    ar1     ma1    sma1 
# 0.2401  -0.9013  0.7499 
# s.e.  0.1427   0.0709  0.1790 

#  
# sigma^2 estimated as 15464184:  log likelihood = -693.69 
# AIC = 1395.38   AICc = 1395.98   BIC = 1404.43 

# Training set error measures: 
#                 ME        RMSE      MAE        MPE        MAPE      MASE       ACF1 
# Training set   328.301  3615.374  2171.002  -2.481166  15.97302  0.4905797 -0.02521172

大数据分析-文本分析

在本章中,我们将使用本书第1部分中抓取的数据。数据中的文字描述了自由职业者的个人资料,以及他们按美元收取的小时费率。下一节的想法是建立一个模型,该模型给出了自由职业者的技能,我们能够预测其小时薪。

下面的代码显示了如何转换原始文本,在这种情况下,原始文本具有成组的单词矩阵形式,具有用户的技能。为此,我们使用一个名为tm的R库。这意味着我们为语料库中的每个单词创建一个变量,其中包含每个变量的出现次数。

library(tm)
library(data.table)  

source('text_analytics/text_analytics_functions.R') 
data = fread('text_analytics/data/profiles.txt') 
rate = as.numeric(data$rate) 
keep = !is.na(rate) 
rate = rate[keep]  

### Make bag of words of title and body 
X_all = bag_words(data$user_skills[keep]) 
X_all = removeSparseTerms(X_all, 0.999) 
X_all 

# <<DocumentTermMatrix (documents: 389, terms: 1422)>> 
#   Non-/sparse entries: 4057/549101 
# Sparsity           : 99% 
# Maximal term length: 80 
# Weighting          : term frequency - inverse document frequency (normalized) (tf-idf) 

### Make a sparse matrix with all the data 
X_all <- as_sparseMatrix(X_all)

现在,我们已将文本表示为稀疏矩阵,我们可以拟合一个将提供稀疏解决方案的模型。对于这种情况,一个很好的选择是使用LASSO(最小绝对收缩和选择算子)。这是一个回归模型,能够选择最相关的特征来预测目标。

train_inx = 1:200
X_train = X_all[train_inx, ] 
y_train = rate[train_inx]  
X_test = X_all[-train_inx, ] 
y_test = rate[-train_inx]  

# Train a regression model 
library(glmnet) 
fit <- cv.glmnet(x = X_train, y = y_train,  
   family = 'gaussian', alpha = 1,  
   nfolds = 3, type.measure = 'mae') 
plot(fit)  

# Make predictions 
predictions = predict(fit, newx = X_test) 
predictions = as.vector(predictions[,1]) 
head(predictions)  

# 36.23598 36.43046 51.69786 26.06811 35.13185 37.66367 
# We can compute the mean absolute error for the test data 
mean(abs(y_test - predictions)) 
# 15.02175

现在,我们有了一个模型,该模型可以给出一组技能来预测自由职业者的时薪。如果收集更多数据,则模型的性能将提高,但是实现此管道的代码将相同。

大数据分析-在线学习

在线学习是机器学习的一个子领域,它可以将监督学习模型扩展到大量数据集。基本思想是,我们不需要读取内存中的所有数据即可适应模型,只需要一次读取每个实例。

在这种情况下,我们将展示如何使用逻辑回归来实现在线学习算法。与大多数监督学习算法一样,成本函数被最小化。在逻辑回归中,成本函数定义为-

Ĵθ=1个[一世=1个ÿ一世ØGHθX一世+1个ÿ一世ØG1个HθX一世]

其中Ĵ(θ)表示的成本函数和ħ θ(x)的表示的假设。如果是逻辑回归,则使用以下公式进行定义-

HθX=1个1个+ËθŤX

现在我们已经定义了成本函数,我们需要找到一种算法来最小化它。实现此目的的最简单算法称为随机梯度下降。用于逻辑回归模型权重的算法的更新规则定义为-

θĴ:=θĴαHθXÿX

以下算法有几种实现方式,但到目前为止,vowpal wabbit库中实现的一种算法是最成熟的一种。该库允许训练大规模回归模型并使用少量RAM。用创建者自己的话来说,它被描述为:“ Vowpal Wabbit(VW)项目是由Microsoft Research和(以前是Yahoo! Research)赞助的一种快速的核心学习系统”。

我们将使用kaggle比赛中的泰坦尼克号数据集原始数据可以在bda / part3 / vw文件夹中找到。在这里,我们有两个文件-

  • 我们有训练数据(train_titanic.csv),并且
  • 未标记的数据,以便做出新的预测(test_titanic.csv)。

为了将csv格式转换为vowpal wabbit输入格式,请使用csv_to_vowpal_wabbit.py python脚本。您显然需要为此安装python。导航到bda / part3 / vw文件夹,打开终端并执行以下命令-

python csv_to_vowpal_wabbit.py

请注意,对于本节,如果您使用的是Windows,则需要安装Unix命令行,为此输入cygwin网站。

打开终端,并在文件夹bda / part3 / vw中,执行以下命令-

vw train_titanic.vw -f model.vw --binary --passes 20 -c -q ff --sgd --l1 
0.00000001 --l2 0.0000001 --learning_rate 0.5 --loss_function logistic

让我们分解一下大众电话的每个论点的含义。

  • -f model.vw-表示我们将模型保存在model.vw文件中,以便以后进行预测

  • –binary-将丢失报告为带有-1,1标签的二进制分类

  • –passs 20-数据被使用20次以学习权重

  • -c-创建一个缓存文件

  • -q ff-在f名称空间中使用二次特征

  • –sgd –使用常规/经典/简单的随机梯度下降更新,即非自适应,非规范化和不变式。

  • –l1 –l2 -L1和L2范数正则化

  • –learning_rate 0.5-更新规则公式中定义的学习率α

以下代码显示了在命令行中运行回归模型的结果。结果中,我们获得了平均对数损失和有关算法性能的小报告。

-loss_function logistic
creating quadratic features for pairs: ff  
using l1 regularization = 1e-08 
using l2 regularization = 1e-07 

final_regressor = model.vw 
Num weight bits = 18 
learning rate = 0.5 
initial_t = 1 
power_t = 0.5 
decay_learning_rate = 1 
using cache_file = train_titanic.vw.cache 
ignoring text input in favor of cache input 
num sources = 1 

average    since         example   example  current  current  current 
loss       last          counter   weight    label   predict  features 
0.000000   0.000000          1      1.0    -1.0000   -1.0000       57 
0.500000   1.000000          2      2.0     1.0000   -1.0000       57 
0.250000   0.000000          4      4.0     1.0000    1.0000       57 
0.375000   0.500000          8      8.0    -1.0000   -1.0000       73 
0.625000   0.875000         16     16.0    -1.0000    1.0000       73 
0.468750   0.312500         32     32.0    -1.0000   -1.0000       57 
0.468750   0.468750         64     64.0    -1.0000    1.0000       43 
0.375000   0.281250        128    128.0     1.0000   -1.0000       43 
0.351562   0.328125        256    256.0     1.0000   -1.0000       43 
0.359375   0.367188        512    512.0    -1.0000    1.0000       57 
0.274336   0.274336       1024   1024.0    -1.0000   -1.0000       57 h 
0.281938   0.289474       2048   2048.0    -1.0000   -1.0000       43 h 
0.246696   0.211454       4096   4096.0    -1.0000   -1.0000       43 h 
0.218922   0.191209       8192   8192.0     1.0000    1.0000       43 h 

finished run 
number of examples per pass = 802 
passes used = 11 
weighted example sum = 8822 
weighted label sum = -2288 
average loss = 0.179775 h 
best constant = -0.530826 
best constant’s loss = 0.659128 
total feature number = 427878

现在我们可以使用受过训练model.vw生成具有新数据的预测。

vw -d test_titanic.vw -t -i model.vw -p predictions.txt 

上一条命令中生成的预测未标准化为适合[0,1]范围。为了做到这一点,我们使用了S形变换。

# Read the predictions
preds = fread('vw/predictions.txt')  

# Define the sigmoid function 
sigmoid = function(x) { 
   1 / (1 + exp(-x)) 
} 
probs = sigmoid(preds[[1]])  

# Generate class labels 
preds = ifelse(probs > 0.5, 1, 0) 
head(preds) 
# [1] 0 1 0 0 1 0 

其他教程链接:

觉得文章有用?

点个广告表达一下你的爱意吧 !😁

评论区

Protected with IP Blacklist CloudIP Blacklist Cloud