Множественная линейная регрессия в Power BI

Предположим, у меня есть набор доходностей, и я хочу вычислить его бета-значения по сравнению с различными рыночными индексами. Давайте использовать следующий набор данных в таблице с именем 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 для получения бета-значений:

= 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

Бета-версии находятся в верхнем ряду, и их использование дает мне следующую линейную оценку:

Manager = 0.962 * Equity - 0.185 * Duration + 0.077 * Credit - 0.001

Вопрос в том, как получить эти значения в Power BI с помощью DAX (желательно без написания собственного сценария R)?


Для простой линейной регрессии по одному столбцу я могу вернуться к математическому определению и написать метод наименьших квадратов реализация аналогична той, что приведена в этом сообщении.

Однако, когда задействовано больше столбцов (мне нужно иметь возможность делать до 12 столбцов, но не всегда одно и то же количество), это очень быстро становится беспорядочным, и я надеюсь, что есть лучший способ.


person Alexis Olson    schedule 14.02.2018    source источник


Ответы (3)


Суть:

DAX - это не выход. Используйте Home > Edit Queries, а затем 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)

Измените Manager на любое из других доступных имен переменных, чтобы изменить зависимую переменную.


Подробности:

Хороший вопрос! Я не понимаю, почему Microsoft не представила более гибкие решения. Но в настоящее время вы не сможете найти очень хорошие подходы без использования R в Power BI.

Поэтому предлагаемый мной подход игнорирует ваш запрос относительно:

Вопрос в том, как получить эти значения в Power BI с помощью DAX (желательно без написания собственного сценария R)?

Однако мой ответ будет соответствовать вашим требованиям относительно:

Хороший ответ должен быть обобщен на более чем 3 столбца (возможно, работая с таблицей несведенных данных с индексами как значениями, а не заголовками столбцов).

Вот так:


Я нахожусь в системе, использующей запятую в качестве десятичного разделителя, поэтому я собираюсь использовать в качестве источника данных следующее (если вы скопируете числа непосредственно в Power BI, разделение столбцов не будет сохранено. Если вы сначала вставите его в Excel, скопируйте его снова и ЗАТЕМ вставьте в Power BI, столбцы будут в порядке):

Date    Equity  Duration    Credit  Manager
31.01.2017  2,907   0,226   1,24    1,78
28.02.2017  2,513   0,493   1,12    3,88
31.03.2017  1,346   -0,046  -0,25   0,13
30.04.2017  1,612   0,695   0,62    1,04
31.05.2017  2,209   0,653   0,48    1,4
30.06.2017  0,796   -0,162  0,35    0,63
31.07.2017  2,733   0,167   0,83    2,06
31.08.2017  0,401   1,083   -0,67   0,29
30.09.2017  1,88    -0,857  1,43    2,04
31.10.2017  2,151   -0,121  0,51    2,33
30.11.2017  2,02    -0,137  -0,02   3,06
31.12.2017  1,454   0,309   0,23    1,28

Начиная с нуля в Power BI (для воспроизводимости), я вставляю данные, используя Enter Data:

введите описание изображения здесь

Теперь перейдите к Edit Queries > Edit Queries и убедитесь, что у вас есть это:

введите описание изображения здесь

Я считаю, что для обеспечения гибкости в отношении количества столбцов для включения в анализ лучше всего удалить столбец Дата. Это не повлияет на результаты вашей регрессии. Просто щелкните правой кнопкой мыши столбец «Дата» и выберите Remove:

введите описание изображения здесь

Обратите внимание, что это добавит новый шаг в Query Settings > Applied Steps>:

введите описание изображения здесь

И здесь вы сможете отредактировать несколько строк кода R, которые мы собираемся использовать. Теперь перейдите к Transform > Run R Script, чтобы открыть это окно:

введите описание изображения здесь

Обратите внимание на строку # 'dataset' holds the input data for this script. К счастью, ваш вопрос касается только ОДНОЙ таблицы ввода, поэтому все не станет слишком сложным (для нескольких таблиц ввода проверьте этот пост). Переменная набора данных представляет собой переменную формы data.frame в R и является хорошей (единственной ..) отправной точкой для дальнейшего анализа.

Вставьте следующий скрипт:

model <- lm(Manager ~ . , dataset)
df<- data.frame(coef(model))
names(df)[names(df)=="coef.model."] <- "coefficients"
df['variables'] <- row.names(df)

введите описание изображения здесь

Нажмите OK, и, если все пойдет хорошо, вы должны получить следующее:

введите описание изображения здесь

Щелкните Table, и вы получите следующее:

введите описание изображения здесь

Под Applied Steps вы увидите, что был вставлен Run R Script шаг. Щелкните звездочку (шестеренку?) Справа, чтобы отредактировать ее, или щелкните df, чтобы отформатировать таблицу вывода.

Вот и все! По крайней мере, в части Редактировать запросы.

Щелкните Home > Close & Apply, чтобы вернуться в раздел отчетов Power BI и убедиться, что у вас есть новая таблица в Visualizations > Fields:

введите описание изображения здесь

Вставьте таблицу или матрицу и активируйте коэффициенты и переменные, чтобы получить это:

введите описание изображения здесь

Надеюсь, это то, что вы искали!


Теперь некоторые подробности о сценарии R:

Насколько это возможно, я бы избегал использования множества различных библиотек R. Таким образом вы снизите риск возникновения проблем с зависимостями.

Функция lm() обрабатывает регрессионный анализ. Ключ к достижению требуемой гибкости в отношении количества объясняющих переменных лежит в части Manager ~ . , dataset. Это просто говорит о том, что нужно выполнить регрессионный анализ Manager переменной в фрейме данных dataset и использовать все оставшиеся столбцы ~ . в качестве независимых переменных. Часть coef(model) извлекает значения коэффициентов из оценочной модели. Результатом является фрейм данных с именами переменных как именами строк. Последняя строка просто добавляет эти имена в сам фрейм данных.

person vestland    schedule 26.02.2018
comment
Выглядит неплохо. В идеале сценарий R мог бы реагировать на срезы и фильтры на странице отчета (поскольку я не могу разумно предварительно вычислить все возможные комбинации, для которых мне нужны бета-версии), но я не думаю, что можно использовать R как часть мера в настоящее время (и это выходит за рамки моего вопроса). - person Alexis Olson; 26.02.2018
comment
Не могу больше договориться о том, как эти вещи должны быть в Power BI. Но, насколько мне известно, мы еще не достигли цели. Что касается их темпов добавления новых функций, это может длиться недолго, пока мы не сможем сделать то, что вы описываете. Но прямо сейчас Power BI преуспевает в визуализации результатов анализа, проведенного где-то еще. Что касается предварительных вычислений бета-версий, для которых вы хотели бы увидеть результаты, я бы посоветовал вам взглянуть на Python и пакет statsmodels. Вы очень быстро наберете скорость. Я думаю, что с R и Python намного легче работать, чем, например, с DAX. - person vestland; 27.02.2018
comment
Так что, если вы можете работать с DAX в Power BI, Python должен быть простым. Google Anaconda и начните оттуда. Spyder или Visual Studio должны подойти в качестве хорошей стартовой IDE. Тогда вы могли бы взглянуть на то, что я недавно опубликовал о запуске регрессий для подмножеств таблицы здесь: stackoverflow.com/questions/48624071/ Единственное, что вам нужно, это Python и текстовый файл. Затем вы можете запустить любую регрессию и даже сохранить результаты в другом текстовом файле. - person vestland; 27.02.2018
comment
И даже визуализируйте результаты в Power BI, если это все еще ваш любимый набор инструментов. К настоящему времени я сделал это более сложным, чем есть на самом деле ... Но тебе действительно стоит взглянуть, если тебе нравятся эти вещи. - person vestland; 27.02.2018
comment
Удалось ли вам реализовать это предложение? - person vestland; 01.03.2018

Поскольку в Power BI нет эквивалентной или удобной замены функции LINEST (я уверен, что вы провели достаточно исследований, прежде чем опубликовать вопрос), любые попытки будут означать переписывание всей функции в Power Query / M, что уже не так «простой» для случая простой линейной регрессии, не говоря уже о нескольких переменных.

Вместо того, чтобы изобретать колесо (заново), гораздо проще (однострочный код ..) сделать это с помощью сценария R в Power BI.

Это неплохой вариант, учитывая, что у меня нет опыта 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)

lm - это встроенная функция линейной модели из R, а функция tidy поставляется с пакет broom, который убирает вывод и вывести фрейм данных для Power BI.

результат

В столбцах term и estimate этого должно быть достаточно для вычисления желаемой оценки.

Запрос M для справки:

let
    Source = Csv.Document(File.Contents("returns.csv"),[Delimiter=",", Columns=5, Encoding=1252, QuoteStyle=QuoteStyle.None]),
    #"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
    #"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Date", type text}, {"Equity", Percentage.Type}, {"Duration", Percentage.Type}, {"Credit", Percentage.Type}, {"Manager", Percentage.Type}}),
    #"Run R Script" = R.Execute("# 'dataset' holds the input data for this script#(lf)# install.packages(""broom"")#(lf)library(broom)#(lf)#(lf)model <- lm(Manager ~ Equity + Duration + Credit, dataset)#(lf)model <- tidy(model)",[dataset=#"Changed Type"]),
    #"""model""" = #"Run R Script"{[Name="model"]}[Value]
in
    #"""model"""
person Foxan Ng    schedule 22.02.2018

Я выяснил, как это сделать специально для трех переменных, но этот подход вообще не масштабируется до большего или меньшего количества переменных.

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 }

Это вычисляемая таблица, которая возвращает указанные коэффициенты регрессии:

Расчетная таблица

Эти числа соответствуют выходным данным ЛИНЕЙН для предоставленных данных.

Примечание. Значения ЛИНЕЙН, которые я привел в вопросе, немного отличаются от тезисов, поскольку они были рассчитаны на основе неокругленных результатов, а не округленных результатов, представленных в вопросе.


Я сослался на этот документ для настройки расчетов и Mathematica для решить систему:

введите описание изображения здесь

person Alexis Olson    schedule 06.01.2021