线性最小二乘拟合

时间:2012-09-04 20:51:03

标签: r linear-regression least-squares lm

DF

 times a   b   s  ex  
1   0 59 140 1e-4  1
2  20 59 140 1e-4  0 
3  40 59 140 1e-4  0
4  60 59 140 1e-4  2
5 120 59 140 1e-4 20
6 180 59 140 1e-4 30
7 240 59 140 1e-4 31
8 360 59 140 1e-4 37
9   0 60 140 1e-4  0
10 20 60 140 1e-4  0
11 40 60 140 1e-4  0
12 60 60 140 1e-4  0
13 120 60 140 1e-4 3300
14 180 60 140 1e-4 6600
15 240 60 140 1e-4 7700
16 360 60 140 1e-4 7700
# dput(DF) 
structure(list(times = c(0, 20, 40, 60, 120, 180, 240, 360, 0, 
20, 40, 60, 120, 180, 240, 360), a = c(59, 59, 59, 59, 59, 59, 
59, 59, 60, 60, 60, 60, 60, 60, 60, 60), b = c(140, 140, 140, 
140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140
), s = c(1e-04, 1e-04, 1e-04, 1e-04, 1e-04, 1e-04, 1e-04, 1e-04, 
1e-04, 1e-04, 1e-04, 1e-04, 1e-04, 1e-04, 1e-04, 1e-04), ex = c(1, 
0, 0, 2, 20, 30, 31, 37, 0, 0, 0, 0, 3300, 6600, 7700, 7700)), .Names = c("times", 
"a", "b", "s", "ex"), row.names = c(NA, 16L), class = "data.frame")

DF2

prime    times       mean     
 g1          0  1.0000000 
 g1         20  0.7202642 
 g1         40  0.8000305 
 g1         60  1.7430986 
 g1        120 16.5172242 
 g1        180 25.6521268         
 g1        240 33.9140056 
 g1        360 34.5735984 
 #dput(DF2)
 structure(list(times = c(0, 20, 40, 60, 120, 180, 240, 360), 
mean = c(1, 0.7202642, 0.8000305, 1.7430986, 16.5172242, 
25.6521268, 33.9140056, 34.5735984)), .Names = c("times", 
"mean"), row.names = c(NA, -8L), class = "data.frame")

DF是更大数据框架的一个例子,它实际上有数百种'a','b'和's'值的组合,这些组合导致不同的'ex'值。我想要做的是找到'a','b'和's'的组合,其'ex'值(DF)最适合'等于'时间'的'均值'值(DF2)。 这个拟合将是一次比较8个值(即,时间== c(0,20,40,60,120,180,240,360)。

在这个例子中,我希望59,140和1e-4代表'a','b'和's'值,因为那些'ex'值(DF)最符合'mean'值(DF2)。

我希望那些'ex'(DF)最适合''的''','b'和's'值'(DF2)

由于我想要'a','b'和's'值的一种可能组合,因此线性最小二乘拟合模型将是最佳的。我会一次比较8个值 - 其中'times'== 0 - 360。 我不希望'a','b'和's'值最适合每个时间点。我想要'a','b'和's'值,其中所有8'ex'(DF)最适合所有8'平均'值(DF2) 这是我需要帮助的地方。

我从未使用过线性最小二乘拟合,但我认为我正在尝试做的事情是可能的。

      lm(DF2$mean ~ DF$ex,....) # i'm not sure if I should combine the two 
      # data frames first then use that as my data argument, then 
      # where I would include 'times' as the point of comparison, 
      # if that would be used in subset?   

1 个答案:

答案 0 :(得分:1)

这听起来像线性模型不是你需要的。在最好的情况下,线性模型将为您提供不同a/b/s配置的线性组合,而不是单个最佳匹配组合。因此,该名称中的术语线性

我认为您可以保证times的{​​{1}}值与DF的{​​{1}}值相匹配。第一步可能是将times转换为数据框,其中每个DF2组合只有一行,并且不同的DF值存储为矩阵的列。然后,对于每一行,您需要从a/b/s值中减去ex值,对这些差异求平方,并将它们相加,以计算该行的单个平方误差。然后只需选择具有最小值的行。

上述解决方案非常模糊。有一百万种方法可以实际实现这一点,而不是复制我的解决方案,你可能最好自己编写它们,以你最了解它们的方式。一些提示如何实现各个步骤:

  • ex可以计算矩阵
  • DF2$mean将提供与每个矩阵行相对应的matrix(DF$ex, byrow=TRUE, ncol=8)
  • DF[seq(from=1, to=nrow(DF), by=8),2:4]可用于合并这两个
  • a/b/s会将这些方法转换为矩阵,您可以简单地减去
  • cbind会对矩阵的所有组成部分进行平方
  • matrix(DF2$mean, byrow=TRUE, ncol=8, nrow=nrow(DF)/8)将添加矩阵行的元素
  • **2将返回最小值的索引

以一种可能的方式将所有内容放在一起,将所有内容放在一个表达式中而不使用中间变量(不是最易读的解决方案):

rowSums

如果不将矩阵存储为数据框的一部分,则可能需要对其进行转置以避免使用which.min个参数,并利用每个列重复向量的事实< / em>在矩阵向量减法中:

DF[seq(from=1, to=nrow(DF), by=8),2:4][which.min(
  rowSums((matrix(DF$ex, byrow=TRUE, ncol=8) -
           matrix(DF2$mean, byrow=TRUE, ncol=8, nrow=nrow(DF)/8)
          )**2
         )
),]