Предлагаю Вашему вниманию функцию, которая помогает раскрыть линейную зависимость ( Y = a + b * X ) между двумя параметрами (нахождение коэффициентов "а" и "b") и позволяет прикинуть значение одного параметра по значению другого с помощью МНК (метод наименьших квадратов).
Во вложении демонстрация возможностей функции, куда входит:
- Отдельное представление сумм известных значений X, Y - Нахождение среднего для значений X, Y - Подсчёт сумм X*Y, X^2, Y^2 - Нахождение коэффициентов линейной модели Y = a + b * X
Код функции:
[vba]
Код
Option Explicit Option Base 1
Function Least_Square_Method#(RngX As Range, RngY As Range, Optional Point# = 0, Optional Mode$ = 0) 'Function calculates expected Y value from known X for linear dependence Dim X, Y, XY, Xip2, Yip2 'Arrays Dim Xav#, Yav#, Angle#, Shift# 'Where Y(x) = Shift + Angle * x Dim i%, Size# 'Array handling X = RngX: Y = RngY: Size = UBound(X, 1) ReDim XY(Size): ReDim Xip2(Size): ReDim Yip2(Size) 'Filling arrays with values For i = 1 To Size XY(i) = X(i, 1) * Y(i, 1) Xip2(i) = X(i, 1) * X(i, 1) Yip2(i) = Y(i, 1) * Y(i, 1) Next i 'Main calculations With Application.WorksheetFunction Xav = .Average(X) Yav = .Average(Y) Angle = (Size * .Sum(XY) - .Sum(X) * .Sum(Y)) / (Size * .Sum(Xip2) - .Sum(X) * .Sum(X)) Shift = Yav - Xav * Angle 'Final answer Select Case Mode Case 0, "Y(x)": Least_Square_Method = Shift + Angle * Point Case 1, "Sum X": Least_Square_Method = .Sum(X) Case 2, "Sum Y": Least_Square_Method = .Sum(Y) Case 3, "Sum XY": Least_Square_Method = .Sum(XY) Case 4, "Sum X^2 ": Least_Square_Method = .Sum(Xip2) Case 5, "Sum Y^2 ": Least_Square_Method = .Sum(Yip2) Case 6, "X average": Least_Square_Method = Xav Case 7, "Y average": Least_Square_Method = Yav Case 8, "B as angle": Least_Square_Method = Angle Case 9, "A as shift": Least_Square_Method = Shift End Select End With End Function
[/vba]
Дополнительная информация:
Есть мнение, что метод наименьших квадратов впервые появляется в работах Лежандра в конце 18-го века. С помощью МНК изучающий тайны космоса Лежандр старался предсказать траектории движения небесных тел с учётом ошибок астрономических измерений. Наброски этого же метода можно найти в работах Гаусса, датированных началом 19-го века.
[p.s.]Возможно, кто-то подскажет, как называется аналогичный метод для работы с зависимостью вида Y = a + b * X + c * X^2 ?[/p.s.]
Всем привет и хорошего настроения!
Предлагаю Вашему вниманию функцию, которая помогает раскрыть линейную зависимость ( Y = a + b * X ) между двумя параметрами (нахождение коэффициентов "а" и "b") и позволяет прикинуть значение одного параметра по значению другого с помощью МНК (метод наименьших квадратов).
Во вложении демонстрация возможностей функции, куда входит:
- Отдельное представление сумм известных значений X, Y - Нахождение среднего для значений X, Y - Подсчёт сумм X*Y, X^2, Y^2 - Нахождение коэффициентов линейной модели Y = a + b * X
Код функции:
[vba]
Код
Option Explicit Option Base 1
Function Least_Square_Method#(RngX As Range, RngY As Range, Optional Point# = 0, Optional Mode$ = 0) 'Function calculates expected Y value from known X for linear dependence Dim X, Y, XY, Xip2, Yip2 'Arrays Dim Xav#, Yav#, Angle#, Shift# 'Where Y(x) = Shift + Angle * x Dim i%, Size# 'Array handling X = RngX: Y = RngY: Size = UBound(X, 1) ReDim XY(Size): ReDim Xip2(Size): ReDim Yip2(Size) 'Filling arrays with values For i = 1 To Size XY(i) = X(i, 1) * Y(i, 1) Xip2(i) = X(i, 1) * X(i, 1) Yip2(i) = Y(i, 1) * Y(i, 1) Next i 'Main calculations With Application.WorksheetFunction Xav = .Average(X) Yav = .Average(Y) Angle = (Size * .Sum(XY) - .Sum(X) * .Sum(Y)) / (Size * .Sum(Xip2) - .Sum(X) * .Sum(X)) Shift = Yav - Xav * Angle 'Final answer Select Case Mode Case 0, "Y(x)": Least_Square_Method = Shift + Angle * Point Case 1, "Sum X": Least_Square_Method = .Sum(X) Case 2, "Sum Y": Least_Square_Method = .Sum(Y) Case 3, "Sum XY": Least_Square_Method = .Sum(XY) Case 4, "Sum X^2 ": Least_Square_Method = .Sum(Xip2) Case 5, "Sum Y^2 ": Least_Square_Method = .Sum(Yip2) Case 6, "X average": Least_Square_Method = Xav Case 7, "Y average": Least_Square_Method = Yav Case 8, "B as angle": Least_Square_Method = Angle Case 9, "A as shift": Least_Square_Method = Shift End Select End With End Function
[/vba]
Дополнительная информация:
Есть мнение, что метод наименьших квадратов впервые появляется в работах Лежандра в конце 18-го века. С помощью МНК изучающий тайны космоса Лежандр старался предсказать траектории движения небесных тел с учётом ошибок астрономических измерений. Наброски этого же метода можно найти в работах Гаусса, датированных началом 19-го века.
[p.s.]Возможно, кто-то подскажет, как называется аналогичный метод для работы с зависимостью вида Y = a + b * X + c * X^2 ?[/p.s.]Rioran
Я одно не понял - если уж используем в коде WorksheetFunction, то почему сразу весь код не сделать встроенными функциями? SUM(),SUMSQ(),SUMPRODUCT(),AVERAGE() INTERCEPT(),SLOPE(),FORECAST() не говоря уже об LINEST()
Ну и тогда для линейных трендов, а также регрессионного анализа вроде бы бессмысленно писать отдельные функции, если уже имеются все встроенные...
По второму вопросу - прямая выдержка ихз хелпа по =ЛИНЕЙН():
можно использовать функцию ЛИНЕЙН, вводя функции переменных x и y как ряды переменных х и у для ЛИНЕЙН. Например, следующая формула: =ЛИНЕЙН(значения_y, значения_x^СТОЛБЕЦ($A:$C))
работает при наличии одного столбца значений Y и одного столбца значений Х для вычисления аппроксимации куба (многочлен 3-й степени) следующей формы:
y = m1*x + m2*x^2 + m3*x^3 + b
Формула может быть изменена для расчетов других типов регрессии, но в отдельных случаях требуется корректировка выходных значений и других статистических данных.
Я одно не понял - если уж используем в коде WorksheetFunction, то почему сразу весь код не сделать встроенными функциями? SUM(),SUMSQ(),SUMPRODUCT(),AVERAGE() INTERCEPT(),SLOPE(),FORECAST() не говоря уже об LINEST()
Ну и тогда для линейных трендов, а также регрессионного анализа вроде бы бессмысленно писать отдельные функции, если уже имеются все встроенные...
По второму вопросу - прямая выдержка ихз хелпа по =ЛИНЕЙН():
можно использовать функцию ЛИНЕЙН, вводя функции переменных x и y как ряды переменных х и у для ЛИНЕЙН. Например, следующая формула: =ЛИНЕЙН(значения_y, значения_x^СТОЛБЕЦ($A:$C))
работает при наличии одного столбца значений Y и одного столбца значений Х для вычисления аппроксимации куба (многочлен 3-й степени) следующей формы:
y = m1*x + m2*x^2 + m3*x^3 + b
Формула может быть изменена для расчетов других типов регрессии, но в отдельных случаях требуется корректировка выходных значений и других статистических данных.
почему сразу весь код не сделать встроенными функциями?
Думал убить сразу двух зайцев: по малекулам разобрать метод в учебных целях и автоматизировать его применение. Про некоторые встроенные функции до сего дня не знал.
Позже перестрою мою функцию с точки зрения большей практичности. LINEST(), она же ЛИНЕЙН() - хороша, но выцеплять оттуда аргументы не очень удобно. Получается, что UDF будет лишь чуть более удобным переключателем показателей для линейной модели.
почему сразу весь код не сделать встроенными функциями?
Думал убить сразу двух зайцев: по малекулам разобрать метод в учебных целях и автоматизировать его применение. Про некоторые встроенные функции до сего дня не знал.
Позже перестрою мою функцию с точки зрения большей практичности. LINEST(), она же ЛИНЕЙН() - хороша, но выцеплять оттуда аргументы не очень удобно. Получается, что UDF будет лишь чуть более удобным переключателем показателей для линейной модели.Rioran
Роман, Москва, voronov_rv@mail.ru Яндекс-Деньги: 41001312674279