机器学习第4章第3节 : R语言计算实例

来源:互联网 发布:软件测试做什么 编辑:程序博客网 时间:2024/06/05 07:20

机器学习第4章第3节 : R语言计算实例

  • 机器学习第4章第3节 R语言计算实例
    • 学生数据集读写
      • list方法
      • dataframe方法
    • 最小二乘法拟合
      • 最小二乘法与回归
      • 最小二乘法拟合
    • 交叉因子频率分析
    • 向量模长计算
      • 模长函数定义
      • 模长计算
    • 欧式距离计算

学生数据集读写

list方法

R语言可以使用list(列表)组件创建与读写学生数据,该组件通常用来容纳一个数据集其中包含不同的数据类型.

  • 创建学生数据集(语法:list(字段1 = 组件1 , 字段2 = 组件2,......)),学生数据集由3个不同的类型的数据组成: name,class,ages,代码如下:
list(name = "student",class = "101",students.ages = c(22,25,20),students.name = c("zhangsan","lisi","wangwu"))  -> mystudents
  • 读取列表,去读刚才创建的学生数据集,代码如下:
mystudents

执行结果:

> mystudents$name[1] "student"$class[1] "101"$students.ages[1] 2225   20$students.name[1] "zhangsan" "lisi"     "wangwu"  
  • 获取学生数据集的字段总数(通过length返回list组件的数量),代码如下:
length(mystudents)

执行结果:

> length(mystudents)[1] 4
  • 查看数据集中所有学生的姓名和年龄(通过”列表变量名$字段名“提取组件内容)代码如下:
c(mystudents$students.name , mystudents$students.ages)

执行结果:

> c(mystudents$students.name , mystudents$students.ages)[1] "zhangsan" "lisi"     "wangwu"   "22"       "25"       "20"  

data.frame方法

此外,R语言还提供了一个很不错的list组件data.frame,它内部可拥有很多组件.

  • 创建data.frame组件存储学生数据,代码如下:
data.frame(name = mystudents$students.name , age = mystudents$students.ages) -> mysts
  • 将数据集中的年龄都增长1岁(类似于新的一年大家都长大了一岁),可使用attachdetach方法

前面一直在使用$符号访问list里面的内容,当R语言的代码较多时,列表组件名前缀访问字段很不方便,因此,R语言提供了另一对非常有用的工具attachdetach.

attach是把数据集的所有字段复制一份副本绑定在所有路径,这样可以直接读取它们(仅仅是读取,写是写在副本上的,写在副本上是没有意义的),无需显示表明列表名字

detach是解绑.


用attach将学生数据集的字段副本绑定在所有路径中,代码如下:

attach(mysts)agename

执行结果:

> attach(mysts)> age[1] 22 25 20> name[1] zhangsan lisi     wangwu  Levels: lisi wangwu zhangsan> 

将绑定的age字段副本加1,并显示更新后的学生数据,代码如下:

age+1 -> mysts$agemysts

执行结果:

> age+1 -> mysts$age> mysts      name age1 zhangsan  232     lisi  263   wangwu  21

使用detach将字段副本从搜索路径上删除(解绑),代码如下:

detach(mysts)agename

执行结果:

> detach(mysts)> age错误: 找不到对象'age'> name错误: 找不到对象'name'

最小二乘法拟合

最小二乘法与回归

最小二乘法是一种数学优化技术,它通过最小化误差的平方和找到一组数据的最佳函数匹配.

假设存在(x,y)两个变量,对于一系列的x变量值,有一系列的y值与其对应,可以找到这两个变量之间的相互关系.比如,对于一次函数来说,可将这些(x,y)值标注在直角坐标系统,从而得到一条直线,这些点就在这条直线附近,那么,直线返程的定义为:

y=kx+b

其中,k和b是任意实数,k为斜率,b为截距.

我们以y=3x+12y=6x+12为例进行分析.如下图

函数图

从上图我们可以很直观的看出,斜率越大,直线越陡(蓝线k值为6,黄线k值为3,蓝线比黄线陡),无论哪条线,对于每一个x,都有一个y值都相对应,比如,当x为1.5时,我们想要求黄线上的坐标,可直接将x=1.5代入y=3x+12就可以得到:

y=3 x 1.5 + 12 = 16.5

这样我们就可以使用 y=kx+b形式的一次方程拟合数据点,这个过程称为线性拟合,拟合的目标是这些点到这条直线的距离的平方和最小(比如刚才的(x=1.5,y=16.5),它到直线y=3x+12的距离的平方和为0,达到了最小).最小二乘法是效果较好的线性拟合的方法,最小二乘法拟合数据点的的过程就是对数据做回归分析,我们把类似上图的几条直线称为回归线

最小二乘法拟合

R语言提供了lsift函数,可完成小二乘法拟合,其主要参数如下:

x y Wt Intercept Tolerance Yname 一个矩阵的行对应的情况和其列对应为变量 结果,可以是一个矩阵 可选参数,加权最小二乘法的执行权重向量 是否使用截距项 公差将用于矩阵分解 用于响应变量的名称

我们来看看y=2x回归方程拟合,这里以x=(1,2,3,4),y=(2,4,6,8)为例在R中进行数据拟合,代码如下:

x <- c(1,2,3,4)y <- c(2,4,6,8)lsfit(x,y) #下面的执行结果中x为常数项,Intercept为截距

执行结果:

> x <- c(1,2,3,4)> y <- c(2,4,6,8)> lsfit(x,y) #下面的执行结果中x为常数项,Intercept为截距$coefficientsIntercept         X         0         2 #----------------------------##.....删去了不必要的的结果代码.....#

在上面的拟合结果中,Intercept代表截距,x表示方程的x变量的常数项,因此,回归方程为y=2x+0=2x


再看看y=2x+3的回归方程拟合,设截距为3,修改刚才的方程,假设回归线为: y=2x+3

根据回归线构造x和y,执行lsfit()函数进行拟合,代码如下:

x <- c(1,2,3,4)y <- c(5,7,9,11)lsfit(x,y)

执行结果:

> x <- c(1,2,3,4)> y <- c(5,7,9,11)> lsfit(x,y)$coefficientsIntercept         X         3         2#----------------------------##.....删去了不必要的的结果代码.....#

根据结果,这些数据点的回归方程为y=2x+3

交叉因子频率分析

交叉因子频率分析的作用在于分析数据的分布区间及其统计指标.

  • 划分数据分布区间.使用cut()函数将变量y中存储的数字划分到5个分布区间,代码如下:
y <- c(11,22,13,14,11,22,31,31,31,14)cuty <- cut(y,5)cuty

执行结果:

> y <- c(11,22,13,14,11,22,31,31,31,14)> cuty <- cut(y,5)> cuty [1] (11,15] (19,23] (11,15] (11,15] (11,15] (19,23] (27,31] (27,31] (27,31] (11,15]Levels: (11,15] (15,19] (19,23] (23,27] (27,31]
  • 使用table函数统计数据再每个区间出现的频率,代码如下:
table(cuty)

执行结果:

> table(cuty)cuty(11,15] (15,19] (19,23] (23,27] (27,31]       5       0       2       0       3 
  • 使用hist函数生成分布直方图,以便更直观的观察数据分布情况.通过指定breaks参数(设置为各区间的边界值)和axes参数(设置为FALSE表示手动画刻度),将数据再table函数生成的区间内进行划分,代码如下:
bins <- seq(min(y),max(y),by=4)hist(y,breaks=bins,col="lightblue",axes=FALSE)axis(1,bins)axis(2)

如果没有弹出图形界面,就在R界面中选择窗口-2 R Graphics:Device:2 (ACTIVE),结果如下图:

window2

hist

结合table函数执行的结果以及hist函数 生成的直方图,可以都得到以下结论:

分析table函数的执行结果可以看出,数据主要都击中在[11,15]的区间中,[11,15]的区间内分布的数字最多,该区间有5个数字.此外在[15,19]和[23,27]区间中没有数据分布,变量y在这两个区间内出现的频率为0.

从上图可以看到,数据分布情况与table函数的执行结果相吻合.

向量模长计算

向量模长即欧几里得范数,在n 维欧几里得空间Rn上,向量vx的长度定义为lenxv.

根据勾股定理,它给出了原点到点x之间的距离.

模长函数定义

R拥有自定义函数功能可按如下格式定义:

yourFunctionName <- function(parameter1,parameter2,parameter3,......,parameterN){    #your code#}

下面定义一个三维向量模长的vector_length函数,完成模长计算

vector_length <- function(x1,x2,x3){    vlength <- sqrt(x1^2 + x2^2 + x3^2)    vlength}

模长计算

调用vector_length函数,计算向量[12,22,19]的模长

vector_length(12,33,19)

执行结果:

> vector_length(12,33,19)[1] 39.92493


N维向量的模长与三维模长类似,我们重新定义 vector_length函数,并调用它计算任意维度向量的模长,代码如下:

# 定义vector_length函数vector_length <- function(x){    temp <- 0    for (i in 1:length(x)){        temp <- temp + x[i]^2    }    vlength <- sqrt(temp)    vlength #打印出结果}# 调用vector_length计算任意维度的向量模长vector_length(c(11,22,33,44,55))vector_length(c(11,22,33,44,55,66,77,88,99))

执行结果

> # 定义vector_length函数> vector_length <- function(x){+ temp <- 0+ for (i in 1:length(x)){+ temp <- temp + x[i]^2+ }+ vlength <- sqrt(temp)+ vlength #打印出结果+ }> > # 调用vector_length计算任意维度的向量模长> vector_length(c(11,22,33,44,55))[1] 81.57818> vector_length(c(11,22,33,44,55,66,77,88,99))[1] 185.7014

欧式距离计算

欧氏距离(Edclid Distance)是在n维空间中两个点的真实距离.n维欧式空间的每个点都可以表示为(x[1],x[2],x[3],……,x[n]), X=(x[1],x[2],x[3],……,x[n])和Y=(y[1],y[2],y[3],……,y[n]),这两个点之间的距离d(X,Y)定义为以下公式:

distance

利用R语言的操作符自定义功能完成欧式距离计算,操作符的定义使用%符号%的方式定义实际使用时,%特属于操作符的一部分,操作符的定义格式如下:

操作符名 <- function(参数1,参数2,参数3,......,参数n){    语句}

下面定义%~%操作符,并计算二维空间的欧氏距离,代码如下:

"%~%" <- function(x1,x2){    temp <- 0    for(i in 1:length(x1)){        temp <- (x1[i] - x2[i])^2    }    edis <- sqrt(temp)    edis}#使用%~%操作符,计算二维空间的欧式距离c(1,2,3) %~% c(4,5,6)

计算结果:

> "%~%" <- function(x1,x2){+ temp <- 0+ for(i in 1:length(x1)){+ temp <- (x1[i] - x2[i])^2+ }+ edis <- sqrt(temp)+ edis+ }> > #使用%~%操作符,计算二维空间的欧式距离> c(1,2,3) %~% c(4,5,6)[1] 3

可以将计算扩展到n维空间中.使用R语言的不定数量参数的机制,来定义n维空间的欧式距离函数mycount,代码如下:

mycount <- function(...){    temp <- 0    for (i in c(...)){        temp = temp +1    }    temp}mycount(11,22,33)mycount(22,33,44,55)mycount(11,55,99)

执行结果:

> mycount <- function(...){+ temp <- 0+ for (i in c(...)){+ temp = temp +1+ }+ temp+ }> > mycount(11,22,33)[1] 3> mycount(22,33,44,55)[1] 4> mycount(11,55,99)[1] 3
原创粉丝点击