(本科)第18章-数据科学的R语言.pdf
(c) 2020,陈强,机器学习及 R 应用,高等教育出版社 1 第第 18 章章 数据科学的数据科学的 R 语言语言 机器学习在数据科学领域也有着广泛的应用。 本章着重介绍在数据科学方面常用的两个超级 R 包,即 tidyverse 与 caret,更为贴近业界的数据科学实践。 18.1 何为数据科学何为数据科学 数据科学(data science)是从数据中发现模式、规律,得到洞见(insight),从而为业界创造商业价值的一套科学方法)。 数据科学的主旨是,从数据中挖掘有用信息,产生新知识(knowledge generation),并为业界创造商业价值。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 2 通俗地说, 数据科学就是 “数据科学家” (data scientist)所做的那些事情,即 所 谓 的 “ 数 据 科 学 项 目 ” (data science project) 。 Wickham and Grolemund(2016)对数据科学项目的流程作了总结,参见图 18.1。 图 18.1 数据科学项目的流程 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 3 (1) 一个典型的数据科学项目始于 “输入” (import)数据到软件, 比如 R。如果没有数据,则巧妇难为无米之炊,无法进行数据科学项目。 (2) 将数据导入软件后,一般需要先进行“数据清理”(data cleaning),使其变得“整洁”(tidy)。需要将数据整理为内部自洽的“一致结构”(consistent structure),通常表现为“矩形数据”(rectangular data),即以行表示个体(观测值),而以列表示变量。 (3) 完成数据清理之后, 一般须进一步对数据进行变换(transform), 包括将变量标准化(standardization),根据原有变量定义新的特征变量,选择原样本的某些子集, 合并数据集, 以及计算统计指标等。 这些变换也称为 “预处理”(pre-processing)。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 4 (4) 在数据清理与预处理之后,即可开始从数据中“创造知识”(knowledge generation)的过程,包括“可视化”(visualization)与“建模”(modeling)。 可视化能让你看到数据中意想不到的现象,或提出新问题。 建模则通过数学模型与算法,找到数据之间的内在联系与规律。无论可视化,还是建模,都可加深我们对于数据的理解(understand)。 (5) 数据科学项目的最后一步为 “交流” (communicate), 即向有关领导、部门或用户汇报你的研究结果与发现。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 5 围绕以上数据科学项目全过程的则是“编程”(programming)。 从输入数据、数据清理、数据变换,到可视化、建模,乃至交流,都离不开编程。 一个优秀的数据科学家需要具备三方面的知识与技能,即数理知识(例如机器学习)、 编程能力(例如R语言编程)与专业知识(熟悉所在行业业务)。 为便于执行数据科学项目, RStudio 首席科学家 Hadley Wickham 推出了超级 R 包 tidyverse,包含一系列内在自洽的 R 包;并因此获得国际统计学会的 COPSS 奖。 下面,安装并载入 R 包 tidyverse: (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 6 install.packages(tidyverse) library(tidyverse) Attaching packages tidyverse 1.3.0 ggplot2 3.2.1 purrr 0.3.3 tibble 2.1.3 dplyr 0.8.4 tidyr 1.0.2 stringr 1.4.0 readr 1.3.1 forcats 0.4.0 Conflicts tidyverse_conflicts() x dplyr:filter() masks stats:filter() x dplyr:lag() masks stats:lag() (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 7 结果表明, 载入R包tidyverse后, 自动加载了8个R包, 即ggplot2,tibble, tidyr, readr, purrr, dplyr, stringr, 以及 forcats(将在下文介绍其中最重要的几个包)。 结果还显示,R 包 dplyr 中的 filter()函数与 lag()函数分别“掩盖”(mask)了同名的 R 基础函数。 如果你想调用 R 基础函数 filter()或 lag(),则须使用它们的全称stats:filter()或 stats:lag(), 从 R 的基础包 stats 调用这两个函数。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 8 18.2 管道算子管道算子 作为函数式语言(functional language),每个 R 命令都是一个函数。 出于编程的需要,经常会使用“复合函数”(composite function),即一个函数套着一个函数,再套一个函数,例如( )f g h x,以此类推。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 9 如果复合函数有太多层,则使得 R 代码变得不易阅读,例如: x y y 1 8.43 其中,对向量 x 先取对数,然后开根号,再求正弦,之后求和,最后保留小数点后两位数。 这里使用了多重的复合函数,有很多括号,看得有些眼花缭乱。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 10 一种解决方法为,引入一些中间环节,例如 x z w y y 1 8.43 以上代码中的“中间对象”(intermediate objects)z 与 w 可能并没有什么意义,而且多用了两行代码。 为此, 可使用管道算子(pipe operator) “%” 来精简代码, 提高可读性。(c) 2020,陈强,机器学习及 R 应用,高等教育出版社 11 管道算子最初来自 R 包 magrittr,也为 R 包 tidyverse 所采用。 只要载入 R 包 tidyverse,就自动加载了管道算子,不必再单独载入R 包 magrittr。 如果你只需管道算子,而不用 tidyverse,则可用命令“library(magrittr)”载入。 使用管道算子,可将以上代码改为 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 12 library(tidyverse) x y % log % sqrt % sin % sum % round(2) y 1 8.43 其中,管道算子“%”可读为“然后”(then)。 比如,“x % log” 把 x 作为参数传给函数 log(), 故等价于 log(x)。 管道算子的优势在于, 可将一系列管道连在一起, 构成一个较长的管道。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 13 比如, “x % log % sqrt”等价于“sqrt(log(x)” ,以此类推。 在 RStudio 中, 可用快捷键 “Ctrl + Shift + M” 来输入管道算子 “%” 。 管道算子的基本用法可总结如下: (1) “x % f”等价于“f(x)” (2) “x % f(y)”等价于“f(x, y)” (3) “x % f % g”等价于“g(f(x)” (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 14 在以上规则(2)中,如何得到函数 f(y,x)?此时,需要使用“参数占位符”(argument placeholder),例如 (4) “x % f(y, .)”等价于“f(y, x)” (5) “x % f(y, z = .)”等价于“f(y, z = x)” 其中, “.”即为参数占位符,用于指示从左边传入的参数 x 在函数 f()中应占据的位置。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 15 并非在所有情况下,都应使用管道算子。 如果管道太长(比如超过 10 步),可考虑通过分拆的多个命令来实现,这样更便于纠错(debug)。 如果函数的输入值或输出值较多(multiple inputs or outputs), 则使用管道算子也不方便。 何时使用管道算子,可能是个人编程的风格。 但即使你不用管道算子, 学习它依然有益, 至少可让你看懂别人的代码。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 16 18.3 输入数据输入数据 R 包 tidyverse 的 readr 包用于读入数据。 R 语言的基础函数 read.csv()与 read.table()已可读取数据,为何还要 readr? 因为 readr 读取数据的速度比 read.table()能快几倍;而业界数据通常样本容量很大。 以第 11 章曾使用过的葡萄牙银行数据为例。这次使用更为完整的数据集 bank-additional-full.csv,可从本书网站下载,并放入工作路径。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 17 首先,以基础函数 read.csv()读入数据,并命名为 bank: bank dim(bank) 1 41188 21 使用函数 system.time()考察运行此命令的时间: system.time(read.csv(bank-additional-full.csv, header = TRUE,sep=;) 用户 系统 流逝 0.43 0.00 0.44 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 18 下面使用 R 包 readr 的 read_csv()系列函数来读取数据。由于此文件以分号“;”分割,故使用其 read_delim()函数: library(tidyverse) bank system.time(read_delim(bank-additional-full.csv, col_names = TRUE,delim = ;) 用户 系统 流逝 0.12 0.00 0.13 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 19 R 包 readr 除了可提升读取速度,还会输出一种称为“tibble”的特殊数据框: bank # A tibble: 41,188 x 21 age job marital education default housing loan contact month 1 56 hous married basic.4y no no no teleph may 2 57 serv married high.sch unknown no no teleph may 3 37 serv married high.sch no yes no teleph may 4 40 admi married basic.6y no no no teleph may 5 56 serv married high.sch no no yes teleph may 6 45 serv married basic.9y unknown no no teleph may (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 20 7 59 admi married professi no no no teleph may 8 41 blue married unknown unknown no no teleph may 9 24 tech single professi no yes no teleph may 10 25 serv single high.sch no yes no teleph may # with 41,178 more rows, and 12 more variables: day_of_week , # duration , campaign , pdays , previous , # poutcome , emp.var.rate , cons.price.idx , # cons.conf.idx , euribor3m , nr.employed , y tibble 仍是数据框, 与传统 data.frame 的主要区别在于打印结果。 tibble 仅打印前 10 行数据与能在屏幕排下的所有变量。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 21 在变量名之下, 还显示每个变量的类型, 比如表示 “double” (即double precision,以双精度表示实数),而表示“character”(字符型)。 另外,也汇报省略的行数与变量名。 这种排列方式对于大型数据较为方便, 不致于在打印数据时淹没整个屏幕。 如果需要把数据框、矩阵或列表转为 tibble,可使以函数as_tibble()。 R 包 readr 中还有 write_csv()函数,可将数据存为 CSV 文件。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 22 如果样本容量特别大(比如大数据),建议使用 R 包 data.table 的fread()函数,进一步提升数据读取速度: install.packages(data.table) library(data.table) system.time(fread(bank-additional-full.csv) 用户 系统 流逝 0.01 0.00 0.02 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 23 18.4 数据清理数据清理 数据科学家可能要花大量时间清洗数据,把数据整理为可用的格式。 R 包 tidyverse 的 tidyr 包使得数据清理变得简单。 “整洁数据”(tidy data)有以下三个简单标准: (1) 每个变量都占一列; (2) 每个观测值都占一行; (3) 每个观测值的每个变量取值都占一格。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 24 以 R 包 tidyverse 的自带数据 table1 为例: library(tidyverse) table1 # A tibble: 6 x 4 country year cases population 1 Afghanistan 1999 745 19987071 2 Afghanistan 2000 2666 20595360 3 Brazil 1999 37737 172006362 4 Brazil 2000 80488 174504898 5 China 1999 212258 1272915272 6 China 2000 213766 1280428583 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 25 table1 是“面板数据”(panel data),其每位个体(Afghanistan、Brazil 与 China)均出现两次(1999、 2000), 共有 4 个变量(country、year、cases、population)。 table1 已经是整洁数据。但在数据被清理之前,同样信息可能以table4a 与 table4b 的不整洁形式存在: (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 26 table4a # A tibble: 3 x 3 country 1999 2000 * 1 Afghanistan 745 2666 2 Brazil 37737 80488 3 China 212258 213766 其中, 由于 “1999” 与 “2000” 一般不宜作为变量名, 故用反撇号(backtick)“”将其括起来。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 27 table4b # A tibble: 3 x 3 country 1999 2000 * 1 Afghanistan 19987071 20595360 2 Brazil 172006362 174504898 3 China 1272915272 1280428583 其中,table4a 包含 table1 中变量 cases 的信息,而 table4b 包含table1 中变量 population 的信息,但变量 year 的两个取值被作为变量1999与2000使用。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 28 为进行数据清理, 首先使用 tidyr 包中的 gather()函数将 table4a中的两列数据“聚集”(gather)为一个变量 cases。 使用管道算子“%” ,此命令可写为 tidy4a % gather(1999, 2000, key = year, value = cases) (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 29 tidy4a # A tibble: 6 x 3 country year cases 1 Afghanistan 1999 745 2 Brazil 1999 37737 3 China 1999 212258 4 Afghanistan 2000 2666 5 Brazil 2000 80488 6 China 2000 213766 结果显示, 生成了两列新变量 year 与 cases。 类似地, 对于 table4b可进行同样的聚集操作: (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 30 tidy4b % gather(1999, 2000, key = year, value = population) tidy4b # A tibble: 6 x 3 country year population 1 Afghanistan 1999 19987071 2 Brazil 1999 172006362 3 China 1999 1272915272 4 Afghanistan 2000 20595360 5 Brazil 2000 174504898 6 China 2000 1280428583 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 31 最后,将 tidy4a 与 tidy4b 横向合并,得到完整的整洁数据: left_join(tidy4a, tidy4b) Joining, by = c(country, year) # A tibble: 6 x 4 country year cases population 1 Afghanistan 1999 745 19987071 2 Brazil 1999 37737 172006362 3 China 1999 212258 1272915272 4 Afghanistan 2000 2666 20595360 5 Brazil 2000 80488 174504898 6 China 2000 213766 1280428583 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 32 其中,函数 left_join()来自 dplyr 包,参见下节。 下面考察不整洁数据的另一情形,例如 table2 的形式: table2 # A tibble: 12 x 4 country year type count 1 Afghanistan 1999 cases 745 2 Afghanistan 1999 population 19987071 3 Afghanistan 2000 cases 2666 4 Afghanistan 2000 population 20595360 5 Brazil 1999 cases 37737 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 33 6 Brazil 1999 population 172006362 7 Brazil 2000 cases 80488 8 Brazil 2000 population 174504898 9 China 1999 cases 212258 10 China 1999 population 1272915272 11 China 2000 cases 213766 12 China 2000 population 1280428583 其中,table2 的问题在于每个观测值都占据了两行。 需要使用函数 spread(),将数据“展开”(spread),使得每个观测值仅占一行: (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 34 table2 % spread(key = type, value = count) # A tibble: 6 x 4 country year cases population 1 Afghanistan 1999 745 19987071 2 Afghanistan 2000 2666 20595360 3 Brazil 1999 37737 172006362 4 Brazil 2000 80488 174504898 5 China 1999 212258 1272915272 6 China 2000 213766 1280428583 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 35 函数 gather()与 spread()为互补运算。 函数 gather()使得宽的数据表格变得更窄、更长。 函数 spread()使得长的数据表格变得更短、更宽。 另外一种不整洁数据的情形是, 两个变量占用了同一列, 例如 table3: (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 36 table3 # A tibble: 6 x 3 country year rate * 1 Afghanistan 1999 745/19987071 2 Afghanistan 2000 2666/20595360 3 Brazil 1999 37737/172006362 4 Brazil 2000 80488/174504898 5 China 1999 212258/1272915272 6 China 2000 213766/1280428583 其中,变量 rate 其实包含了两个变量(cases 与 population)的信息。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 37 为此, 使用函数separate(), 将变量rate的信息进行 “分离” (separate): table3 % separate(rate, into = c(cases, population), convert = TRUE) # A tibble: 6 x 4 country year cases population 1 Afghanistan 1999 745 19987071 2 Afghanistan 2000 2666 20595360 3 Brazil 1999 37737 172006362 4 Brazil 2000 80488 174504898 5 China 1999 212258 1272915272 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 38 6 China 2000 213766 1280428583 其中, 参数 “convert = TRUE” 表示将所得变量 cases 与 population变为更合适的类型,即(表示整数);否则,将继承原来变量 rate的类型。 在上述命令中,并未指定在何处分割变量 rate。 函数 separate()默认在既非字母、 也非数字的字符处切割。 也可使用参数“sep=/”指定在“/”处进行分离。 还可指定分割的具体位置;比如将变量 year 在其第 2 个字符之后,切割为变量 century 与 year: (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 39 table5 % separate(year, into = c(century, year), sep = 2) table5 # A tibble: 6 x 4 country century year rate 1 Afghanistan 19 99 745/19987071 2 Afghanistan 20 00 2666/20595360 3 Brazil 19 99 37737/172006362 4 Brazil 20 00 80488/174504898 5 China 19 99 212258/1272915272 6 China 20 00 213766/1280428583 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 40 与函数 separate()相反的运算为 unite(),比如将 table5 的变量century 与 year 合二为一: table5 % unite(new, century, year,sep=) # A tibble: 6 x 3 country new rate 1 Afghanistan 1999 745/19987071 2 Afghanistan 2000 2666/20595360 3 Brazil 1999 37737/172006362 4 Brazil 2000 80488/174504898 5 China 1999 212258/1272915272 6 China 2000 213766/1280428583 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 41 其中,参数“sep=”表示在合并变量取值时,不加任何字符;默认加下划线“_” 。 18.5 数据变换数据变换 R 包 tidyverse 的 dplyr 包专门用于做数据变换, 包括选取观测值、排序、选变量、生成新变量、合并数据框等。 使用 R 包 nycflights13 的 flights 数据来演示。该数据包含 2013年从纽约出发(包括纽约的三个机场)的所有 336,776 次航班的信息,共 19个变量。 * 详见教材,以及配套 R 程序(现场演示) 。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 42 18.6 高阶画图高阶画图 完成数据清理与变换后, 即可进入 “知识创造” (knowledge generation)。 创造知识的一种直观方法为可视化,即通过画图展示数据中的信息。 R 包 tidyverse 包含一个精美的高阶画图包 ggplot2。 “gg”表示“画图语法”(grammar of graphics),它提供一套从底层构件出发的系统性画图方法。 与 R 语言的基础画图函数相比,ggplot2 的画图方式更为灵活,而画图结果更为精美。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 43 ggplot2 的画图方式与 Photoshop 之相似,也通过叠加“图层”(layers)来画图。 在理论上, 画图就是把数据集的变量以某种方式映射(mapping)到画布上。 这种映射可以指定把什么变量映射到 X 轴, 把什么变量映射到 Y 轴,映射到画布上的“几何对象”(geometric object)是什么,以及该几何对象的颜色、大小、形状、透明度等。 进一步,在不同的图层上,可以定义不同的映射。 最后,由多个图层综合成一幅图。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 44 以 ggplot2 自带的数据框 mpg 为例来演示。 该数据框包含美国环境保护局(Environmental Protection Agency)收集的不同车型之燃油效率(fuel efficiency)信息。 * 详见教材,以及配套 R 程序(现场演示) 。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 45 18.7 机器学习的统一接口机器学习的统一接口 是否存在任何情况下都最优秀的算法呢?答案是否定的。 如果不对数据生成过程(data generating process)作任何假设, 则无法预先(a priori)判断任意两个算法的相对优越性。 这就是机器学习中著名的无免费午餐定理 (No Free Lunch Theorem,简记 NFL),由 Wolpert(1996)与 Wolpert and Macready(1997)提出。 直观上,如果数据生成过程为线性,则最简单的线性模型也可能胜过复杂的非线性模型,故无法预判孰优孰劣。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 46 又比如,若真实的决策边界为矩形,则基于决策树的算法有望胜出。 针对具体数据与问题,究竟哪个算法最优,还须用数据来回答。 由于不同算法由不同研究者开发,所用命令格式不尽相同,故不便于流程化地比较这些算法的预测效果。 Kuhn(2008)开发了 R 包 caret, 为预测性建模提供统一的接口(a unified interface for predictive modeling),并使得模型训练过程更为流程化。 caret 表示“classification and regression training” 。 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 47 首先,安装并载入 R 包 caret: install.packages(caret) library(caret) 使用威斯康辛乳腺癌数据 wisc_bc_data.csv 进行演示 此数据包含 569 位病人的观测值, 以及与乳腺癌诊断(diagnosis)有关的 32 个变量(详见第 10 章)。 载入数据: (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 48 wbcd wbcd wbcd$diagnosis prop.table(table(wbcd$diagnosis) Benign Malignant 0.6274165 0.3725835 使用 caret 包的 createDataPartition()函数将样本随机分割为训练集与测试集: (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 49 set.seed(1) train_index train test prop.table(table(train$diagnosis) Benign Malignant 0.627193 0.372807 prop.table(table(test$diagnosis) Benign Malignant 0.6283186 0.3716814 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 51 响应变量 diagnosis 在训练集与测试集的分布比例几乎一样(细微差别由于观测值数目无法整除所致)。 定义对数据的预处理方式为“标准化”(standardization): preProc trControl metric # LOGIT set.seed(123) fit.glm # LDA set.seed(123) fit.lda # Naive Bayes set.seed(123) fit.nb # GLMNET (Penalized Logit) set.seed(123) fit.glmnet # KNN set.seed(123) fit.knn # CART set.seed(123) fit.cart # Bagged Trees set.seed(123) fit.bag # Random Forest set.seed(123) fit.rf # Gradient Boosting Machine set.seed(123) fit.gbm # SVM set.seed(123) fit.svm # Neural Network set.seed(123) fit.nnet results summary(results) Call: summary.resamples(object = results) Models: Logit, LDA, NB, GLMNET, KNN, CART, Bagging, RF, GBM, SVM, NNET Number of resamples: 30 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 67 Accuracy Min. 1st Qu. Median Mean 3rd Qu. Max. NAs Logit 0.8913043 0.9336957 0.9565217 0.9503543 0.9777778 1 0 LDA 0.8913043 0.9555556 0.9777778 0.9642834 0.9782609 1 0 NB 0.8478261 0.9130435 0.9555556 0.9408052 0.9565217 1 0 GLMNET 0.9555556 0.9777778 0.9782609 0.9824799 1.0000000 1 0 KNN 0.9130435 0.9565217 0.9780193 0.9730435 1.0000000 1 0 CART 0.8222222 0.9111111 0.9231884 0.9284541 0.9562802 1 0 Bagging 0.8695652 0.9336957 0.9451691 0.9489372 0.9777778 1 0 RF 0.9130435 0.9555556 0.9565217 0.9642190 0.9782609 1 0 GBM 0.9130435 0.9557971 0.9780193 0.9701771 1.0000000 1 0 SVM 0.9333333 0.9565217 0.9782609 0.9788245 1.0000000 1 0 NNET 0.9777778 0.9782609 0.9782609 0.9875684 1.0000000 1 0 (c) 2020,陈强,机器学习及 R 应用,高等教育出版社 68 Kappa Min. 1st Qu. Median Mean 3rd Qu. Max. NAs Logit 0.7638604 0.8551865 0.9066937 0.8938526 0.9521785 1 0 LDA 0.7516199 0.9032258 0.9521785 0.9211642 0.9527721 1 0 NB 0.6849315 0.8151951 0.9049140 0.8736074 0.9089109 1 0 GLMNET 0.9032258 0.9521785 0.9535894 0.9622810 1.0000000 1 0 KNN 0.8038380 0.9066937 0.9527721 0.9413197 1.0000000 1 0 CART 0.6463654 0.8115401 0.8392929 0.8485466 0.9070637 1 0 Bagging 0.7267327 0.8583162 0.8824746 0.8915437 0.9532710 1 0 RF 0.8038380 0.9043659 0.9066937 0.9228805 0.9537486 1 0 GBM 0.8038380 0.9043659 0.9524753