《R的极客理想—工具篇》—— 1.8 caTools:一个奇特的工具集

简介:

本节书摘来自华章出版社《R的极客理想—工具篇》一 书中的第1章,第1.8节,作者:张丹,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

1.8 caTools:一个奇特的工具集

问题
R除了统计,还能干什么?
screenshot

引言
R语言生来就是自由的,不像Java和PHP等有统一的规范约束。R语言不仅命名、语法各包各异,就连功能也是各种混搭。caTools库就是这种混搭库,包括了不相关的几组函数工具集,有图片处理的,有编解码的,有分类器的,有向量计算的,有科学计算的,而且都很好用!以至于我都不知道如何用简短的语言去描述这个包了!唯有用“奇特”来概括它的特点。

1.8.1 caTools介绍

caTools是一个基础的工具包,包括移动窗口(Moving Window)统计,二进制图片读写,快速计算曲线的面积AUC,LogitBoost分类器,base64的编码器/解码器,快速计算舍入、误差、求和、累计求和等函数。下面分别介绍caTools包中的API。
(1)二进制图片读写
read.gif & write.gif: gif格式图片的读写。
read.ENVI & write.ENVI: ENVI格式图片的读写,如GIS图片。
(2)base64的编码器/解码器:
base64encode: 编码器。
base64decode: 解码器。
注 Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个位元为一个单元,对应某个可打印字符。
(3)快速计算曲线的面积AUC
colAUC: 计算ROC曲线的面积(AUC)。
combs: 向量元素的无序组合。
trapz: 数值积分形梯形法则。
(4)LogitBoost分类器
LogitBoost: logitBoost分类算法。
predict.LogitBoost: 预测logitBoost分类。
sample.split: 把数据切分成训练集和测试集。
(5)快速计算工具
runmad: 计算向量中位数。
runmean: 计算向量均值。
runmin & runmax: 计算向量最小值和最大值。
runquantile: 计算向量位数。
runsd: 计算向量标准差。
sumexact, cumsumexact: 无误差求和,针对编程语言关于double类型的精度优化。

1.8.2 caTools安装

本节使用的系统环境是:
Linux: Ubuntu Server 12.04.2 LTS 64bit
R: 3.0.1 x86_64-pc-linux-gnu
注 caTools同时支持Windows 7环境和Linux环境。
安装caTools包非常简单,只需要一条命令就可以完成。

~ R  # 启动R程序
> install.packages("caTools")  # 执行caTools安装命令

1.8.3 caTools使用

在R环境中,加载caTools类库:

> library(caTools)
  1. 二进制图片读写gif
    (1)写一个gif图片
> write.gif(volcano, "volcano.gif", col=terrain.colors, flip=TRUE, scale="always",
 comment="Maunga Whau Volcano")  #取datasets::volcano数据集,写入volcano.gif

(2)读一个gif图片到内存,再从内存输出

> y = read.gif("volcano.gif", verbose=TRUE, flip=TRUE)  #读入图片到变量y
GIF image header
Global colormap with 256 colors
Comment Extension
Image [61 x 87]: 3585 bytes
GIF Terminator

> attributes(y)  #查看变量的属性
$names
[1] "image"       "col"         "transparent"   "comment"
> class(y$image)  #查看图片存储矩阵
[1] "matrix"
> ncol(y$image)  #列数
[1] 61
> nrow(y$image)  #行数
[1] 87
> head(y$col,10)  #颜色表,取前10个
 [1] "#00A600FF" "#01A600FF" "#03A700FF" "#04A700FF" "#05A800FF" "#07A800FF" "#08A900FF"
 [8] "#09A900FF" "#0BAA00FF" "#0CAA00FF"
> y$comment  #查看图片备注
[1] "Maunga Whau Volcano"
> image(y$image, col=y$col, main=y$comment, asp=1)  #通过y变量画图,

如图1-19所示
(3)创建一个Git动画

> x <- y <- seq(-4*pi, 4*pi, len=200)
> r <- sqrt(outer(x^2, y^2, "+"))
> image = array(0, c(200, 200, 10))
> for(i in 1:10) image[,,i] = cos(r-(2*pi*i/10))/(r^.25)
> write.gif(image, "wave.gif", col="rainbow")
> y = read.gif("wave.gif")
> for(i in 1:10) image(y$image[,,i], col=y$col, breaks=(0:256)-0.5, asp=1)

在当前的操作目录,会生成一个 wave.gif 的文件,如图1-20所示。动画演示效果参见本书在线资源中的文件wave.gif。
screenshot

我们看到,caTools与谢益辉的animation包有一样的GIF输出动画功能。但使用caTools做gif动画,不需要依赖其他软件库。而animation的saveGIF函数需要依赖于ImageMagick或者GraphicsMagick等第三方软件。

  1. Base64的编码器/解码器

Base64常用于处理文本数据的场合,表示、传输、存储一些二进制数据,包括MIME的email、email via MIME、在XML中存储复杂数据。Base64的编码解码,只支持向量(vector)类型,不支持data.frame和list类型。把一个boolean向量编解码,代码如下:

> size=1  #设置每个元素占用的字节数
> x = (10*runif(10)>5)
> y = base64encode(x, size=size)
> z = base64decode(y, typeof(x), size=size)

> x  #原始数据
 [1] FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
> y  #编码后的密文
[1] "AAAAAAEBAAAAAA=="
> z  #解码后的明文
 [1] FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
把一个字符串编解码,代码如下:
> x = "Hello R!!" # character
> y = base64encode(x)
> z = base64decode(y, typeof(x))

> x  #原始数据
[1] "Hello R!!"
> y  #编码后的密文
[1] "SGVsbG8gUiEh"
> z  #解码后的明文
[1] "Hello R!!"
错误测试:把一个数据框编解码。
> data(iris)
> class(iris)
[1] "data.frame"

> head(x)  #原始数据
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

> base64encode(x)  #对数据框进行编码
Error in writeBin(x, raw(), size = size, endian = endian) :
  can only write vector objects
  1. ROC曲线
    ROC曲线就是接收者操作特征曲线(receiver operating characteristic curve)的简称,这是一种坐标图式的分析工具,主要用于选择最佳的信号侦测模型、舍弃次佳的模型和在同一模型中设定最佳阈值。ROC曲线首先由二战中的电子工程师和雷达工程师发明,用来侦测战场上的敌军载具(飞机、船舰等),即信号检测,之后很快就被引进心理学来进行信号的知觉检测。数十年来,ROC分析被用于医学、无线电、生物学、犯罪心理学等领域,而且最近在机器学习(machine learning)和数据挖掘(data mining)领域也得到了很好的发展。

取MASS::cats数据集,3列分别是Sex(性别)、Bwt(体重)、Hwt(心脏重量)。

> library(MASS)
> data(cats)  #加载数据集
> head(cats)  #打印前6行数据
  Sex Bwt Hwt
1   F 2.0 7.0
2   F 2.0 7.4
3   F 2.0 9.5
4   F 2.1 7.2
5   F 2.1 7.3
6   F 2.1 7.6
> colAUC(cats[,2:3], cats[,1], plotROC=TRUE)  #计算ROC的曲线面积AUC,输出图片,如图1-21所示
              Bwt      Hwt
F vs. M 0.8338451 0.759048

从AUC判断分类器(预测模型)优劣的标准:
AUC = 1,是完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。在绝大多数预测的场合,不存在完美分类器。
0.5 < AUC < 1,优于随机猜测。这个分类器(模型)如果妥善设定阈值的话,能有预测价值。
AUC = 0.5,跟随机猜测一样(例如丢硬币),模型没有预测价值。
AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。
从图1-21我们看到Bwt和Hwt都在(0.5,1)之间,因此,cats的数据集是一个真实有效数据集。如果cats的数据集,是一个通过分类预测的数据集,用AUC对数据集的评分,就可以检验分类器的好坏了。
screenshot

  1. 向量元素的无序组合
    combs(v,k)函数,用于创建无序的组合的矩阵,矩阵的列表示以几种元素进行组合,矩阵的行表示每种不同的组合。参数v是向量;k是数值,小于等于v的长度[1:length(v)]。
> combs(2:5, 3)
     [,1] [,2] [,3]
[1,]    2    3    4
[2,]    2    3    5
[3,]    2    4    5
[4,]    3    4    5

> combs(c("cats", "dogs", "mice"), 2)
     [,1]   [,2]
[1,] "cats" "dogs"
[2,] "cats" "mice"
[3,] "dogs" "mice"

> a = combs(1:4, 2)  #快速组合构建矩阵
> a
      [,1] [,2]
[1,]    1    2
[2,]    1    3
[3,]    1    4
[4,]    2    3
[5,]    2    4
[6,]    3    4
> b = matrix( c(1,1,1,2,2,3,2,3,4,3,4,4), 6, 2)
> b
     [,1] [,2]
[1,]    1    2
[2,]    1    3
[3,]    1    4
[4,]    2    3
[5,]    2    4
[6,]    3    4
  1. 数值积分梯形法则
    梯形法则原理:将被积函数近似为直线函数,被积的部分近似为梯形。
> x = (1:10)*pi/10
> trapz(x, sin(x))
[1] 1.934983

> x = (1:1000)*pi/1000
> trapz(x, sin(x))
[1] 1.999993
  1. LogitBoost分类器
    取datasets::iris数据集,5列分别是Sepal.Length(花萼长)、 Sepal.Width((花萼宽)、 Petal.Length(花瓣长)、Petal.Width(花瓣宽)、Species(种属)。
> head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

> Data = iris[,-5]
> Label = iris[, 5]
> model = LogitBoost(Data, Label, nIter=20)  #训练模型
> model  #模型数据
$Stump
      feature threshhold sign feature threshhold sign feature threshhold sign
 [1,]       3        1.9   -1       2        2.9   -1       4        1.6    1
 [2,]       4        0.6   -1       3        4.7   -1       3        4.8    1
 [3,]       3        1.9   -1       2        2.0   -1       4        1.7    1
 [4,]       4        0.6   -1       3        1.9    1       3        4.9    1
 [5,]       3        1.9   -1       4        1.6   -1       4        1.3    1
 [6,]       4        0.6   -1       1        6.5    1       2        2.6   -1
 [7,]       3        1.9   -1       3        1.9    1       4        1.7    1
 [8,]       4        0.6   -1       2        2.0   -1       2        3.0   -1
 [9,]       3        1.9   -1       3        5.0   -1       3        5.0    1
[10,]       4        0.6   -1       2        2.9    1       1        4.9   -1
[11,]       3        1.9   -1       3        1.9    1       3        4.4    1
[12,]       4        0.6   -1       2        2.0   -1       4        1.7    1
[13,]       3        1.9   -1       3        5.1   -1       2        3.1   -1
[14,]       4        0.6   -1       2        2.0   -1       3        5.1    1
[15,]       3        1.9   -1       3        1.9    1       1        6.5   -1
[16,]       4        0.6   -1       4        1.6   -1       3        5.1    1
[17,]       3        1.9   -1       2        3.1    1       2        3.1   -1
[18,]       4        0.6   -1       3        1.9    1       1        4.9   -1
[19,]       3        1.9   -1       2        2.0   -1       4        1.4    1
[20,]       4        0.6   -1       3        5.1   -1       2        2.2   -1

$lablist
[1] setosa     versicolor virginica
Levels: setosa versicolor virginica

attr(,"class")
[1] "LogitBoost"

> Lab = predict(model, Data)  #分类预测,Lab只显示分类的结果, Prob显示各分类的概率
> Prob = predict(model, Data, type="raw")
> t = cbind(Lab, Prob)  #结果合并,打印前6列
> head(t)
     Lab setosa  versicolor    virginica
[1,]   1      1 0.017986210 1.522998e-08
[2,]   1      1 0.002472623 3.353501e-04
[3,]   1      1 0.017986210 8.315280e-07
[4,]   1      1 0.002472623 4.539787e-05
[5,]   1      1 0.017986210 1.522998e-08
[6,]   1      1 0.017986210 1.522998e-08

前6条数据,Lab列表示数据属于分类1,即setosa。其他3列setosa、versicolor、virginica,分类表示属于该分类的概率是多少。下面设置迭代次数,比较分类结果与实际数据结果。

> table(predict(model, Data, nIter= 2), Label)  #设置迭代次数为2
            Label
             setosa versicolor virginica
  setosa         48          0         0
  versicolor      0         45         1
  virginica       0          3        45

> table(predict(model, Data, nIter=10), Label)  #设置迭代次数为10
            Label
             setosa versicolor virginica
  setosa         50          0         0
  versicolor      0         47         0
  virginica       0          1        47

> table(predict(model, Data), Label)    #默认迭代次数, 训练时LogitBoost的nIter值
            Label
             setosa versicolor virginica
  setosa         50          0         0
  versicolor      0         49         0
  virginica       0          0        48

从上面3次测试结果可以看出,迭代次数越多模型分类越准确。下面随机划分训练集和测试集,并分类预测。

> mask = sample.split(Label)  #随机取训练集
> length(which(mask))  #训练集99条记录
[1] 99
> length(which(!mask))  #测试集51条记录
[1] 51
> model = LogitBoost(Data[mask,], Label[mask], nIter=10)  #训练模型
> table(predict(model, Data[!mask,], nIter=2), Label[!mask])  #分类预测
             setosa versicolor virginica
  setosa         16          0         0
  versicolor      0         15         3
  virginica       0          1        12

> table(predict(model, Data[!mask,]), Label[!mask])
             setosa versicolor virginica
  setosa         17          0         0
  versicolor      0         16         4
  virginica       0          1        13
  1. 快速计算工具runmean
    均线在股票交易上非常流行,是一种简单、实用的看盘指标。下面我们对时间序列数据取均线,输出结果如图1-22所示。
> BJsales  #取datasets::BJsales数据集
Time Series:
Start = 1
End = 150
Frequency = 1
  [1] 200.1 199.5 199.4 198.9 199.0 200.2 198.6 200.0 200.3 201.2 201.6 201.5
 [13] 201.5 203.5 204.9 207.1 210.5 210.5 209.8 208.8 209.5 213.2 213.7 215.1
 [25] 218.7 219.8 220.5 223.8 222.8 223.8 221.7 222.3 220.8 219.4 220.1 220.6
> plot(BJsales,col="black", lty=1,lwd=1, main = "Moving Window Means")
> lines(runmean(BJsales, 3), col="red", lty=2, lwd=2)
> lines(runmean(BJsales, 8), col="green", lty=3, lwd=2)
> lines(runmean(BJsales,15), col="blue", lty=4, lwd=2)
> lines(runmean(BJsales,24), col="magenta", lty=5, lwd=2)
> lines(runmean(BJsales,50), col="cyan", lty=6, lwd=2)

screenshot

我们从图1-22中看到6条线, 黑色是原始数据,其他各种颜色线代表不同单位的均线。比如,红色(red)线表示3个点的平均,绿色(green)线表示8个点的平均。

  1. 快速计算工具组合
    对数据集取最大路径(runmax)、最小路径(runmin)、均值路径(runmean)和中位数路径(runmed),输出结果如图1-23所示。
> n=200;k=25
> set.seed(100)
> x = rnorm(n,sd=30) + abs(seq(n)-n/4)
> plot(x, main = "Moving Window Analysis Functions (window size=25)")
> lines(runmin (x,k), col="red",lty=1, lwd=1)
> lines(runmax (x,k), col="cyan",lty=1, lwd=1)
> lines(runmean(x,k), col="blue",lty=1, lwd=1)
> lines(runmed (x,k), col="green",lty=2, lwd=2)

screenshot

  1. 无误差求和
    各种编程语言,用计算机做小数计算的时候,都会出现计算误差的情况,R语言也有这个问题。首先用sum()函数求和。
> x = c(1, 1e20, 1e40, -1e40, -1e20, -1)  #计算误差求和
> a = sum(x); print(a)
[1] -1e+20
> b = sumexact(x); print(b)  #无计算误差求和
[1] 0

我们对向量x求和,各组值加起来正好为0。但是sum()函数,结果是-1e+20,这是由于编程精度的问题造成的计算误差。通过sumexact()函数修正后,就没有误差了。下面用cumsum()函数累积求和。

> a = cumsum(x); print(a)  #计算误差累积求和
[1]  1e+00  1e+20  1e+40  0e+00 -1e+20 -1e+20
> b = cumsumexact(x); print(b)  #无计算误差累积求和
[1] 1e+00 1e+20 1e+40 1e+20 1e+00 0e+00

cumsum()函数同样出现了精度的误差,需要用cumsumexact()函数来修正。
最后还是要用“奇特”来概括这个工具集,相信你也发现了它的奇特。

相关文章
|
域名解析 网络协议 Linux
【Shell 命令集合 网络通讯 】Linux 设置和管理网络接口配置信息 netconfig命令 使用指南
【Shell 命令集合 网络通讯 】Linux 设置和管理网络接口配置信息 netconfig命令 使用指南
784 1
|
8月前
|
机器学习/深度学习 数据采集 算法
【风电功率预测】【多变量输入单步预测】基于RVM-Adaboost的风电功率预测研究(Matlab代码实现)
【风电功率预测】【多变量输入单步预测】基于RVM-Adaboost的风电功率预测研究(Matlab代码实现)
408 129
|
人工智能
《AI助力生物学:基因编辑与蛋白质结构解析的加速引擎》
在生物学研究中,AI正发挥重要作用,特别是在基因编辑和蛋白质结构解析方面。AI通过设计新型基因编辑工具(如OpenCRISPR™)、提高编辑效率与精准度(如EVOLVEpro),以及优化整个编辑过程,显著加速了基因编辑的研究进展。在蛋白质结构解析领域,AI技术如AlphaFold实现了精准预测蛋白质三维结构,加速了蛋白质设计与改造,并解析蛋白质相互作用网络。这不仅推动了医学和农业领域的发展,也带来了伦理和法律等挑战,需要确保其健康、可持续发展。
626 11
|
JavaScript 前端开发 API
什么是声明式UI什么是命令式UI?鸿蒙ArkTS为什么是声明式UI-优雅草卓伊凡
什么是声明式UI什么是命令式UI?鸿蒙ArkTS为什么是声明式UI-优雅草卓伊凡
361 12
什么是声明式UI什么是命令式UI?鸿蒙ArkTS为什么是声明式UI-优雅草卓伊凡
|
传感器 安全 物联网
Gateway基本配置:打开网络之门
Gateway基本配置:打开网络之门
|
机器学习/深度学习 人工智能 供应链
智能制造:AI驱动的生产革命——探索生产线优化、质量控制与供应链管理的新纪元
【7月更文第19天】随着第四次工业革命的浪潮席卷全球,人工智能(AI)正逐步成为推动制造业转型升级的核心力量。从生产线的智能化改造到质量控制的精密化管理,再到供应链的全局优化,AI技术以其强大的数据处理能力和深度学习算法,为企业开启了全新的生产效率和质量标准。本文将深入探讨AI在智能制造中的三大关键领域——生产线优化、质量控制、供应链管理中的应用与影响,并通过具体案例和代码示例加以阐述。
1816 3
|
图形学
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
839 0
|
存储 缓存 算法框架/工具
Transformers 4.37 中文文档(十三)(9)
Transformers 4.37 中文文档(十三)
258 1
|
存储 编解码 开发工具
拉取RTSP流后的几个去向探讨(播放|转RTMP|轻量级RTSP服务|本地录制|GB28181)
本文汇总了大牛直播SDK在Android平台上拉取RTSP流后的多种应用方向,包括本地播放、转推至RTMP服务器、轻量级RTSP服务、GB28181平台及录像等功能。提供了详细的实现方法与示例代码,旨在帮助开发者高效利用RTSP流数据,实现低延迟、稳定且灵活的应用场景。
736 1
|
人工智能 安全 搜索推荐
1.8B参数,阿里云首个联合DNA、RNA、蛋白质的生物大模型,涵盖16.9W物种
【6月更文挑战第14天】阿里云发布首个集成DNA、RNA和蛋白质数据的生物大模型LucaOne,拥有1.8B参数,涉及16.9万物种。LucaOne通过few-shot learning技术和streamlined downstream architecture实现多生物语言统一处理,提升生物系统理解与分析能力。该模型将加速生物信息学研究,推动生物医学应用,但同时也引发生物数据安全、预测偏差及AI伦理法律等问题的讨论。[论文链接](https://www.biorxiv.org/content/10.1101/2024.05.10.592927v1)
1163 3