如何解决使用Haskell'statistics'软件包进行线性回归
我需要对一组测量数据进行线性回归。我知道statistics是工作的去库。 ols
模块中Statistics.Regression
函数的描述表明这就是我需要的东西。但是,从文档中尚不清楚如何表示我的测量数据,例如
measurements = [(1.0,2.0),(2.0,2.5),(3.0,3.0)] :: [(Double,Double)] -- (X,Y) coordinates of points
签名的功能
ols :: Matrix -- A has at least as many rows as columns.
-> Vector -- b has the same length as columns in A.
-> Vector
以及如何解释结果。
我期望得到方程a = 1.5
的值b = 0.5
和y = a + bx
。
如何构造输入Matrix
和Vector
,以及生成的Vector
中会有什么?
解决方法
以某种方式期望统计库提供某种通用性的功能,因此,如果您只想了解简单的情况,则必须缩小提供的功能。在这里,库函数需要几个因果变量,而不只是一个。此外,它使用向量和矩阵,您可能只需要简单列表。
要显示如何使用具有单个因果变量的库,我将假定您只需要一个使用普通Haskell数据类型的接口,如下所示:
-- [(x0,y0),(x1,y1),(x2,y2) ... ] -> ((a,b),r2) for y ≃ a + b*x
simpleRegression1 :: [(Double,Double)] -> ((Double,Double),Double)
使用olsRegress
比ols
似乎更容易,因为:
- 不需要Matrix数据类型
- 您可以轻松获得y截距值(在符号中为 a )
- 您还可以从同一次通话中获得拟合优度系数
代码可以编写如下:
import qualified Data.List as L
import qualified Data.Vector.Unboxed as DVU
import qualified Statistics.Regression as SR
-- [(x0,Double)
simpleRegression1 xyPairs =
let xList = L.map fst xyPairs
yList = L.map snd xyPairs
xVecList = [DVU.fromList xList]
yVec = DVU.fromList yList
(sv,r2) = SR.olsRegress xVecList yVec
[b,a] = DVU.toList sv
in
((a,r2)
在我们的例子中,只有一个列向量,所以xVecList
只有一个元素。
如olsRegress documentation中所述,y截距“ a”值是输出矢量的最后一个元素。
测试代码:
main = do
let measurements = [(1.0,1.9999),(2.0,2.5001),(3.0,2.9999)]
---- measurements = [(1.0,2.0),2.5),3.0)]
((a,r2) = simpleRegression1 measurements
putStrLn $ "measurements = " ++ (show measurements)
putStrLn $ "a = " ++ (show a) ++ " b = " ++ (show b) ++
" r2 = " ++ (show r2)
let ypList = L.map (\x -> a+b*x) (L.map fst measurements)
diffList = L.zipWith (-) (L.map snd measurements) ypList
putStrLn $ "ypList = " ++ (show ypList)
putStrLn $ "diffList = " ++ (show diffList)
测试输出:
measurements = [(1.0,2.9999)]
a = 1.4999666666666656 b = 0.5000000000000006 r2 = 0.9999999466666695
ypList = [1.999966666666666,2.4999666666666664,2.9999666666666673]
diffList = [-6.666666666599319e-5,1.3333333333376274e-4,-6.66666666675475e-5]
请注意,还有一个LinearRegression module。
,在概念上,让我重写ols
的签名以反映其实际完成的工作:
ols :: (VectorSpace u,VectorSpace v) => (u +> v) -> v -> u
其中+>
表示linear function,这就是矩阵表示的含义。
因此,u
是您想要的结果(即参数a
和b
)。矩阵自变量是将这些参数映射到实际测量预测的(线性)函数。因此,这涉及在数据集中每个 x 位置计算 a·x + b 。
在一个更受数学启发(而不是Matlab或R启发)的库中,您可以大致以这种方式编写它:
m :: Matrix
m = fromFunction $ \(a,b) -> fmap (\x -> a*x + b) [1,2,3])
然后类型v
的测量向量就是您在输出中拥有的y
值,因此您可以进行评估
ols m [2,2.5,3]
实际上,在linearmap-category
中-与statistics
一样,它的键入正确-您几乎可以完全按照以下方式进行操作:
> :m +Math.LinearMap.Category
> import Linear (V2(..),V3(..))
> lfun (\(V2 a b) -> fmap (\x -> a*x + b) (V3 1 2 3)) \$ V3 2 2.5 3
V2 0.4999999999999998 1.5000000000000018
我怀疑在statisics
中,您需要根据线性函数构建矩阵。这有点古怪,但并不困难:建立矩阵意味着简单地放入可能的基础输入(1,0)
和(0,1)
,为它们评估函数(即一次对a=1
,{{1} },然后一次用于b=0
,a=0
),并将所有b=1
向下的结果记为列向量。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。