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

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

学生数据集读写

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)
age
name

执行结果:

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

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

age+1 -> mysts$age
mysts

执行结果:

> age+1 -> mysts$age
> mysts
      name age
1 zhangsan  23
2     lisi  26
3   wangwu  21

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

detach(mysts)
age
name

执行结果:

> 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函数,可完成小二乘法拟合,其主要参数如下:

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

我们来看看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为截距
$coefficients
Intercept         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)
$coefficients
Intercept         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
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值