R 和 Hadoop 大数据分析(二)

原文:annas-archive.org/md5/b7f3a14803c1b4d929732471e0b28932

译者:飞龙

协议:CC BY-NC-SA 4.0

第五章 使用 R 和 Hadoop 学习数据分析

在前面的章节中,我们学习了 R 和 Hadoop 的安装、配置和集成。

在本章中,我们将学习如何在集成的 R 和 Hadoop 环境中执行数据分析操作。由于本章旨在介绍数据分析,我们将通过一个有效的数据分析周期来理解这一过程。

在本章中,我们将学习:

  • 理解数据分析项目生命周期

  • 理解数据分析问题

理解数据分析项目生命周期

在处理数据分析项目时,有一些固定任务需要遵循,以便获得预期的结果。因此,我们将构建一个数据分析项目周期,这将是一组标准的数据驱动流程,旨在有效地将数据转化为洞察力。项目生命周期中定义的数据分析流程应按顺序执行,以便有效地使用输入数据集实现目标。这个数据分析过程可能包括识别数据分析问题、设计和收集数据集、数据分析和数据可视化。

数据分析项目生命周期的各个阶段见下图:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_05_01.jpg

让我们从这些阶段的角度来看一下如何进行数据分析。

确定问题

今天,商业分析趋势通过对 Web 数据集执行数据分析来推动业务增长。由于他们的数据量逐渐增加,他们的分析应用需要具备可扩展性,以便从数据集中提取洞察。

借助 Web 分析,我们可以解决商业分析问题。假设我们有一个大型电子商务网站,我们希望了解如何增加业务量。我们可以通过按受欢迎程度将网站的重要页面分为高、中、低类别,来识别这些重要页面。根据这些流行页面的类型、流量来源和内容,我们将能够制定出通过提高网站流量和改进内容来改善业务的路线图。

设计数据需求

为了对特定问题进行数据分析,需要来自相关领域的数据集。根据领域和问题规格,可以决定数据源,并根据问题定义,定义这些数据集的数据属性。

例如,如果我们要进行社交媒体分析(问题规格),我们可以使用 Facebook 或 Twitter 作为数据源。为了识别用户特征,我们需要用户档案信息、点赞和帖子作为数据属性。

数据预处理

在数据分析中,我们并不总是使用相同的数据源、数据属性、数据工具和算法,因为它们并不总是以相同的格式使用数据。这导致需要进行数据操作,例如数据清洗、数据聚合、数据增强、数据排序和数据格式化,以便将数据提供为所有数据工具和算法所支持的格式,这些工具和算法将用于数据分析。

简而言之,预处理用于执行数据操作,将数据转换为固定的数据格式,然后将数据提供给算法或工具。数据分析过程将以该格式化数据作为输入开始。

在大数据情况下,数据集需要格式化并上传到Hadoop 分布式文件系统HDFS),并由 Hadoop 集群中的各种节点使用映射器和减少器进一步处理。

对数据进行分析

数据在满足数据分析算法所需格式后,将进行数据分析操作。数据分析操作旨在通过数据挖掘概念从数据中发现有意义的信息,以便做出更好的商业决策。这些操作可能会使用描述性分析或预测性分析来进行商业智能。

数据分析可以通过各种机器学习和自定义算法概念进行,例如回归、分类、聚类和基于模型的推荐。对于大数据,相同的算法可以转换为 MapReduce 算法,在 Hadoop 集群上运行,通过将它们的数据分析逻辑转化为 MapReduce 任务,这些任务将运行在 Hadoop 集群上。这些模型需要通过机器学习概念的各个评估阶段进一步评估和改进。改进或优化后的算法可以提供更好的洞察。

数据可视化

数据可视化用于展示数据分析的输出。可视化是一种交互式的方式来展示数据洞察。可以使用各种数据可视化软件以及 R 包来完成这项工作。R 有多种用于数据集可视化的包。如下所示:

  • ggplot2:这是Dr. Hadley Wickhamhad.co.nz/)提出的图形语法的实现。欲了解更多信息,请参阅cran.r-project.org/web/packages/ggplot2/

  • rCharts:这是一个 R 包,用于通过Markus GesmannDiego de Castillo提供的熟悉的网格式绘图界面,创建、定制并发布交互式 JavaScript 可视化。欲了解更多信息,请参阅ramnathv.github.io/rCharts/

以下是使用 R 进行可视化的一些流行示例:

理解数据分析问题

在这一部分,我们包含了三个实际的数据分析问题,涉及使用 R 和 Hadoop 技术的各个阶段的基于数据的活动。这些数据分析问题的定义旨在帮助读者理解如何利用 R 的函数、包以及 Hadoop 的计算能力进行大数据分析。

数据分析问题的定义如下:

  • 探索网页分类

  • 计算股市变化频率

  • 预测推土机蓝色书籍的销售价格(案例研究)

探索网页分类

这个数据分析问题的设计目的是识别网站网页的类别,基于页面的访问次数,可以将其按受欢迎程度分为高、中或低(常规)。在设计数据分析生命周期的数据需求阶段时,我们将看到如何从Google Analytics收集这些类型的数据。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_05_02.jpg

确定问题

由于这是一个网页分析问题,该问题的目标是识别为网站设计的网页的重要性。基于这些信息,可以改善或增加较不受欢迎页面的内容、设计或访问量。

设计数据需求

在这一部分,我们将处理该数据分析问题的数据需求和数据收集。首先,让我们看看如何为该问题实现数据需求。

由于这是一个网页分析问题,我们将使用 Google Analytics 数据源。要从 Google Analytics 中提取这些数据,我们需要有一个现有的 Google Analytics 账户,并且该账户上存储有网页流量数据。为了增加受欢迎度,我们将需要所有网页的访问信息。此外,Google Analytics 中还提供了许多与维度和指标相关的其他属性。

理解所需的 Google Analytics 数据属性

从 Google Analytics 提取的数据集的表头格式如下:

date, source, pageTitle, pagePath
  • date:这是网页被访问的日期

  • source:这是指向网页的推荐链接

  • pageTitle:这是网页的标题

  • pagePath:这是网页的 URL

数据收集

由于我们将从 Google Analytics 中提取数据,因此我们需要使用 RGoogleAnalytics,这是一个用于在 R 中提取 Google Analytics 数据集的 R 库。要提取数据,您需要先在 R 中安装此插件。然后,您将能够使用其函数。

以下是从 Google Analytics 提取数据的代码:

# Loading the RGoogleAnalytics library
require("RGoogleAnalyics")

# Step 1\. Authorize your account and paste the access_token
query <- QueryBuilder()
access_token <- query$authorize()

# Step 2\. Create a new Google Analytics API object
ga <- RGoogleAnalytics()

# To retrieve profiles from Google Analytics
ga.profiles <- ga$GetProfileData(access_token)

# List the GA profiles 
ga.profiles

# Step 3\. Setting up the input parameters
profile <- ga.profiles$id[3] 
startdate <- "2010-01-08"
enddate <- "2013-08-23"
dimension <- "ga:date,ga:source,ga:pageTitle,ga:pagePath"
metric <- "ga:visits"
sort <- "ga:visits"
maxresults <- 100099

# Step 4\. Build the query string, use the profile by setting its index value
query$Init(start.date = startdate,
           end.date = enddate,
           dimensions = dimension,
           metrics = metric,

           max.results = maxresults,
           table.id = paste("ga:",profile,sep="",collapse=","),
           access_token=access_token)

# Step 5\. Make a request to get the data from the API
ga.data <- ga$GetReportData(query)

# Look at the returned data
head(ga.data)
write.csv(ga.data,"webpages.csv", row.names=FALSE)

上述文件将在章节内容中提供下载。

数据预处理

现在,我们有了 Google Analytics 的原始数据,存储在 CSV 文件中。在将数据提供给 MapReduce 算法之前,我们需要处理这些数据。

需要对数据集进行两项主要更改:

  • 需要从 pagePath 列中移除查询参数,如下所示:

    pagePath <- as.character(data$pagePath)
    pagePath <- strsplit(pagePath,"\\?")
    pagePath <- do.call("rbind", pagePath)
    pagePath <- pagePath [,1]
    
  • 需要创建新的 CSV 文件,如下所示:

    data  <- data.frame(source=data$source, pagePath=d,visits =)
    write.csv(data, "webpages_mapreduce.csv" , row.names=FALSE)
    

执行数据分析

为了对网站页面进行分类,我们将构建并运行与 R 和 Hadoop 集成的 MapReduce 算法。正如在第二章《编写 Hadoop MapReduce 程序》中已讨论的那样,编写 Hadoop MapReduce 程序,有时我们需要使用多个 Mappers 和 Reducers 来执行数据分析;这意味着需要使用链式 MapReduce 任务。

在链式 MapReduce 任务中,多个 Mappers 和 Reducers 可以通过某种方式进行通信,使得第一个任务的输出作为第二个任务的输入。MapReduce 执行顺序如下图所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_05_03.jpg

链式 MapReduce

现在让我们开始编程任务以执行分析:

  1. 通过设置 Hadoop 变量并加载 RHadoop 库中的 rmr2rhdfs 包来初始化:

    # setting up the Hadoop variables need by RHadoop
    Sys.setenv(HADOOP_HOME="/usr/local/hadoop/")
    Sys.setenv(HADOOP_CMD="/usr/local/hadoop/bin/hadoop")
    
    # Loading the RHadoop libraries rmr2 and rhdfs
    library(rmr2)
    library(rhdfs)
    
    # To initializing hdfs
    hdfs.init()
    
  2. 上传数据集到 HDFS:

    # First uploading the data to R console,
    webpages <- read.csv("/home/vigs/Downloads/webpages_mapreduce.csv")
    
    # saving R file object to HDFS,
    webpages.hdfs <- to.dfs(webpages) 
    

现在我们将看到这些分析的 Hadoop MapReduce 任务 1 的开发过程。我们将这个任务分为 Mapper 和 Reducer。由于有两个 MapReduce 任务,因此将有两个 Mappers 和 Reducers。还需要注意的是,我们只需要为两个任务创建一个文件,包含所有的 Mappers 和 Reducers。Mapper 和 Reducer 将通过定义它们各自的函数来建立。

让我们来看一下 MapReduce 任务 1。

  • Mapper 1:代码如下:

    mapper1 <- function(k,v) {
    
     # To storing pagePath column data in to key object
     key <- v[2]
    
     # To store visits column data into val object
     Val <- v[3]
    
     # emitting key and value for each row
     keyval(key, val)
    }
    totalvisits <- sum(webpages$visits)
    
  • Reducer 1:代码如下:

    reducer1 <- function(k,v) {
    
      # Calculating percentage visits for the specific URL
      per <- (sum(v)/totalvisits)*100
      # Identify the category of URL
      if (per <33 )
     {
    val <- "low"
    }
     if (per >33 && per < 67)
     {
     val <- "medium"
     }
     if (per > 67)
     {
     val <- "high"
     }
    
     # emitting key and values
     keyval(k, val)
    }
    
  • MapReduce 任务 1 的输出:信息的中间输出如下截图所示:https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_05_18.jpg

上述截图中的输出仅为 MapReduce 任务 1 的输出信息。这可以视为一个中间输出,其中仅考虑了整个数据集中的 100 行数据来提供输出。在这些行中,23 个 URL 是唯一的;因此,输出提供了 23 个 URL。

让我们看看 Hadoop MapReduce 任务 2:

  • Mapper 2:代码如下:

    #Mapper:
    mapper2 <- function(k, v) {
    
    # Reversing key and values and emitting them 
     keyval(v,k)
    }
    
  • Reducer 2:代码如下:

    key <- NA
    val <- NULL
    # Reducer:
    reducer2  <-  function(k, v) {
    
    # for checking whether key-values are already assigned or not.
     if(is.na(key)) {
     key <- k
     val <- v
      } else {
       if(key==k) {
     val <- c(val,v)
      } else{
       key <- k
       val <- v
      }
     }
    # emitting key and list of values 
    keyval(key,list(val))
    }
    

    提示

    在执行 MapReduce 作业之前,请启动所有 Hadoop 守护进程,并通过 hdfs.init() 方法检查 HDFS 连接。如果您的 Hadoop 守护进程尚未启动,可以通过 $hduser@ubuntu :~ $HADOOP_HOME/bin/start-all.sh 启动它们。

一旦我们准备好 Mapper 和 Reducer 的逻辑,就可以通过 rmr2 包中的 MapReduce 方法执行 MapReduce 作业。在这里,我们开发了多个 MapReduce 作业,因此我们需要在 mapreduce 函数内调用 mapreduce 函数,并传入所需的参数。

调用链式 MapReduce 作业的命令如下图所示:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_05_04.jpg

以下是从 HDFS 检索生成的输出的命令:

from.dfs(output)

在执行 Hadoop MapReduce 时,执行日志输出将打印到终端,用于监控目的。我们将通过将 MapReduce 作业 1 和 MapReduce 作业 2 分成不同的部分来理解它们。

MapReduce 作业 1 的详细信息如下:

对于 MapReduce 作业 2。

这个链式 MapReduce 作业的输出存储在 HDFS 位置,可以通过以下命令检索:

from.dfs(output)

前述命令的响应如下图所示(仅显示数据集前 1000 行的输出):

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_05_11.jpg

数据可视化

我们使用三个类别收集了网页分类输出。我认为我们最好的做法是简单地列出这些 URL。但如果我们有更多的信息,比如来源,我们可以将网页表示为一个图的节点,通过用户跟随链接的有向边来标记其流行度。这可以带来更多有价值的见解。

计算股票市场变化的频率

这个数据分析 MapReduce 问题旨在计算股票市场变化的频率。

确定问题

由于这是一个典型的股票市场数据分析问题,它将计算某一特定符号的股票市场过去变动的频率,比如傅里叶变换。基于这些信息,投资者可以获得关于不同时间段变化的更多见解。因此,这次分析的目标是计算百分比变化的频率。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_05_12.jpg

设计数据需求

对于本次股票市场分析,我们将使用 Yahoo! Finance 作为输入数据集。我们需要检索特定符号的股票信息。为此,我们将使用 Yahoo! API,传递以下参数:

  • 从某月开始

  • 从某天开始

  • 从某年开始

  • 到某月

  • 到某天

  • 到某年

  • 符号

提示

有关此 API 的更多信息,请访问developer.yahoo.com/finance/

数据预处理

为了对提取的数据集进行分析,我们将使用 R 来执行以下命令:

stock_BP <- read.csv("http://ichart.finance.yahoo.com/table.csv?s=BP")

或者你也可以通过终端下载:

wget http://ichart.finance.yahoo.com/table.csv?s=BP
#exporting to csv file

write.csv(stock_BP,"table.csv", row.names=FALSE)

然后通过创建一个特定的 Hadoop 目录将其上传到 HDFS:

# creating /stock directory in hdfs
bin/hadoop dfs -mkdir /stock

# uploading table.csv to hdfs in /stock directory
bin/hadoop dfs -put /home/Vignesh/downloads/table.csv /stock/ 

对数据进行分析

为了执行数据分析操作,我们将使用 R 和 Hadoop 进行流式处理(无需HadoopStreaming包)。因此,这个 MapReduce 作业的开发可以在没有任何 RHadoop 集成库/包的情况下完成。

在这个 MapReduce 作业中,我们已经在不同的 R 文件中定义了 Map 和 Reduce,并将它们提供给 Hadoop streaming 函数。

  • Mapper: stock_mapper.R

    #! /usr/bin/env/Rscript
    # To disable the warnings
    options(warn=-1)
    # To take input the data from streaming
    input <- file("stdin", "r")
    
    # To reading the each lines of documents till the end
    while(length(currentLine <-readLines(input, n=1, warn=FALSE)) > 0)
    {
    
    # To split the line by "," seperator
    fields <- unlist(strsplit(currentLine, ","))
    
    # Capturing open column value
     open <- as.double(fields[2])
    
    # Capturing close columns value
     close <- as.double(fields[5])
    
    # Calculating the difference of close and open attribute
     change <- (close-open)
    
    # emitting change as key and value as 1
    write(paste(change, 1, sep="\t"), stdout())
    }
    
    close(input)
    
    
  • Reducer: stock_reducer.R

    #! /usr/bin/env Rscript
    stock.key <- NA
    stock.val <- 0.0
    
    conn <- file("stdin", open="r")
    while (length(next.line <- readLines(conn, n=1)) > 0) {
     split.line <- strsplit(next.line, "\t")
     key <- split.line[[1]][1]
     val <- as.numeric(split.line[[1]][2])
     if (is.na(current.key)) {
     current.key <- key
     current.val <- val
     }
     else {
     if (current.key == key) {
    current.val <- current.val + val
    }
    else {
    write(paste(current.key, current.val, sep="\t"), stdout())
    current.key <- key
    current.val<- val
    }
    }
    }
    write(paste(current.key, current.val, sep="\t"), stdout())
    close(conn)
    
    

从以下代码中,我们可以在 R 中运行 MapReduce,而无需安装或使用任何 R 库/包。R 中有一个system()方法,可以在 R 控制台内触发系统命令,帮助我们在 R 中直接启动 Hadoop 作业。它还会将命令的响应提供到 R 控制台。

# For locating at Hadoop Directory
system("cd $HADOOP_HOME")

# For listing all HDFS first level directorysystem("bin/hadoop dfs -ls /")

# For running Hadoop MapReduce with streaming parameters
system(paste("bin/hadoop jar 
/usr/local/hadoop/contrib/streaming/hadoop-streaming-1.0.3.jar ",

" -input /stock/table.csv",
" -output /stock/outputs",
" -file /usr/local/hadoop/stock/stock_mapper.R",
" -mapper /usr/local/hadoop/stock/stock_mapper.R",
" -file /usr/local/hadoop/stock/stock_reducer.R",
" -reducer /usr/local/hadoop/stock/stock_reducer.R"))

# For storing the output of list command 
dir <- system("bin/hadoop dfs -ls /stock/outputs", intern=TRUE)
dir

# For storing the output from part-oooo (output file)
out <- system("bin/hadoop dfs -cat /stock/outputs/part-00000", intern=TRUE)

# displaying Hadoop MapReduce output data out

你也可以通过终端运行这个相同的程序:

bin/hadoop jar /usr/local/hadoop/contrib/streaming/hadoop-streaming-1.0.3.jar \

 -input /stock/table.csv \
 -output /stock/outputs\
 -file /usr/local/hadoop/stock/stock_mapper.R \
 -mapper /usr/local/hadoop/stock/stock_mapper.R \
 -file /usr/local/hadoop/stock/stock_reducer.R \
 -reducer /usr/local/hadoop/stock/stock_reducer.R 

在运行该程序时,R 控制台或终端的输出将如以下截图所示,通过此输出我们可以监控 Hadoop MapReduce 作业的状态。这里我们将按顺序查看这些输出的各个部分。请注意,我们已将日志输出分为几个部分,以帮助您更好地理解。

MapReduce 的日志输出包含(当从终端运行时):

数据可视化

如果我们通过各种图表在 R 中可视化我们的输出,我们可以获得更多的见解。在这里,我们通过ggplot2包尝试可视化输出。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_05_19.jpg

从前面的图表中,我们可以迅速识别出,大部分时间股票价格从 0 附近变动到 1.5。因此,股票历史上的价格波动在投资时会很有帮助。

生成此图所需的代码如下:

# Loading ggplot2 library
library(ggplot2);

# we have stored above terminal output to stock_output.txt file

#loading it to R workspace
myStockData <- read.delim("stock_output.txt", header=F, sep="", dec=".");

# plotting the data with ggplot2 geom_smooth function
ggplot(myStockData, aes(x=V1, y=V2)) + geom_smooth() + geom_point();

在下一部分,我们将介绍如何使用 R 和 Hadoop 进行大数据分析的案例研究,应用于Kaggle数据竞赛。

预测推土机蓝皮书销售价格——案例研究

这是一个案例研究,旨在预测重型设备拍卖销售价格,并为推土机创建蓝皮书。

识别问题

在这个例子中,我包括了 Cloudera 数据科学家的一项案例研究,讲述了如何对大数据集进行重采样,并在 R 和 Hadoop 中应用随机森林模型。在这里,我参考了 Kaggle 推土机蓝皮书竞赛来理解大数据问题定义的类型。该竞赛的目标是根据设备的使用情况、设备类型和配置,预测某一特定重型设备在使用拍卖中的销售价格。这个解决方案由Uri Laserson(Cloudera 的数据科学家)提供。提供的数据包含拍卖结果发布、使用情况和设备配置的信息。

这是一个技巧,用于对大数据集建模并将其划分为较小的数据集。将模型应用于该数据集是传统的机器学习技术,如随机森林或集成方法。随机森林可能有两个原因:

  • 大型数据集通常存储在集群中,因此任何操作都将具有一定程度的并行性。不同的模型在不同的节点上拟合,这些节点包含初始数据的不同子集。

  • 即使你可以使用整个初始数据集来拟合单个模型,事实证明,集成方法(通过使用数据子集来拟合多个较小的模型)通常优于单一模型。实际上,用 1 亿数据点拟合单个模型的效果可能比用每个包含 1000 万数据点的几个模型要差(即较小的总数据集优于较大的总数据集)。

有放回抽样是从初始数据集中采样以生成样本集合用于模型拟合的最常见方法。该方法等同于从多项分布中抽样,其中选择任何单个输入数据点的概率在整个数据集上是均匀的。

提示

Kaggle 是一个大数据平台,来自全球的数据科学家在这里竞赛,解决由数据驱动的组织主办的大数据分析问题。

设计数据需求

对于本次竞赛,Kaggle 提供了一个包含约 400,000 个训练数据点的真实世界数据集。每个数据点代表了推土机销售、配置以及销售价格的各种属性。为了预测销售价格,随机森林回归模型需要被实现。

注意

该 Kaggle 竞赛的参考链接为 www.kaggle.com/c/bluebook-for-bulldozers。你可以查看数据、信息、论坛和排行榜,还可以探索其他大数据分析竞赛并参与其中,以评估你的数据分析技能。

我们选择这个模型是因为我们有兴趣从一个大型数据集的随机集合中预测销售价格的数值。

数据集以以下数据文件的形式提供:

文件名描述格式(大小)
Train这是一个包含 2011 年数据的训练集。
Valid这是一个验证集,包含 2012 年 1 月 1 日至 2012 年 4 月 30 日的数据。
Data dictionary这是训练数据集变量的元数据。
Machine_Appendix这包含了给定机器的正确制造年份,以及品牌、型号和产品类别的详细信息。
Test这是测试数据集。
random_forest_benchmark_test这是主办方提供的基准解决方案。

提示

如果你想学习和实践大数据分析,可以通过参与 Kaggle 数据竞赛从 Kaggle 数据源获取大数据集。这些数据集来自世界各地不同行业的多个领域。

数据预处理

为了对提供的 Kaggle 数据集执行分析,我们需要构建一个预测模型。为了预测拍卖的销售价格,我们将在提供的数据集上拟合模型。但是数据集提供了多个文件。因此,我们将它们合并,并进行数据增强以获取更有意义的数据。我们将从Train.csvMachine_Appendix.csv构建模型,以更好地预测销售价格。

下面是需要在数据集上执行的数据预处理任务:

# Loading Train.csv dataset which includes the Sales as well as machine identifier data attributes.

transactions <- read.table(file="~/Downloads/Train.csv",
header=TRUE,
sep=",",
quote="\"",
row.names=1,
fill=TRUE,
colClasses=c(MachineID="factor",
 ModelID="factor",
datasource="factor",
YearMade="character",
SalesID="character",
auctioneerID="factor",
UsageBand="factor",
saledate="custom.date.2",
Tire_Size="tire.size",
Undercarriage_Pad_Width="undercarriage",
Stick_Length="stick.length"),
na.strings=na.values)

# Loading Machine_Appendix.csv for machine configuration information

machines <- read.table(file="~/Downloads/Machine_Appendix.csv",
header=TRUE,
sep=",",
quote="\"",
fill=TRUE,
colClasses=c(MachineID="character",
ModelID="factor",
fiManufacturerID="factor"),
na.strings=na.values)

# Updating the values to numeric 
# updating sale data number
transactions$saledatenumeric <- as.numeric(transactions$saledate)
transactions$ageAtSale <- as.numeric(transactions$saledate - as.Date(transactions$YearMade, format="%Y"))

transactions$saleYear <- as.numeric(format(transactions$saledate, "%Y"))

# updating the month of sale from transaction
transactions$saleMonth <- as.factor(format(transactions$saledate, "%B"))

# updating the date of sale from transaction
transactions$saleDay <- as.factor(format(transactions$saledate, "%d"))

# updating the day of week of sale from transaction
transactions$saleWeekday <- as.factor(format(transactions$saledate, "%A"))

# updating the year of sale from transaction
transactions$YearMade <- as.integer(transactions$YearMade)

# deriving the model price from transaction
transactions$MedianModelPrice <- unsplit(lapply(split(transactions$SalePrice, 
transactions$ModelID), median), transactions$ModelID)

# deriving the model count from transaction
transactions$ModelCount <- unsplit(lapply(split(transactions$SalePrice, transactions$ModelID), length), transactions$ModelID)

# Merging the transaction and machine data in to dataframe 
training.data <- merge(x=transactions, y=machines, by="MachineID")

# write denormalized data out
write.table(x=training.data,
file="~/temp/training.csv",
sep=",",
quote=TRUE,
row.names=FALSE,
eol="\n",
col.names=FALSE)
# Create poisson directory at HDFS
bin/hadoop dfs -mkdir /poisson

# Uploading file training.csv at HDFS
bin/hadoop dfs -put ~/temp/training.csv /poisson/

在数据上执行分析

由于我们将使用采样的数据集执行分析,我们需要了解需要对多少个数据集进行采样。

对于随机抽样,我们考虑了三个模型参数,如下所示:

  • 我们在初始训练集中有 N 个数据点。这非常大(106-109),分布在一个 HDFS 集群中。

  • 我们将为一个集成分类器训练一组 M 个不同的模型。

  • 每个 M 个模型将使用 K 个数据点进行拟合,其中通常 K << N。(例如,K 可能是 N 的 1-10%)。

我们有 N 个训练数据集,这些数据集是固定的,通常在我们的控制之外。由于我们将通过泊松抽样来处理这些数据,我们需要定义要输入随机森林模型的总输入向量数。

需要考虑三种情况:

  • KM < N:在这种情况下,我们没有使用我们可用的全部数据量。

  • KM = N:在这种情况下,我们可以完全分割我们的数据集,以生成完全独立的样本。

  • KM > N:在这种情况下,我们必须用替换的方式对部分数据进行重新抽样。

在下一节中描述的泊松抽样方法在相同的框架内处理所有三种情况。但是请注意,对于 KM = N 的情况,它不会对数据进行分区,而只是重新抽样。

理解泊松近似重采样

广义线性模型是一般线性模型的扩展。泊松回归是广义模型的一种情况。因变量服从泊松分布。

泊松抽样将在 MapReduce 任务的 Map 上运行,因为它发生在输入数据点上。这并不保证每个数据点都将被考虑到模型中,但它比全数据集的多项式重新抽样更好。但它将通过使用 N 个训练输入点保证生成独立样本。

在这里,下图显示了在泊松抽样中可以检索到的遗漏数据集的数量,其功能为 KM/N:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_05_17.jpg

灰线指示了 KM=N 的值。现在,让我们看看 MapReduce 算法的伪代码。我们使用了三个参数:N、M 和 K,其中 K 是固定的。我们使用 T=K/N 来消除先验值 N 的需求。

  • 采样参数的示例:在这里,我们将用伪代码实现前述逻辑。首先,我们将定义两个模型输入参数frac.per.modelnum.models,其中frac.per.model用于定义可以使用的完整数据集的比例,而num.models用于定义将从数据集中拟合的模型数量。

    T = 0.1  # param 1: K / N-average fraction of input data in each model 10%
    
    M = 50   # param 2: number of models
    
  • Mapper 的逻辑:Mapper 将被设计为通过数据整理生成完整数据集的样本。

    def map(k, v):
    // for each input data point
        for i in 1:M  
        // for each model
            m = Poisson(T)  
        // num times curr point should appear in this sample
            if m > 0
                for j in 1:m
       // emit current input point proper num of times
                    emit (i, v)
    
  • Reducer 的逻辑:Reducer 将接受一个数据样本作为输入,并对其进行随机森林模型的拟合。

    def reduce(k, v):
        fit model or calculate statistic with the sample in v
    
使用 RHadoop 拟合随机森林

在机器学习中,拟合模型意味着将最佳的线拟合到我们的数据中。拟合模型有几种类型,分别是欠拟合、过拟合和正常拟合。在欠拟合和过拟合的情况下,可能会出现较高的偏差(交叉验证和训练误差高)和较高的方差(交叉验证误差高但训练误差低)的影响,这是不理想的。我们通常会对数据集进行模型拟合。

下面是拟合模型的三种拟合类型的示意图:

我们将使用机器学习中的随机森林技术对数据进行拟合。这是一种递归划分方法,特别适用于大规模和小规模问题。它涉及一组(或集合)分类(或回归)树,这些树是通过在数据的随机子集上计算得出的,每个分类树的每次分割都使用一个随机选择和限制的预测变量子集。

此外,使用分类/回归树集成的结果已经被用于生成比使用单一分类树更好的预测。

我们将使用 RHadoop 实现我们的泊松采样策略。首先,我们会为参数设置全局值:

#10% of input data to each sample on avg
frac.per.model <- 0.1  
num.models <- 50

让我们检查如何按照伪代码的规范,使用 RHadoop 实现 Mapper。

  • Mapper 的实现方式如下:

    poisson.subsample <- function(k, input) {
      # this function is used to generate a sample from the current block of data
      generate.sample <- function(i) {
        # generate N Poisson variables
        draws <- rpois(n=nrow(input), lambda=frac.per.model)
        # compute the index vector for the corresponding rows,
        # weighted by the number of Poisson draws
        indices <- rep((1:nrow(input)), draws)
        # emit the rows; RHadoop takes care of replicating the key appropriately
        # and rbinding the data frames from different mappers together for the
        # reducer
        keyval(i, input[indices, ])
      }
    
      # here is where we generate the actual sampled data
      c.keyval(lapply(1:num.models, generate.sample))
    }
    

    由于我们使用的是 R,因此在收集的样本数据集上使用随机森林模型拟合模型是一个复杂的过程。

  • Reducer 的实现方式如下:

    # REDUCE function
    fit.trees <- function(k, v) {
      # rmr rbinds the emitted values, so v is a dataframe
      # note that do.trace=T is used to produce output to stderr to keep the reduce task from timing out
      rf <- randomForest(formula=model.formula,
                            data=v,
                            na.action=na.roughfix,
                            ntree=10,
                            do.trace=FALSE)
    
     # rf is a list so wrap it in another list to ensure that only
     # one object gets emitted. this is because keyval is vectorized
      keyval(k, list(forest=rf))
    }
    
  • 为了拟合模型,我们需要model.formula,其内容如下:

    model.formula <- SalePrice ~ datasource + auctioneerID + YearMade + saledatenumeric + ProductSize + ProductGroupDesc.x + Enclosure + Hydraulics + ageAtSale + saleYear + saleMonth + saleDay + saleWeekday + MedianModelPrice + ModelCount + MfgYear
    
    

    SalePrice定义为响应变量,其他变量定义为随机森林模型的预测变量。

    提示

    R 中的随机森林模型不支持具有超过 32 个级别的因子变量。

  • MapReduce 作业可以通过以下命令执行:

    mapreduce(input="/poisson/training.csv",
     input.format=bulldozer.input.format,
     map=poisson.subsample,
     reduce=fit.trees,
     output="/poisson/output")
    
    

    生成的树被导出到 HDFS 的/poisson/output路径下。

  • 最后,我们可以加载这些树,合并它们,并用它们来分类新的测试点:

    mraw.forests <- values(from.dfs("/poisson/output"))
    forest <- do.call(combine, raw.forests)
    
    

每个 50 个样本都生成了一个包含 10 棵树的随机森林,因此最终的随机森林是由 500 棵树组成的,并且以分布式的方式在 Hadoop 集群上进行拟合。

注意

所有源文件的完整集合可以在 Cloudera 官方网站的博客中找到,链接:blog.cloudera.com/blog/2013/02/how-to-resample-from-a-large-data-set-in-parallel-with-r-on-hadoop/

希望我们已经学习到了一种可扩展的方法,通过使用泊松近似来进行多项式采样,从而以并行方式训练集成分类器或进行自助法(bootstrapping)。

总结

在本章中,我们学习了如何在 R 和 Hadoop 集成环境中,利用各种数据驱动活动进行大数据分析。

在下一章中,我们将学习更多关于如何使用 R 和 Hadoop 来执行机器学习技术的内容。

第六章:使用机器学习理解大数据分析

在本章中,我们将学习不同的机器学习技术,这些技术可以与 R 和 Hadoop 一起使用,以通过以下要点执行大数据分析:

  • 机器学习简介

  • 机器学习算法类型

  • 监督式机器学习算法

  • 无监督机器学习算法

  • 推荐算法

机器学习简介

机器学习是人工智能的一个分支,它使我们能够在没有显式编程的情况下,使应用程序具备智能。机器学习的概念被用于使应用程序能够从现有数据集中做出决策。机器学习与数据挖掘的结合可以用于开发垃圾邮件检测器、自动驾驶汽车、语音识别、面部识别和在线交易欺诈活动检测等。

有许多知名的组织正在使用机器学习算法,使他们的服务或产品能够理解用户的需求,并根据用户的行为提供服务。谷歌拥有其智能的网页搜索引擎,提供了第一大搜索引擎、Google Mail 中的垃圾邮件分类、Google News 中的新闻标签分类,以及亚马逊的推荐系统。许多开源框架可用于开发这些类型的应用程序/框架,如 R、Python、Apache Mahout 和 Weka。

机器学习算法类型

目前有三种不同类型的机器学习算法,用于智能系统开发:

  • 监督式机器学习算法

  • 无监督机器学习算法

  • 推荐系统

在本章中,我们将讨论一些著名的商业问题,包括分类、回归和聚类,以及如何在 Hadoop 上执行这些机器学习技术,以克服内存问题。

如果你加载的某个数据集无法适应机器的内存,并且你尝试运行它,预测分析将抛出与机器内存相关的错误,例如错误:无法分配大小为 990.1 MB 的向量。解决方案是增加机器配置或使用商品硬件进行并行化。

监督式机器学习算法

在本节中,我们将学习监督式机器学习算法。算法如下:

  • 线性回归

  • 逻辑回归

线性回归

线性回归主要用于基于历史信息预测和预报值。回归是一个监督式机器学习技术,用于识别目标变量和解释变量之间的线性关系。我们可以说,它用于预测目标变量的数值。

在接下来的章节中,我们将学习如何使用 R 和 Hadoop 进行线性回归。

这里,目标变量是需要预测的变量,帮助预测目标变量的变量称为解释变量。通过线性关系,我们可以识别解释变量变化对目标变量的影响。

在数学中,回归可以如下表示:

y = ax + e

其他公式包括:

  • 回归线的斜率由以下公式给出:

    a = (NΣxy - (Σx)(Σy)) / (NΣx² - (Σx)²)

  • 回归的截距点由以下公式给出:

    e = (Σy - b(Σx)) / N

这里,xy 是构成数据集的变量,N 是值的总数。

假设我们有以下表格中的数据:

xy
633.1
643.6
653.8
664

如果我们有一个新的 x 值,我们可以通过回归公式获得对应的 y 值。

线性回归的应用包括:

  • 销售预测

  • 预测最佳产品价格

  • 从各种来源和活动中预测下一次在线购买

让我们看看如何使用统计技术来实现提供的数据集的回归模型。假设我们已获得 n 个统计数据单元。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_06_01.jpg

它的公式如下:

Y = e[0] + a[0]x[0] + a[1]x[1] + a[2]x[2] + a[3]x[3] + a[4]x[4]

这里,Y 是目标变量(响应变量),xi 是解释变量,e[0] 是误差项的平方和,可以视为噪声。为了获得更准确的预测,我们需要尽早通过 call 函数减少这个误差项。

使用 R 进行线性回归

现在我们将看看如何在 R 中执行线性回归。我们可以使用内置的 lm() 方法来构建一个线性回归模型。

Model <-lm(target ~ ex_var1, data=train_dataset)

它将基于提供的数据集的属性构建回归模型,并存储所有用于预测和识别数据模式的变量系数和模型参数。

# Defining data variables
X = matrix(rnorm(2000), ncol = 10)
y = as.matrix(rnorm(200))

# Bundling data variables into dataframe
train_data <- data.frame(X,y)

# Training model for generating prediction
lmodel<- lm(y~ train_data $X1 + train_data $X2 + train_data $X3 + train_data $X4 + train_data $X5 + train_data $X6 + train_data $X7 + train_data $X8 + train_data $X9 + train_data $X10,data= train_data)

summary(lmodel)

以下是使用前述 summary 命令可以显示的各种模型参数:

  • RSS:这等于 ∑(y 实际 - y)²。

  • 自由度DOF):用于识别预测模型的拟合度,应该尽可能小(从逻辑上讲,值为 0 表示完美预测)。

  • 残差标准误差RSS/DF):用于识别预测模型的拟合度,应该尽可能小(从逻辑上讲,值为 0 表示完美预测)。

  • pr:这是变量被纳入模型的概率;要将一个变量纳入模型,其值应小于 0.05。

  • t 值:这等于 15。

  • f:这是检查 R 方是否为非零值的统计量。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_06_03.jpg

使用 R 和 Hadoop 进行线性回归

假设我们有一个大型数据集。现在我们如何进行回归数据分析?在这种情况下,我们可以使用 R 和 Hadoop 集成,通过实现 Mapper 和 Reducer 来执行并行线性回归。它将把数据集分配到各个节点之间,然后这些节点将并行处理分布式数据。当我们在 R 和 Hadoop 集群中运行时,它不会引发内存问题,因为大型数据集将被分布式并与 Hadoop 计算节点中的 R 一起处理。同时,请记住,这种实现方法的预测精度不比 lm() 模型高。

RHadoop 用于集成 R 和 Hadoop,它是 Revolution Analytics 的一个受信的开源发行版。如需了解有关 RHadoop 的更多信息,请访问 github.com/RevolutionAnalytics/RHadoop/wiki。在 RHadoop 的软件包中,这里我们只使用 rmrrhdfs 库。

让我们看看如何使用 R 和 Hadoop 数据技术进行回归分析。

# Defining the datasets with Big Data matrix X
X = matrix(rnorm(20000), ncol = 10)
X.index = to.dfs(cbind(1:nrow(X), X))
y = as.matrix(rnorm(2000))

在这里,Sum() 函数是可重用的,如以下代码所示:

# Function defined to be used as reducers 
Sum = 
  function(., YY) 
    keyval(1, list(Reduce('+', YY)))

线性回归算法的大纲如下:

  1. 使用 MapReduce 作业 1 计算 Xtx 值。

  2. 使用 MapReduce 作业 2 计算 Xty 值。

  3. 使用 Solve (Xtx, Xty) 推导系数值。

让我们逐一理解这些步骤。

第一步是使用 MapReduce 作业 1 计算 Xtx 值。

  1. 大矩阵以完整行的块传递给 Mapper。这些子矩阵的较小交叉乘积会被计算并传递给单个 Reducer,后者将它们加总在一起。由于我们有一个单一的键,Combiner 是必须的,而且由于矩阵求和具有结合性和交换性,我们当然可以在这里使用它。

    # XtX = 
      values(
    
    # For loading hdfs data in to R 
        from.dfs(
    
    # MapReduce Job to produce XT*X
          mapreduce(
            input = X.index,
    
    # Mapper – To calculate and emitting XT*X
            map = 
              function(., Xi) {
                yi = y[Xi[,1],]
                Xi = Xi[,-1]
                keyval(1, list(t(Xi) %*% Xi))},
    
    # Reducer – To reduce the Mapper output by performing sum operation over them
            reduce = Sum,
            combine = TRUE)))[[1]]
    
  2. 当我们有大量数据存储在 Hadoop 分布式文件系统 (HDFS) 中时,我们需要将其路径值传递给 MapReduce 方法的输入参数。

  3. 在前面的代码中,我们看到 X 是设计矩阵,它是通过以下函数创建的:

    X = matrix(rnorm(2000), ncol = 10)
    
  4. 它的输出将如下所示:https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_06_10.jpg

所以,这里所有列将被视为解释变量,并且它们的标准误差可以按照与正常线性回归中计算标准误差的相同方式来计算。

计算 Xty 值与 MapReduce 作业 2 基本相同,向量 y 会根据正常作用域规则在各节点中可用。

Xty = values(

# For loading hdfs data
from.dfs(

# MapReduce job to produce XT * y
      mapreduce(
       input = X.index,

# Mapper – To calculate and emitting XT*y
        map = function(., Xi) {
          yi = y[Xi[,1],]
          Xi = Xi[,-1]
          keyval(1, list(t(Xi) %*% yi))},

# Reducer – To reducer the Mapper output by performing # sum operation over them
        reduce = Sum,
        combine = TRUE)))[[1]]

要推导系数值,使用 solve (Xtx, Xty),请按照以下步骤操作:

  1. 最后,我们只需要调用以下代码行来获取系数值。

    solve(XtX, Xty)
    
  2. 前面的命令的输出将如下所示:https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_06_02.jpg

逻辑回归

在统计学中,逻辑回归或 logit 回归是一种概率分类模型。逻辑回归在许多学科中广泛应用,包括医学和社会科学领域。它可以是二项式或多项式。

二元逻辑回归处理因变量结果可能有两种可能类型的情况。多项式逻辑回归处理结果可能有三种或更多类型的情况。

逻辑回归可以使用逻辑函数实现,这里列出了它们。

  • 要预测对数几率比,请使用以下公式:

    logit§ = β0 + β1 × x1 + β2 × x2 + … + βn × xn

  • 概率公式如下:

    p = e^(logit§) ⁄ 1 + e^(logit§)

logit(p)是解释变量 X(x1,x2,x3…xn)的线性函数,类似于线性回归。因此,该函数的输出将在 0 到 1 的范围内。根据概率分数,我们可以将其概率范围设置为 0 到 1。在大多数情况下,如果分数大于 0.5,则视为 1,否则为 0。此外,我们可以说它为分类结果提供了分类边界。

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_06_04.jpg

上述图是一个训练数据集。基于训练数据集的绘图,我们可以说glm模型在 R 中生成了一个分类边界。

逻辑回归的应用包括:

  • 预测在线购买的可能性

  • 检测糖尿病的存在

使用 R 进行逻辑回归

要使用 R 执行逻辑回归,我们将使用iris数据集和glm模型。

#loading iris dataset
data(iris)

# Setting up target variable
target <- data.frame(isSetosa=(iris$Species == 'setosa'))

# Adding target to iris and creating new dataset
inputdata <- cbind(target,iris)

# Defining the logistic regression formula
formula <- isSetosa ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width

# running Logistic model via glm()
logisticModel <- glm(formula, data=inputdata, family="binomial")

使用 R 和 Hadoop 进行逻辑回归

要使用 R 和 Hadoop 执行逻辑回归,我们将使用rmr2和 RHadoop。

逻辑回归算法的大纲如下:

  • 定义lr.map映射函数

  • 定义lr.reducer减少函数

  • 定义logistic.regression MapReduce 函数

让我们逐一理解它们。

我们将首先定义梯度下降的逻辑回归函数。可以通过将非依赖变量形成矩阵数据格式来执行多变量回归。对于因子变量,我们可以将它们转换为二元变量以适应模型。此函数将要求inputiterationsdimsalpha作为输入参数。

  • lr.map:这代表逻辑回归映射器,将计算子集点对梯度的贡献。

    # Mapper – computes the contribution of a subset of points to the gradient.
    
    lr.map = 
        function(., M) {
          Y = M[,1] 
          X = M[,-1]
          keyval(
            1,
            Y * X * 
              g(-Y * as.numeric(X %*% t(plane))))}
    
  • lr.reducer:这代表逻辑回归减少器,仅执行键 1 所有值的总和。

    # Reducer – Perform sum operation over Mapper output.
    
    lr.reduce =
        function(k, Z) 
          keyval(k, t(as.matrix(apply(Z,2,sum))))
    
  • logistic.regression:这将主要定义logistic.regression MapReduce 函数,并带有以下输入参数。调用此函数将开始执行 MapReduce 函数的逻辑回归。

    • input: 这是一个输入数据集。

    • iterations: 这是计算梯度的固定迭代次数。

    • dims:这是输入变量的维度

    • alpha:这是学习率

让我们看看如何开发逻辑回归函数。

# MapReduce job – Defining MapReduce function for executing logistic regression

logistic.regression = 
  function(input, iterations, dims, alpha){
  plane = t(rep(0, dims))
  g = function(z) 1/(1 + exp(-z))
  for (i in 1:iterations) {
    gradient = 
      values(
        from.dfs(
          mapreduce(
            input,
            map = lr.map,
            reduce = lr.reduce,
            combine = T)))
    plane = plane + alpha * gradient }
  plane }

让我们按如下方式运行这个逻辑回归函数:

# Loading dataset
data(foodstamp)

# Storing data to hdfs 
testdata <-  to.dfs(as.matrix(foodstamp))

# Running logistic regression with R and Hadoop
print(logistic.regression(testdata,10,3,0.05))

前述命令的输出结果如下:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_06_09.jpg

无监督机器学习算法

在机器学习中,无监督学习用于从未标记的数据集中发现隐藏的结构。由于数据集是未标记的,因此在评估潜在解决方案时不会出现错误。

无监督机器学习包括几种算法,以下是其中的一些:

  • 聚类

  • 人工神经网络

  • 向量量化

我们将在这里考虑流行的聚类算法。

聚类

聚类是将一组对象分组的任务,使得具有相似特征的对象被分到同一类别,而其他对象则分到不同类别。在聚类中,输入数据集是未标记的;它们需要根据数据结构的相似性进行标记。

在无监督机器学习中,分类技术执行相同的程序,通过提供的输入训练数据集将数据映射到一个类别。这个相应的过程称为聚类(或聚类分析),它通过某种固有相似性的度量将数据分组到不同的类别中;例如,数据点之间的距离。

从下图中,我们可以识别出聚类是基于相似性将对象分组:

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_06_05.jpg

R 库中有几种聚类技术,如 k-means、k-medoids、层次聚类和基于密度的聚类。在这些技术中,k-means 是数据科学中广泛使用的聚类算法。该算法要求用户提供聚类的数量作为输入参数。

聚类的应用如下:

  • 市场细分

  • 社交网络分析

  • 组织计算机网络

  • 天文数据分析

使用 R 进行聚类

我们在这里考虑k-means方法来实现聚类模型,基于iris输入数据集,只需调用其内置的 R 数据集——iris数据(欲了解更多信息,请访问stat.ethz.ch/R-manual/R-devel/library/datasets/html/iris.html)。在这里我们将看到如何使用 R 执行 k-means 聚类。

# Loading iris flower dataset
data("iris")
# generating clusters for iris dataset
kmeans <- kmeans(iris[, -5], 3, iter.max = 1000)

# comparing iris Species with generated cluster points
Comp <- table(iris[, 5], kmeans$cluster)

对于小型数据集,推导聚类是相当简单的,但对于大型数据集,推导聚类需要使用 Hadoop 来提供计算能力。

使用 R 和 Hadoop 进行聚类

由于 k-means 聚类算法已经在 RHadoop 中开发完成,我们将使用并理解它。您可以根据输入数据集格式修改它们的 Mappers 和 Reducers。由于我们正在处理 Hadoop,因此需要开发 Mappers 和 Reducers,以便在节点上并行运行。

聚类算法的概述如下:

  • 定义dist.fun距离函数

  • 定义k-means.map k-means Mapper 函数

  • 定义k-means.reduce k-means Reducer 函数

  • 定义k-means.mr k-means MapReduce 函数

  • 定义要提供给聚类算法的输入数据点

现在我们将通过提供所需的参数运行k-means.mr(k-means MapReduce 作业)。

让我们逐一理解它们。

  • dist.fun:首先,我们将查看dist.fun函数,该函数用于计算中心矩阵C与点矩阵P之间的距离。它经过测试后,能够在大约 16 秒内生成 10⁶个点和 10²个中心(5 维)。

    # distance calculation function
    dist.fun = 
          function(C, P) {
            apply(
              C,
              1, 
              function(x) 
                colSums((t(P) - x)²))}
    
  • k-means.map:k-means MapReduce 算法的 Mapper 将计算点与所有中心之间的距离,并返回每个点的最近中心。这个 Mapper 将根据以下代码进行迭代运行。在第一次迭代中,聚类中心将被随机分配,从下一次迭代开始,它将根据与聚类中所有点的最小距离计算这些聚类中心。

    # k-Means Mapper
      kmeans.map = 
          function(., P) {
            nearest = {
    
    # First interations- Assign random cluster centers 
              if(is.null(C)) 
                sample(
                  1:num.clusters, 
                  nrow(P), 
                  replace = T)
    
    # Rest of the iterations, where the clusters are assigned # based on the minimum distance from points
              else {
                D = dist.fun(C, P)
                nearest = max.col(-D)}}
    
           if(!(combine || in.memory.combine))
              keyval(nearest, P) 
            else 
              keyval(nearest, cbind(1, P))}
    
  • k-means.reduce:k-means MapReduce 算法的 Reducer 将计算矩阵点的列平均值作为键。

    # k-Means Reducer
    kmeans.reduce = {
    
    # calculating the column average for both of the 
    # conditions
    
          if (!(combine || in.memory.combine) ) 
            function(., P) 
              t(as.matrix(apply(P, 2, mean)))
          else 
            function(k, P) 
              keyval(
                k, 
                t(as.matrix(apply(P, 2, sum))))}
    
  • kmeans.mr:定义 k-means MapReduce 函数涉及指定几个输入参数,具体如下:

    • P:表示输入数据点。

    • num.clusters:这是总的聚类数量。

    • num.iter:这是处理数据集的总迭代次数。

    • combine:这将决定是否启用 Combiner(TRUEFALSE)。

      # k-Means MapReduce – for 
      kmeans.mr = 
        function(
          P, 
          num.clusters, 
          num.iter, 
          combine, 
          in.memory.combine) {
          C = NULL
          for(i in 1:num.iter ) {
            C = 
              values(
      
      # Loading hdfs dataset
                from.dfs(
      
      # MapReduce job, with specification of input dataset,
      # Mapper and Reducer
                  mapreduce(
                    P,
                    map = kmeans.map,
                    reduce = kmeans.reduce)))
            if(combine || in.memory.combine)
              C = C[, -1]/C[, 1]
            if(nrow(C) < num.clusters) {
              C = 
                rbind(
                  C,
                  matrix(
                    rnorm(
                      (num.clusters - 
                         nrow(C)) * nrow(C)), 
                    ncol = nrow(C)) %*% C) }}
              C}
      
  • 定义要提供给聚类算法的输入数据点:

    # Input data points
    P = do.call(
          rbind, 
          rep(
    
            list(
    
    # Generating Matrix of
              matrix(
    # Generate random normalized data with sd = 10
                rnorm(10, sd = 10), 
                ncol=2)), 
            20)) + 
        matrix(rnorm(200), ncol =2)
    
  • 通过提供所需参数运行kmeans.mr(k-means MapReduce 作业)。

    # Running kmeans.mr Hadoop MapReduce algorithms with providing the required input parameters
    
    kmeans.mr(
          to.dfs(P),
          num.clusters = 12, 
          num.iter = 5,
          combine = FALSE,
          in.memory.combine = FALSE)
    
  • 上述命令的输出显示在以下截图中:https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_06_06.jpg

推荐算法

推荐是机器学习技术,用于预测用户可能喜欢的新项目,基于用户与之前项目的关联。推荐广泛应用于电子商务领域。通过这种灵活的数据和行为驱动算法,企业可以通过确保在正确的时间向正确的客户自动推荐相关选择,从而增加转化率,实现交叉销售或追加销售。

例如,当一个客户在亚马逊上寻找三星 Galaxy S IV/S4 手机时,商店还会建议其他类似的手机,这些手机会出现在购买此商品的客户还购买了窗口中。

有两种不同类型的推荐:

例如,一个名为 Vaibhav 的用户喜欢并使用以下几本书:

  • 《Apache Mahout 秘籍》Piero GiacomelliPackt Publishing

  • 《Hadoop MapReduce 秘籍》Thilina GunarathneSrinath PereraPackt Publishing

  • 《Hadoop 真实世界解决方案秘籍》Brian FemianoJon LentzJonathan R. OwensPackt Publishing

  • 《大数据入门》Dr. Fern HalperJudith HurwitzMarcia KaufmanAlan NugentJohn Wiley & Sons Publishers

基于上述信息,推荐系统将预测 Vaibhav 会喜欢阅读哪些新书,如下所示:

  • 《大数据分析与 R 与 Hadoop》Vignesh PrajapatiPackt Publishing

现在我们将了解如何使用 R 和 Hadoop 生成推荐。但是,在讲解 R 和 Hadoop 的结合之前,首先让我们看看如何用 R 来生成推荐。这将帮助你理解如何将生成的推荐系统转换为 MapReduce 推荐算法。在使用 R 和 Hadoop 生成推荐时,我们将使用Revolution Analytics的 RHadoop 分发版。

在 R 中生成推荐的步骤

为了生成用户推荐,我们需要具有特定格式的数据集,算法可以读取这些数据。在这里,我们将使用协同过滤算法来生成推荐,而不是基于内容的算法。因此,我们需要用户对可用项目集的评分信息。因此,small.csv数据集采用user ID, item ID, item's ratings格式。

# user ID, item ID, item's rating
1,         101,     5.0
1,         102,     3.0
1,         103,     2.5
2,         101,     2.0
2,         102,     2.5
2,         103,     5.0
2,         104,     2.0
3,         101,     2.0
3,         104,     4.0
3,         105,     4.5
3,         107,     5.0
4,         101,     5.0
4,         103,     3.0
4,         104,     4.5
4,         106,     4.0
5,         101,     4.0
5,         102,     3.0
5,         103,     2.0
5,         104,     4.0
5,         105,     3.5
5,         106,     4.0

上述代码和数据集摘自《Mahout in Action》一书,作者为Robin AnilEllen FriedmanTed DunningSean Owen,由 Manning Publications 出版,网址为www.fens.me/

推荐可以通过矩阵分解技术推导出来,如下所示:

Co-occurrence matrix * scoring matrix = Recommended Results

为了生成推荐系统,我们将遵循以下步骤:

  1. 计算共现矩阵。

  2. 建立用户评分矩阵。

  3. 生成推荐。

从下一部分开始,我们将看到执行前述步骤的技术细节。

  1. 在第一部分中,计算共现矩阵时,我们能够识别数据集中给定的共现物品集。简单来说,我们可以称之为从给定数据集中计数物品对。

    # Quote plyr package
    library (plyr)
    
    # Read dataset
    train <-read.csv (file = "small.csv", header = FALSE)
    names (train) <-c ("user", "item", "pref") 
    
    # Calculated User Lists
    usersUnique <-function () {
      users <-unique (train $ user)
      users [order (users)]
    }
    
    # Calculation Method Product List
    itemsUnique <-function () {
      items <-unique (train $ item)
      items [order (items)]
    }
    
    # Derive unique User Lists
    users <-usersUnique () 
    
    # Product List
    items <-itemsUnique () 
    
    # Establish Product List Index
    index <-function (x) which (items %in% x)
    data<-ddply(train,.(user,item,pref),summarize,idx=index(item)) 
    
    # Co-occurrence matrix
    Co-occurrence <-function (data) {
      n <-length (items)
      co <-matrix (rep (0, n * n), nrow = n)
      for (u in users) {
        idx <-index (data $ item [which(data$user == u)])
        m <-merge (idx, idx)
        for (i in 1: nrow (m)) {
          co [m$x[i], m$y[i]] = co[m$x[i], m$y[i]]+1
        }
      }
      return (co)
    }
    
    # Generate co-occurrence matrix
    co <-co-occurrence (data) 
    
  2. 为了基于用户评分信息建立用户评分矩阵,可以为用户生成用户-物品评分矩阵。

    # Recommendation algorithm
    recommend <-function (udata = udata, co = coMatrix, num = 0) {
      n <- length(items)
    
      # All of pref
      pref <- rep (0, n)
      pref[udata$idx] <-udata$pref
    
      # User Rating Matrix
      userx <- matrix(pref, nrow = n)
    
      # Scoring matrix co-occurrence matrix *
      r <- co %*% userx
    
      # Recommended Sort
      r[udata$idx] <-0
      idx <-order(r, decreasing = TRUE)
      topn <-data.frame (user = rep(udata$user[1], length(idx)), item = items[idx], val = r[idx])
    
      # Recommended results take months before the num
      if (num> 0) {
        topn <-head (topn, num)
      }
    
      # Recommended results take months before the num
      if (num> 0) {
        topn <-head (topn, num)
      }
    
      # Back to results 
      return (topn)
    }
    
  3. 最终,可以通过两个矩阵项的产品操作生成输出推荐:共现矩阵和用户评分矩阵。

    # initializing dataframe for recommendations storage
    recommendation<-data.frame()
    
    # Generating recommendations for all of the users
    for(i in 1:length(users)){
      udata<-data[which(data$user==users[i]),]
      recommendation<-rbind(recommendation,recommend(udata,co,0)) 
    }
    

提示

通过Myrrix和 R 接口生成推荐非常简单。更多信息,请参考github.com/jwijffels/Myrrix-R-interface

使用 R 和 Hadoop 生成推荐

为了使用 R 和 Hadoop 生成推荐,我们需要开发一个能够并行执行和处理数据的算法。这可以通过使用 Mappers 和 Reducers 来实现。该部分的一个非常有趣的部分是我们如何将 R 和 Hadoop 结合使用,从大数据集生成推荐。

所以,以下步骤类似于使用 R 生成推荐,但将其转换为 Mapper 和 Reducer 范式有些复杂:

  1. 建立共现矩阵项。

  2. 将用户评分矩阵建立到文章中。

  3. 生成推荐。

我们将使用与之前在 R 中生成推荐相同的概念来结合 R 和 Hadoop 生成推荐。但在这种情况下,我们需要使用键值对范式,因为它是并行操作的基础。因此,每个函数都将通过考虑键值对范式来实现。

  1. 在第一部分中,建立共现矩阵项时,我们将按照步骤建立共现项:按用户分组,定位每个用户选择的单独出现物品计数,以及配对计数。

    # Load rmr2 package
    library (rmr2)
    
    # Input Data File
    train <-read.csv (file = "small.csv", header = FALSE)
    names (train) <-c ("user", "item", "pref")
    
    # Use the hadoop rmr format, hadoop is the default setting.
    rmr.options (backend = 'hadoop')
    
    # The data set into HDFS
    train.hdfs = to.dfs (keyval (train$user, train))
    
    # see the data from hdfs
    from.dfs (train.hdfs)
    

    需要注意的要点是:

    • train.mr:这是 MapReduce 任务的键值对范式信息

    • key:这是物品列表向量

    • value:这是物品组合向量

    # MapReduce job 1 for co-occurrence matrix items
    train.mr <-mapreduce (
      train.hdfs, 
      map = function (k, v) {
        keyval (k, v$item)
      }
    
    # for identification of co-occurrence items
      , Reduce = function (k, v) {
        m <-merge (v, v)
        keyval (m$x, m$y)
      }
    )
    

    共现矩阵项将被组合以进行计数。

    为了定义一个 MapReduce 任务,使用step2.mr来计算物品组合的频率。

    • Step2.mr:这是 MapReduce 任务的键值对范式信息

    • key:这是物品列表向量

    • value:这是共现矩阵数据框的值(itemitemFreq

    # MapReduce function for calculating the frequency of the combinations of the items.
    step2.mr <-mapreduce (
      train.mr,
    
      map = function (k, v) {
        d <-data.frame (k, v)
        d2 <-ddply (d,. (k, v), count)
    
        key <- d2$k
        val <- d2
        keyval(key, val)
      }
    )
    
    # loading data from HDFS
    from.dfs(step2.mr)
    
  2. 为了将用户评分矩阵建立到文章中,让我们定义Train2.mr MapReduce 任务。

    # MapReduce job for establish user scoring matrix to articles
    
    train2.mr <-mapreduce (
      train.hdfs, 
      map = function(k, v) {
          df <- v
    
    # key as item
        key <-df $ item
    
    # value as [item, user pref]
        val <-data.frame (item = df$item, user = df$user, pref = df$pref)
    
    # emitting (key, value)pairs
        keyval(key, val)
      }
    )
    
    # loading data from HDFS
    from.dfs(train2.mr)
    
    • Train2.mr:这是 MapReduce 任务的键值对范式信息

    • key:这是物品列表

    • value:这是用户商品评分矩阵的值

    以下是合并和共现评分矩阵:

    # Running equi joining two data – step2.mr and train2.mr
    eq.hdfs <-equijoin (
      left.input = step2.mr, 
      right.input = train2.mr,
      map.left = function (k, v) {
        keyval (k, v)
      },
      map.right = function (k, v) {
        keyval (k, v)
      },
      outer = c ("left")
    )
    
    # loading data from HDFS
    from.dfs (eq.hdfs)
    
    • eq.hdfs:这是 MapReduce 任务的键值对范式信息

    • key:这里的键是空的

    • value:这是合并的数据框值

  3. 在生成推荐的部分,我们将获取推荐结果的列表。

    # MapReduce job to obtain recommended list of result from equijoined data
    cal.mr <-mapreduce (
      input = eq.hdfs,
    
      map = function (k, v) {
        val <-v
        na <-is.na (v$user.r)
        if (length (which(na))> 0) val <-v [-which (is.na (v $ user.r)),]
        keyval (val$kl, val)
      }
      , Reduce = function (k, v) {
        val <-ddply (v,. (kl, vl, user.r), summarize, v = freq.l * pref.r)
        keyval (val $ kl, val)
      }
    )
    
    # loading data from HDFS
    from.dfs (cal.mr)
    
    • Cal.mr: 这是 MapReduce 作业的键值范式信息

    • key: 这是项目列表

    • value: 这是推荐结果数据框的值

    通过定义用于获取带有优先级值的推荐项目列表的结果,将对推荐结果进行排序处理。

    # MapReduce job for sorting the recommendation output
    result.mr <-mapreduce (
      input = cal.mr,
      map = function (k, v) {
        keyval (v $ user.r, v)
      }
      , Reduce = function (k, v) {
        val <-ddply (v,. (user.r, vl), summarize, v = sum (v))
        val2 <-val [order (val$v, decreasing = TRUE),]
        names (val2) <-c ("user", "item", "pref")
        keyval (val2$user, val2)
      }
    )
    # loading data from HDFS
    from.dfs (result.mr)
    
    • result.mr: 这是 MapReduce 作业的键值范式信息

    • key: 这是用户 ID

    • value: 这是推荐结果数据框的值

在这里,我们设计了用于生成基于项目推荐的协同算法。由于我们尝试使其在并行节点上运行,我们重点关注了 Mapper 和 Reducer。它们在某些情况下可能不是最优的,但你可以通过使用现有代码使其变得最优。

总结

在这一章中,我们学习了如何借助 R 和 Hadoop 技术利用机器学习进行大数据分析。在下一章,我们将学习如何通过将 R 与各种外部数据源集成来丰富数据集。

第七章 从各种数据库导入和导出数据

在本章的最后,我们将看到如何将来自不同来源的数据加载到 R 中,以执行数据分析操作。在这里,我们考虑了一些流行的数据库,它们被用作数据存储,支持不同应用和技术下的分析操作。如我们所知,使用 R 执行分析操作相较于其他分析工具非常简单,而且 R 是免费的、开源的。由于 R 可以通过安装 R 包使用自定义函数,CRAN 上有许多数据库包可供与 R 连接使用。因此,R 编程语言因其数据库独立性以及操作系统独立性,越来越受欢迎。

我们特别设计了本章,旨在分享如何将来自不同数据库系统的数据加载到 R 中进行数据建模。我们在本章中包括了多个流行的数据库示例,用于执行各种数据库操作。

我们已经覆盖了与 R 一起使用的各种流行数据源。它们如下:

  • RData

  • MySQL

  • Excel

  • MongoDB

  • SQLite

  • PostgreSQL

  • Hive

  • HBase

https://github.com/OpenDocCN/freelearn-ds-pt5-zh/raw/master/docs/bgdt-anal-r-hdp/img/3282OS_07_01.jpg

从上面的图表中,我们可以理解到,R 支持多种数据库系统,可以在不同的数据库上执行与数据分析相关的操作。由于 R 有大量的库可以连接各种数据库,我们只需要继承它们即可。

在下面的表格中,列出了常见的数据库系统及其相关的 R 包,以便更容易理解相关的 R 包:

数据库系统名称有用的 R 包 / 函数工具
文本文件文本数据文件,如.csv.txt.r
MySQLRMySQL
ExcelXlsx
MongoRMongo
SQLliteRSQLlite
PostgreSQLRPostgreSQL
HDFSRHDFS
HiveRHive
HBaseRHBase

正如我们所知,提到的每个数据库都有其独特的重要性和功能。为了更好地理解,每个数据源都将通过以下几点进行描述:

  • 介绍

  • 特性

  • 安装

  • 将数据导入到 R 中

  • 数据操作

  • 从 R 导出数据

在本章中,我们将安装并使用 R 包,这些包将用于 R 中的各种数据操作。

现在,我们将开始了解数据库以及如何执行与数据相关的操作,以便为所有数据库的后续数据分析做准备。

学习数据文件作为数据库

在进行数据分析活动时,我们需要不断进行数据导入、加载或导出功能。有时,可能需要使用 R 编程语言反复执行相同的操作。因此,我们可以使用 R 的现有函数来执行相同的数据操作。

理解不同类型的文件

常用的 R 数据存储操作文件有四种不同的类型。它们如下:

  • CSV(逗号分隔值)

  • Txt(带有制表符分隔值)

  • .RDATA(R 的本地数据格式)

  • .rda(R 的本地数据格式)

安装 R 包

要使用之前指定格式的数据文件,我们不需要额外安装 R 包。我们只需要使用 R 提供的内置函数。

将数据导入 R

要执行与分析相关的活动,我们需要使用以下函数将数据导入 R:

  • CSV:read.csv() 用于读取 逗号分隔值CSV)文件,其中小数点是 ","。检索到的数据将存储到一个 R 对象中,这被视为 Dataframe

    Dataframe <- read.csv("data.csv",sep=",")
    
    
  • TXT:要检索制表符分隔的值,read.table() 函数将与一些重要参数一起使用,该函数的返回类型将是 Dataframe 类型

    Dataframe <- read.table("data.csv", sep="\t")
    
    
  • .RDATA:此处,.RDATA 格式由 R 用于存储特定时间段的工作区数据。它被视为图像文件。这将存储/检索工作区中所有可用的数据。

    load("history.RDATA")
    
    
  • .rda:这也是 R 的本地数据格式,根据需要存储特定的数据变量。

    load("data_variables_a_and_b.rda")
    
    

从 R 导出数据

要从 R 导出现有的数据对象并支持按要求的数据文件,我们需要使用以下函数:

  • CSV:通过以下命令将 dataframe 对象写入 csv 数据文件:

    write.csv(mydata, "c:/mydata.csv", sep=",", row.names=FALSE)
    
    
  • TXT:通过以下命令将数据写入带有制表符分隔符的数据文件:

    write.table(mydata, "c:/mydata.txt", sep="\t")
    
    
  • .RDATA:要存储可用于 R 会话的工作区数据变量,请使用以下命令:

    save.image()
    
    
  • .rda:此函数用于存储特定的数据对象,供以后使用。使用以下代码将它们保存到 .rda 文件中。

    # column vector
    a <- c(1,2,3)
    
    # column vector
    b <- c(2,4,6)
    
    # saving it to R (.rda) data format
    save(a, b, file=" data_variables_a_and_b.rda")
    
    

理解 MySQL

MySQL 是世界上最流行的开源数据库。世界上许多最大和发展最快的组织,包括 Facebook、Google、Adobe 和 Zappos,都依赖 MySQL 数据库,以节省时间和金钱,支持高流量的网站、关键业务系统和软件包。

由于 R 和 MySQL 都是开源的,它们可以用于构建交互式网页分析应用程序。同时,借助这个独特的包,也可以对现有的网页应用程序进行简单的数据分析。

要在 Linux 机器上安装 MySQL,您需要按照以下步骤顺序进行操作:

  • 安装 MySQL

  • 安装 RMySQL

安装 MySQL

我们将看到如何在 Linux 上安装 MySQL:

// Updating the linux package list
sudo apt-get update

// Upgrading the updated packages
sudo apt-get dist-upgrade

//First, install the MySQL server and client packages:
sudo apt-get install mysql-server mysql-client

提示

使用以下命令登录到 MySQL 数据库:

mysql -u root -p

安装 RMySQL

现在,我们已经在 Linux 机器上安装了 MySQL。是时候通过以下 R 命令从 CRAN 安装 RMySQL 库:

# to install RMySQL library
install.packages("RMySQL")

#Loading RMySQL
library(RMySQL)

在 RMySQL 库安装在 R 上后,通过提供 MySQL 管理控制台中提供的用户权限,执行 MySQL 数据库连接:

mydb = dbConnect(MySQL(), user='root', password='', dbname='sample_table', host='localhost')

学习列出表格及其结构

现在,数据库连接已成功完成。要列出 MySQL 数据库中可用的表及其数据结构,可以查看以下命令。要返回 mydb 数据库下创建的可用表,请使用以下命令:

dbListTables(mydb)

要返回在 sample_table 表中创建的数据字段列表,请使用以下命令:

dbListFields(mydb, 'sample_table')

将数据导入到 R 中

我们知道如何检查 MySQL 表及其字段。在识别出有用的数据表后,我们可以使用以下 RMySQL 命令将其导入 R 中。为了根据提供的 SQL 查询从 MySQL 数据库中检索自定义数据,我们需要将其存储在一个对象中:

rs = dbSendQuery(mydb, "select * from sample_table")

可用的数据相关信息可以通过以下 fetch 命令从 MySQL 获取到 R 中:

dataset = fetch(rs, n=-1)

在此,指定参数 n = -1 用于检索所有待处理的记录。

理解数据操作

要执行 MySQL 数据库的数据操作,我们需要执行 SQL 查询。但在 RMySQL 的情况下,我们可以通过 dbSendQuery 函数执行命令。

使用现有的 R 数据框在 MySQL 数据库中创建新表可以通过以下命令完成:

dbWriteTable(mydb, name='mysql_table_name', value=data.frame.name)

要将 R 矩阵数据插入到 MySQL 中现有的数据表,可以使用以下命令:

# defining data matrix
datamatrix <- matrix(1:4, 2, 2)

# defining query to insert the data
query <- paste("INSERT INTO names VALUES(",datamatrix [1,1], ",", datamatrix [1,2], ")")

# command for submitting the defined SQL query dbGetQuery(con, query)

有时候,当 MySQL 表不再使用时,我们需要删除它。可以执行以下查询来删除 mysql_some_table 表:

dbSendQuery(mydb, 'drop table if exists mysql_some_table').

理解 Excel

Excel 是由微软开发的一款电子表格应用程序,支持在 Windows 和 Mac OS 上运行,具有类似于 R 的功能,用于执行统计计算、图形可视化和数据建模。Excel 是微软在 Microsoft Office 套件中提供的,主要支持 .xls 电子表格数据文件格式。如果我们希望从 R 中读取或写入 Microsoft Excel 电子表格,可以使用许多可用的 R 包。但其中一个流行且有效的 R 库是 xlsx。

该包通过编程方式提供对 Excel 文件的控制,允许用户将 .xlsx 文档的电子表格读取到 data.frame 中,并将 data.frame 写入文件。该包是由 Adrian A. Dragulescu 开发的。

安装 Excel

在这里,我们将 .xls 文件作为数据源,可以借助 Microsoft Excel 97/2000/XP/2003 来构建和维护该文件。

以下是 xlsx 包的前提条件:

  • xlsxjars

  • rJava

安装 xlsxX 包:

  • Install.packages(“xlsxjars”)

  • Install.packages(“rJava”)

  • Install.packages(“xlsx”)

将数据导入到 R 中

假设我们已经创建了一个 Excel 文件,现在我们希望在 R 中执行与数据分析相关的操作,那么这个包是将 Excel 文件加载到 R 中进行处理的最佳选择。

es <- read.xlsx("D:/ga.xlsx",1) 

前面的命令将把 Excel 数据(带有工作表 1)存储到 R 中的 es 数据框格式。

理解 R 和 Excel 中的数据操作

以下命令将用于选择数据框res的子集,其中选择前五行:

r <- res[1:5,]

将数据导出到 Excel

根据定义的名称,处理后的数据可以以xls文件格式存储,支持 Excel。

ress <- write.xlsx(r, "D:/ga1.xls") 

理解 MongoDB

MongoDB 是一种基于 NoSQL 的分布式文档数据存储。它特别设计用于提供可扩展且高性能的数据存储解决方案。在许多场景中,它可以用来替代传统的关系型数据库或键值数据存储。Mongo 的最大特点是其查询语言,非常强大,语法与面向对象的查询语言有些相似。

以下是 MongoDB 的特点:

  • 面向集合的存储,易于存储对象类型

  • 支持动态查询

  • 完整的索引支持

  • 丰富的查询语言

  • 数据碎片处理顺序以支持云级扩展

  • 基于 BSON 的文件数据存储

  • 支持 C、C++、C#、Erlang、Haskell、Java、JavaScript、Perl、PHP、Python、Ruby 和 Scala

我们可以通过安装以下先决条件,将 R 和 MongoDB 一起使用:

  • MongoDB 安装

  • rmongodb 安装

安装 MongoDB

以下是在 Ubuntu 12.04 和 CentOS 中安装 MongoDB 的步骤:

首先,我们将看到 Ubuntu 的安装步骤。

  1. 使用以下命令配置软件包管理系统(APT):

    sudo apt-key adv --keyserverhkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
    
    
  2. 使用以下命令创建/etc/apt/sources.list.d/mongodb.list

    echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list
    
    
  3. 现在,使用以下命令更新您的操作系统软件包列表:

    sudo apt-get update
    
    
  4. 使用以下命令安装 MongoDB 的最新版本:

    apt-get install mongodb-10gen
    
    

现在,我们将看到 CentOS 的安装步骤。

  1. 配置软件包管理系统(YUM)。

  2. 创建/etc/yum.repos.d/mongodb.repo并使用以下配置:

    • 对于 64 位系统,请使用以下命令:

      [mongodb]
      name=MongoDB Repository
      baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
      gpgcheck=0
      enabled=1
      
      
    • 对于 32 位系统,请使用以下命令:

      [mongodb]
      name=MongoDB Repository
      baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/i686/
      gpgcheck=0
      enabled=1
      
      
  3. 安装软件包。

使用以下命令,安装 MongoDB 的稳定版本及相关工具:

yum install mongo-10gen mongo-10gen-server

现在,您已成功安装 MongoDB。

提示

用于控制 mongodb 服务的有用命令

要启动 mongodb 服务,我们使用以下命令:

sudo service mongodb start

要停止 mongodb 服务,我们使用以下命令:

sudo service mongodb stop

要重启 mongodb 服务,我们使用以下命令:

sudo service mongodb restart

要启动 Mongo 控制台,我们使用以下命令:

mongo

SQL 映射到 MongoDB

以下是 SQL 术语与 MongoDB 术语的映射,帮助更好地理解数据存储:

序号SQL 术语MongoDB 术语
1.数据库数据库
2.集合
3.索引索引
4.文档
5.字段
6.加入嵌入与链接

SQL 映射到 MongoQL

以下是 SQL 语句与 Mongo QL 语句的映射,帮助理解查询开发/转换:

序号SQL 语句Mongo QL 语句
1.
INSERT INTO students VALUES(1,1)

|

$db->students->insert(array("a" => 1, "b" => 1));

|

2.
SELECT a, b FROM students

|

$db->students->find(array(), array("a" => 1, "b" => 1));

|

3.
SELECT * FROM students WHERE age < 15

|

$db->students->find(array("age" => array('$lt' => 15)));

|

4.
UPDATE students SET a=1 WHERE b='q'

|

$db->students->update(array("b" => "q"), array('$set' => array("a" => 1)));

|

5.
DELETE FROM students WHERE name="siddharth"

|

$db->students->remove(array("name" => " siddharth"));

|

安装 rmongodb

要在 R 中使用 MongoDB,我们需要安装带有 rmongodb 库的 R。我们可以通过以下命令从 CRAN 安装 rmongodb:

# installing library rmongodb in R
install.packages (rmongodb)

将数据导入 R

我们已经学习了如何在 Ubuntu 12.04 上安装 MongoDB。现在,我们可以对数据执行所有必要的操作。在本节中,我们将学习如何在 R 中处理和导入 Mongo 数据进行数据分析活动。加载库时,我们使用以下命令:

# loading the library of rmongodb
library (rmongodb)

Mongo connection establishment
mongo <-mongo.create ()

Check whether the normal series
mongo.is.connected (mongo)

Create a BSON object cache
buf <- mongo.bson.buffer.create ()

Add element to the object buf
mongo.bson.buffer.append (buf, "name", "Echo")

mongo.bson 类的对象用于存储 BSON 文档。BSON 是 MongoDB 用来在其数据库中存储文档的格式。MongoDB 的网络流量也使用 BSON 消息:

b <- mongo.bson.from.list(list(name="Fred", age=29, city="Boston"))iter <- mongo.bson.iterator.create(b)  # b is of class "mongo.bson"while (mongo.bson.iterator.next(iter))print(mongo.bson.iterator.value(iter))

了解数据操作

现在我们将看到如何在 R 中操作 Mongo 数据对象:

# To check whether mongo is connected or not in R.
if (mongo.is.connected(mongo)) {ns <- "test.people"
#Returns a fresh mongo.bson.buffer object ready to have data 
#appended onto it in R.buf <- mongo.bson.buffer.create()mongo.bson.buffer.append(buf, "name", "Joe")criteria <- mongo.bson.from.buffer(buf)

# mongo.bson.buffer objects are used to build mongo.bson objects.buf <- mongo.bson.buffer.create()
 mongo.bson.buffer.start.object(buf, "inc")mongo.bson.buffer.append(buf, "age", 1L)mongo.bson.buffer.finish.object(buf)objNew <- mongo.bson.from.buffer(buf)# increment the age field of the first record   matching name "Joe"mongo.update(mongo, ns, criteria, objNew)

# mongo.bson.buffer objects are used to build mongo.bson objects.buf <- mongo.bson.buffer.create()mongo.bson.buffer.append(buf, "name", "Jeff")criteria <- mongo.bson.from.buffer(buf)

# mongo.bson.buffer objects are used to build mongo.bson objects.buf <- mongo.bson.buffer.create()mongo.bson.buffer.append(buf, "name", "Jeff")mongo.bson.buffer.append(buf, "age", 27L)objNew <- mongo.bson.from.buffer(buf)# update the entire record to { name: "Jeff", age: 27 }# where name equals "Jeff"# if such a record exists; otherwise, insert this as a new reordmongo.update(mongo, ns, criteria, objNew,mongo.update.upsert)# do a shorthand update:mongo.update(mongo, ns, list(name="John"), list(name="John", age=25))}

了解 SQLite

SQLite 是一个使用 C 编程语言开发的关系型数据库管理系统。SQLite 遵循 ACID 原则,并实现了大部分 SQL 标准。与其他数据库系统不同,SQLite 没有独立的进程来为客户端应用程序提供数据。它是一个嵌入式 SQL 数据库引擎。SQLite 系统直接读取和写入系统磁盘文件,因为它是一个基于文件的数据库。相关的 SQL 数据库包含多个表、索引和视图,并且这种数据库文件格式支持跨平台使用。

快速了解事务的 ACID 属性:

为了执行事务,需要满足一系列属性。它们是原子性、一致性、隔离性和持久性,具体解释如下:

  • 原子性指的是数据库所有任务都必须执行的保证。

  • 一致性确保数据库始终保持一致状态,就像我们开始之前的状态一样。

  • 隔离性指的是在事务期间,其他操作无法访问或查看数据的中间状态。

  • 持久性指的是一旦用户收到成功通知,事务将会持久化,不会被撤销。这意味着它能在系统故障后生存,并且数据库系统已检查完整性约束,且不需要中止事务。

了解 SQLite 的特点

以下是遵循 ACID 属性的 SQLite 数据库特性:

  • 零配置

  • 支持跨平台的磁盘格式

  • 比客户端-服务器型数据库系统更快

  • 易于使用的 API

使用 SQLite 和 R 一起使用时,我们需要以下先决条件:

  • SQLite 安装

  • 安装 RSQLite

安装 SQLite

要在 Ubuntu 中安装 SQLite 数据库,请遵循给定的命令:

// install sqllite by firing the following commands
sudo apt-get purge sqlite3 sqlite3-doc libsqlite3-0
sudo apt-get autoremove
sudo apt-get install sqlite3 sqlite3-doc

安装 RSQLite

我们可以通过以下命令安装 RSQLite:

# installing RSQLite library from CRAN in R
Install.packages("RSQLite")

将数据导入 R

我们将看到如何使用 RSQLite 包将数据插入 R 中。

要加载已安装的包,我们使用以下命令:

#loading the installed package
library("RSQLite")

使用以下命令,您可以连接到数据库并列出所有数据库中的表:

# connect to db
con <- dbConnect(SQLite(), dbname="data/first.db")

# list all tables
tables <- dbListTables(con)

# exclude sqlite_sequence (contains table information)
tables <- tables[tables != "sqlite_sequence"]
lDataFrames <- vector("list", length=length(tables))

# create a data.frame for each table
for (i in seq(along=tables)) {
 lDataFrames[[i]] <- dbGetQuery(conn=con, statement=paste("SELECT * FROM '", tables[[i]], "'", sep=""))
}

了解数据操作

我们可以使用以下命令操作数据集:

dbBeginTransaction(con)
rs <- dbSendQuery(con, "DELETE from candidates WHERE age > 50")
Exporting the data from Rdata(USArrests)
dbWriteTable(con, "USArrests", USArrests)

理解 PostgreSQL

PostgreSQL 是一个开源的对象关系型数据库管理系统。PostgreSQL 可以在大多数操作系统上运行,如 Linux、UNIX 和 Windows。它支持文本、图像、声音和视频数据源。它还支持 C、C++、Java、Python、Ruby 和 Tcl 等编程技术。

理解 PostgreSQL 的特性

以下是 PostgreSQL 的特性:

  • 复杂 SQL 查询

  • 完全符合 ACID 规范

  • SQL 子查询

使用 PostgreSQL 在 R 中时,我们需要安装以下先决条件:

  • 安装 PostgreSQL

  • 安装 RPostgreSQL

安装 PostgreSQL

在这一节中,我们将学习如何安装 PostgreSQL。

安装 PostgreSQL 时,将按照以下命令进行:

// updating the packages list
Sudo apt-get update

// installing postgresql 
sudo apt-get install postgresql postgresql-contrib

// creating postgresql user
su – postgres createuser

安装 RPostgreSQL

现在我们将了解如何安装并使用 RPostgreSQL:

# installing package from CRAN
install.packages(RPostgreSQL)
Importing the data into R# loading the installed package
library(RPostgreSQL)

## load the PostgreSQL driver
drv <- dbDriver("PostgreSQL")

## Open a connection
con <- dbConnect(drv, dbname="oxford")

## Submits a statement
rs <- dbSendQuery(con, "select * from student")

## fetch all elements from the result set
fetch(rs,n=-1)

## Closes the connection
dbDisconnect(con)

## Frees all the resources on the driver
dbUnloadDriver(drv)

使用以下代码,我们将学习如何在 R 中操作存储在 PostgreSQL 中的数据:

opendbGetQuery(con, "BEGIN TRANSACTION")
rs <- dbSendQuery(con,
"Delete * from sales as p where p.cost>10")
if(dbGetInfo(rs, what = "rowsAffected") > 250){
  warning("Rolling back transaction")
  dbRollback(con)
}else{
  dbCommit(con)
}

从 R 中导出数据

在这一节中,我们将学习如何加载数据,将数据框中的内容写入指定的表,并从数据库连接中删除指定的表:

conn <- dbConnect("PostgreSQL", dbname = "wireless")
if(dbExistsTable(con, "frame_fuel")){
  dbRemoveTable(conn, "frame_fuel")
  dbWriteTable(conn, "frame_fuel", fuel.frame)
}
if(dbExistsTable(conn, "RESULTS")){
  dbWriteTable(conn, "RESULTS", results2000, append = T)
  else
  dbWriteTable(conn, "RESULTS", results2000)
}

理解 Hive

Hive 是一个基于 Hadoop 的数据仓库框架,由 Facebook 开发。它允许用户使用 SQL 查询,并通过 HiveQL 等语言将查询高度抽象化为 Hadoop MapReduce。这使得没有 MapReduce 经验的 SQL 程序员能够使用该数据仓库,并且便于与商业智能和可视化工具集成,实现实时查询处理。

理解 Hive 的特性

以下是 Hive 的特性:

  • Hibernate 查询语言(HQL)

  • 支持 UDF

  • 元数据存储

  • 数据索引

  • 不同的存储类型

  • Hadoop 集成

RHive 的先决条件如下:

  • Hadoop

  • Hive

我们假设读者已经配置了 Hadoop;如果没有,他们可以通过 第一章,准备使用 R 和 Hadoop 来学习 Hadoop 的安装。由于运行 RHive 需要 Hive,我们将首先了解如何安装 Hive。

安装 Hive

安装 Hive 的命令如下:

// Downloading the hive source from apache mirror
wget http://www.motorlogy.com/apache/hive/hive-0.11.0/hive-0.11.0.tar.gz

// For extracting the hive source
tar xzvf  hive-0.11.0.tar.gz

设置 Hive 配置

要设置 Hive 配置,我们需要通过添加几项内容来更新 hive-site.xml 文件:

  • 使用以下命令更新 hive-site.xml 文件:

    <description> JDBC connect string for a JDBC metastore </ description>
    </Property>
    
    <property>
    <name> javax.jdo.option.ConnectionDriverName </ name>
    <value> com.mysql.jdbc.Driver </ value>
    <description> Driver class name for a JDBC metastore </ description>
    </Property>
    
    <property>
    <name> javax.jdo.option.ConnectionUserName </ name>
    <value> hive </value>
    <description> username to use against metastore database </ description>
    </ Property>
    
    <property>
    <name> javax.jdo.option.ConnectionPassword </name>
    <value> hive</value>
    <description> password to use against metastore database </ description>
    </Property>
    
    <property>
    <name> hive.metastore.warehouse.dir </ name>
    <value> /user/hive/warehouse </value>
    <description> location of default database for the warehouse </ description>
    </Property>
    
  • 通过添加以下行来更新 hive-log4j.properties

    log4j.appender.EventCounter = org.apache.hadoop.log.metrics.EventCounter
    
    
  • 使用以下命令更新环境变量:

    export $HIVE_HOME=/usr/local/ hive-0.11.0
    
    
  • 在 HDFS 中,为 Hive 创建特定目录:

    $HADOOP_HOME/bin/ hadoop fs-mkidr /tmp
    $HADOOP_HOME/bin/ hadoop fs-mkidr /user/hive/warehouse
    $HADOOP_HOME/bin/ hadoop fs-chmod g+w / tmp
    $HADOOP_HOME/bin/ hadoop fs-chmod g+w /user/hive/warehouse
    
    

    提示

    要启动 Hive 服务器,需要从 HIVE_HOME 执行 hive --service hiveserver 命令。

安装 RHive

  • 使用以下命令安装依赖库 rjava

    // for setting up java configuration variables
    sudo R CMD javareconf
    
    // Installing rJava package
    install.packages ("rJava")
    
    // Installing RHive package from CRAN
    install.packages("RHive")
    
    // Loading RHive library
    library("RHive")
    
    

理解 RHive 操作

我们将了解如何使用 RHive 库在 R 中加载并操作 Hive 数据集:

  • 初始化 RHive 时,我们使用:

    rhive.init ()
    
    
  • 要连接到 Hive 服务器,我们使用:

    rhive.connect ("192.168.1.210")
    
    
  • 要查看所有表,我们使用:

    rhive.list.tables ()
     tab_name
    1 hive_algo_t_account
    2 o_account
    3 r_t_account
    
    
  • 要查看表结构,我们使用:

    rhive.desc.table ('o_account');
     col_name data_type comment
    
    1 id int
    2 email string
    3 create_date string
    
    
  • 执行 HQL 查询时我们使用:

    rhive.query ("select * from o_account");
    
    
  • 关闭与 Hive 服务器的连接时我们使用:

    rhive.close()
    
    

理解 HBase

Apache HBase 是一个分布式大数据存储系统,适用于 Hadoop。它允许对大数据进行随机、实时的读写访问。该系统设计为面向列的数据存储模型,灵感来自于 Google Bigtable。

理解 HBase 的特性

以下是 HBase 的特性:

  • 使用 XML 的 RESTful web 服务

  • 线性和模块化的可扩展性

  • 严格一致的读写操作

  • 可扩展的 shell

  • 用于实时查询的块缓存和布隆过滤器

RHBase 的前提条件如下:

  • Hadoop

  • HBase

  • Thrift

在这里我们假设用户已经为其 Linux 机器配置了 Hadoop。如果有人想了解如何在 Linux 上安装 Hadoop,请参考 第一章,准备使用 R 和 Hadoop

安装 HBase

以下是安装 HBase 的步骤:

  1. 下载 HBase 的 tar 文件并解压:

    wget http://apache.cs.utah.edu/hbase/stable/hbase-0.94.11.tar.gz
    
    tar -xzf hbase-0.94.11.tar.gz
    
    
  2. 进入 HBase 安装目录并更新配置文件:

    cd hbase-0.94.11/
    
    vi conf/hbase-site.xml
    
    
  3. 修改配置文件:

    1. 更新 hbase-env.sh

      ~ Vi conf / hbase-env.sh 
      
      
    2. 设置 HBase 配置:

       export JAVA_HOME = /usr/lib/jvm/java-6-sun
       export HBASE_HOME = /usr/local/hbase-0.94.11
       export HADOOP_INSTALL = /usr/local/hadoop
       export HBASE_CLASSPATH = /usr/local/hadoop/conf
       export HBASE_MANAGES_ZK = true
      
      
    3. 更新 hbase-site.xmlzxml

      Vi conf / hbase-site.xml
      
      
    4. 修改 hbase-site.cml,其内容应类似于以下代码:

          <configuration>
            <property>
              <name> hbase.rootdir </name>
              <value> hdfs://master:9000/hbase </value>
            </Property>
      
            <property>
              <name>hbase.cluster.distributed </name>
              <value>true</value>
            </Property>
      
            <property>
               <name>dfs.replication </name>
               <value>1</value>
            </Property>
      
            <property>
              <name>hbase.zookeeper.quorum </name>
              <value>master</value>
            </Property>
      
            <property>
                <name>hbase.zookeeper.property.clientPort </name>
                <value>2181</value>
            </Property>
      
            <property>
              <name>hbase.zookeeper.property.dataDir </name>
              <value>/root/hadoop/hdata</​​value>
            </Property>
          </ Configuration>
      

      提示

      如果使用了独立的 Zookeeper 配置,则需要更改配置。

    5. 复制 Hadoop 环境配置文件和库文件。

      Cp $HADOOP_HOME/conf/hdfs-site.xml $HBASE_HOME/conf
      Cp $HADOOP_HOME/hadoop-core-1.0.3.jar $HBASE_HOME/lib
      Cp $HADOOP_HOME/lib/commons-configuration-1.6.jar $HBASE_HOME/lib
      Cp $HADOOP_HOME/lib/commons-collections-3.2.1.jar $HBASE_HOME/lib
      
      

安装 thrift

以下是安装 thrift 的步骤:

  1. 从网上下载 thrift 源码并将其放置到客户端。我们将使用 Ubuntu O.S 12.04 来完成此操作:

    get http://archive.apache.org/dist/thrift/0.8.0/thrift-0.8.0.tar.gz
    
    
  2. 使用以下命令解压下载的 .tar.gz 文件:

    tar xzvf thrift-0.8.0.tar.gz
    cd thrift-0.8.0/
    
    
  3. 编译配置参数:

    ./Configure
    
    
  4. 安装 thrift:

    Make
    Make install
    
    

    提示

    启动 HBase thrift 服务器时,我们需要调用以下命令:

    $HBASE_HOME/bin/hbase-daemon.sh start
    
    

安装 RHBase

安装 HBase 后,我们将展示如何获取 RHBase 库。

  • 安装 rhbase 时使用以下命令:

    wget https://github.com/RevolutionAnalytics/rhbase/blob/master/build/rhbase_1.2.0.tar.gz
    
    
  • 使用以下命令安装下载的包:

    R CMD INSTALL rhbase_1.2.0.tar.gz
    
    

将数据导入到 R 中

一旦 RHBase 安装完成,我们可以借助 RHBase 将数据集从 HBase 加载到 R 中:

  • 列出所有表时我们使用:

    hb.list.tables ()
    
    
  • 创建新表时我们使用:

    hb.new.table ("student")
    
    
  • 显示表结构时我们使用:

    hb.describe.table("student_rhbase")
    
    
  • 读取数据时我们使用:

    hb.get ('student_rhbase', 'mary')
    
    

理解数据操作

现在,我们将展示如何在 R 中操作 HBase 数据集:

  • 创建表时我们使用:

    hb.new.table ("student_rhbase", "info")
    
    
  • 插入数据时我们使用:

    hb.insert ("student_rhbase", list (list ("mary", "info: age", "24")))
    
    
  • 删除表时我们使用:

    hb.delete.table ('student_rhbase')
    
    

总结

在本章中,我们学习了如何将与各种数据库系统和其数据集集成的 R 包加载到 R 中进行数据分析。大多数流行的数据库系统都提供了 R 包,用于加载数据、更新数据以及查询数据以进行分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值