Excel formula 幂指数的多元线性回归

Excel formula 幂指数的多元线性回归,excel-formula,linear-regression,powerbi,dax,Excel Formula,Linear Regression,Powerbi,Dax,假设我有一组回报,我想计算它的贝塔值与不同的市场指数。为了有一个具体的例子,让我们在名为Returns的表中使用以下数据集: Date Equity Duration Credit Manager ----------------------------------------------- 01/31/2017 2.907% 0.226% 1.240% 1.78% 02/28/2017 2.513% 0.493% 1.120% 3.88%

假设我有一组回报,我想计算它的贝塔值与不同的市场指数。为了有一个具体的例子,让我们在名为
Returns
的表中使用以下数据集:

  Date       Equity  Duration  Credit  Manager
-----------------------------------------------
01/31/2017   2.907%   0.226%   1.240%   1.78%
02/28/2017   2.513%   0.493%   1.120%   3.88%
03/31/2017   1.346%  -0.046%  -0.250%   0.13%
04/30/2017   1.612%   0.695%   0.620%   1.04%
05/31/2017   2.209%   0.653%   0.480%   1.40%
06/30/2017   0.796%  -0.162%   0.350%   0.63%
07/31/2017   2.733%   0.167%   0.830%   2.06%
08/31/2017   0.401%   1.083%  -0.670%   0.29%
09/30/2017   1.880%  -0.857%   1.430%   2.04%
10/31/2017   2.151%  -0.121%   0.510%   2.33%
11/30/2017   2.020%  -0.137%  -0.020%   3.06%
12/31/2017   1.454%   0.309%   0.230%   1.28%
现在在Excel中,我可以使用
LINEST
函数来获取beta值:

= LINEST(Returns[Manager], Returns[[Equity]:[Credit]], TRUE, TRUE)
它会弹出一个如下所示的数组:

0.077250253 -0.184974002  0.961578127 -0.001063971
0.707796954  0.60202895   0.540811546  0.008257129
0.50202386   0.009166729  #N/A         #N/A
2.688342242  8            #N/A         #N/A
0.000677695  0.000672231  #N/A         #N/A
Beta位于最上面一行,使用它们可以得到以下线性估计:

Manager = 0.962 * Equity - 0.185 * Duration + 0.077 * Credit - 0.001
问题是如何使用DAX在Power BI中获得这些值(最好不用编写自定义R脚本)


对于一列,我可以回到数学定义,编写一个类似于中给出的最小二乘法实现


然而,当涉及到更多的列时(我需要能够处理多达12列,但不总是相同的数字),这会很快变得混乱,我希望有更好的方法。

因为Power BI中没有等效的或方便的替代品来替代
LINEST
函数(我相信你在发布问题之前已经做了足够的研究),任何尝试都意味着在powerquery/m中重写整个函数,对于简单线性回归来说,这已经不是那么“简单”,更不用说多个变量了

与(重新)发明轮子相比,在PowerBI中使用R脚本不可避免地要容易得多(一行代码..)

考虑到我之前没有R方面的经验,这是一个不错的选择。经过几次搜索和反复试验,我能够得出以下结论:

# 'dataset' holds the input data for this script
# install.packages("broom") # uncomment to install if package does not exist
library(broom)

model <- lm(Manager ~ Equity + Duration + Credit, dataset)
model <- tidy(model)

精髓:

DAX不是可行的方法。请使用
Home>Edit querys
,然后使用
Transform>Run R Script
。插入以下R代码片段,使用表中的所有可用变量运行回归分析:

model <- lm(Manager ~ . , dataset)
df<- data.frame(coef(model))
names(df)[names(df)=="coef.model."] <- "coefficients"
df['variables'] <- row.names(df)
从Power BI的零开始(出于再现性目的),我使用
Enter data
插入数据:

现在,转到
编辑查询>编辑查询
,并检查您是否有:

为了在分析中包含的列数方面保持灵活性,我发现最好删除日期列。这不会对回归结果产生影响。只需右键单击日期列并选择
删除

请注意,这将在
Query Settings>Applied Steps
>下添加一个新步骤:

在这里,您可以编辑我们将要使用的几行R代码。现在,转到
Transform>Run R Script
打开此窗口:

请注意,
#“dataset”行保存了此脚本的输入数据。
。谢天谢地,您的问题只涉及一个输入表,所以事情不会变得太复杂(对于多个输入表,请签出)。dataset变量是R中form data.frame的一个变量,是一个好的(唯一的..)进一步分析的起点

插入以下脚本:

model <- lm(Manager ~ . , dataset)
df<- data.frame(coef(model))
names(df)[names(df)=="coef.model."] <- "coefficients"
df['variables'] <- row.names(df)
模型关闭并应用
返回Power BI报告部分,确认您在
可视化>字段下有一个新表

插入表格或矩阵并激活系数和变量以获得:

我希望这就是你想要的


现在,有关R脚本的一些详细信息:

只要有可能,我将避免使用大量不同的R库。这样可以降低依赖性问题的风险


函数
lm()
处理回归分析。获得解释变量数量所需灵活性的关键在于
管理器~,数据集
部分。这只是说对数据框
数据集
中的
管理器
变量运行回归分析,并使用所有剩余列
~.
作为解释变量。
coef(模型)
part从估计的模型中提取系数值。结果是一个以变量名作为行名的数据框。最后一行只是将这些名称添加到数据框本身。

我已经知道了如何具体地对三个变量执行此操作,但这种方法根本不会放大或缩小到更多或更少的变量。

Regression = 
VAR ShortNames =
    SELECTCOLUMNS (
        Returns,
        "A", [Equity],
        "D", [Duration],
        "C", [Credit],
        "Y", [Manager]
    )
VAR n = COUNTROWS ( ShortNames )

VAR A = SUMX ( ShortNames, [A] )
VAR D = SUMX ( ShortNames, [D] )
VAR C = SUMX ( ShortNames, [C] )
VAR Y = SUMX ( ShortNames, [Y] )

VAR AA = SUMX ( ShortNames, [A] * [A] ) - A * A / n
VAR DD = SUMX ( ShortNames, [D] * [D] ) - D * D / n
VAR CC = SUMX ( ShortNames, [C] * [C] ) - C * C / n

VAR AD = SUMX ( ShortNames, [A] * [D] ) - A * D / n
VAR AC = SUMX ( ShortNames, [A] * [C] ) - A * C / n
VAR DC = SUMX ( ShortNames, [D] * [C] ) - D * C / n

VAR AY = SUMX ( ShortNames, [A] * [Y] ) - A * Y / n
VAR DY = SUMX ( ShortNames, [D] * [Y] ) - D * Y / n
VAR CY = SUMX ( ShortNames, [C] * [Y] ) - C * Y / n

VAR BetaA =
    DIVIDE (
        AY*DC*DC - AD*CY*DC - AY*CC*DD + AC*CY*DD + AD*CC*DY - AC*DC*DY,
        AD*CC*AD - AC*DC*AD - AD*AC*DC + AA*DC*DC + AC*AC*DD - AA*CC*DD
    )
VAR BetaD =
    DIVIDE (
        AY*CC*AD - AC*CY*AD - AY*AC*DC + AA*CY*DC + AC*AC*DY - AA*CC*DY,
        AD*CC*AD - AC*DC*AD - AD*AC*DC + AA*DC*DC + AC*AC*DD - AA*CC*DD
    )
VAR BetaC =
    DIVIDE (
      - AY*DC*AD + AD*CY*AD + AY*AC*DD - AA*CY*DD - AD*AC*DY + AA*DC*DY,
        AD*CC*AD - AC*DC*AD - AD*AC*DC + AA*DC*DC + AC*AC*DD - AA*CC*DD
    )
VAR Intercept =
    AVERAGEX ( ShortNames, [Y] )
        - AVERAGEX ( ShortNames, [A] ) * BetaA
        - AVERAGEX ( ShortNames, [D] ) * BetaD
        - AVERAGEX ( ShortNames, [C] ) * BetaC
RETURN
        { BetaA, BetaD, BetaC, Intercept }
这是一个计算表,返回指定的回归系数:

这些数字与LINEST提供的数据的输出相匹配

注:我在问题中引用的LINEST值与论文略有不同,因为它们是根据未舍入的回报而不是问题中提供的舍入回报计算的


我参考了计算设置和Mathematica来解决系统:


这看起来相当不错。理想情况下,R脚本可以响应报告页面上的切片器和过滤器(因为我无法合理地预计算我想要Beta的所有可能组合),但我认为此时不可能将R作为度量的一部分(这超出了我的问题范围)。对于Power BI中这些东西应该如何使用,我无法达成更多一致意见。但据我所知,我们还没有达到这一点。关于他们添加新功能的速度,我们可能不会持续很久,直到我们能够实现您所描述的。但现在,Power BI擅长的一件事是可视化其他地方所做分析的结果。当它出现时o预计算Beta如果你想看到结果,我建议你看看Python和statsmodels包。你会很快跟上速度。我认为R和Python比DAX更容易处理。因此,如果你能在Power BI中处理DAX,Python应该很容易。谷歌Anaconda并从那里开始。Spyder或VisualStudio应该作为一个优秀的入门级IDE来做这件事。然后你可以看看我最近发布的关于在ta子集上运行回归的内容
model <- lm(Manager ~ . , dataset)
df<- data.frame(coef(model))
names(df)[names(df)=="coef.model."] <- "coefficients"
df['variables'] <- row.names(df)
Regression = 
VAR ShortNames =
    SELECTCOLUMNS (
        Returns,
        "A", [Equity],
        "D", [Duration],
        "C", [Credit],
        "Y", [Manager]
    )
VAR n = COUNTROWS ( ShortNames )

VAR A = SUMX ( ShortNames, [A] )
VAR D = SUMX ( ShortNames, [D] )
VAR C = SUMX ( ShortNames, [C] )
VAR Y = SUMX ( ShortNames, [Y] )

VAR AA = SUMX ( ShortNames, [A] * [A] ) - A * A / n
VAR DD = SUMX ( ShortNames, [D] * [D] ) - D * D / n
VAR CC = SUMX ( ShortNames, [C] * [C] ) - C * C / n

VAR AD = SUMX ( ShortNames, [A] * [D] ) - A * D / n
VAR AC = SUMX ( ShortNames, [A] * [C] ) - A * C / n
VAR DC = SUMX ( ShortNames, [D] * [C] ) - D * C / n

VAR AY = SUMX ( ShortNames, [A] * [Y] ) - A * Y / n
VAR DY = SUMX ( ShortNames, [D] * [Y] ) - D * Y / n
VAR CY = SUMX ( ShortNames, [C] * [Y] ) - C * Y / n

VAR BetaA =
    DIVIDE (
        AY*DC*DC - AD*CY*DC - AY*CC*DD + AC*CY*DD + AD*CC*DY - AC*DC*DY,
        AD*CC*AD - AC*DC*AD - AD*AC*DC + AA*DC*DC + AC*AC*DD - AA*CC*DD
    )
VAR BetaD =
    DIVIDE (
        AY*CC*AD - AC*CY*AD - AY*AC*DC + AA*CY*DC + AC*AC*DY - AA*CC*DY,
        AD*CC*AD - AC*DC*AD - AD*AC*DC + AA*DC*DC + AC*AC*DD - AA*CC*DD
    )
VAR BetaC =
    DIVIDE (
      - AY*DC*AD + AD*CY*AD + AY*AC*DD - AA*CY*DD - AD*AC*DY + AA*DC*DY,
        AD*CC*AD - AC*DC*AD - AD*AC*DC + AA*DC*DC + AC*AC*DD - AA*CC*DD
    )
VAR Intercept =
    AVERAGEX ( ShortNames, [Y] )
        - AVERAGEX ( ShortNames, [A] ) * BetaA
        - AVERAGEX ( ShortNames, [D] ) * BetaD
        - AVERAGEX ( ShortNames, [C] ) * BetaC
RETURN
        { BetaA, BetaD, BetaC, Intercept }