Выбор наилучшей регрессии. Пошаговая регрессия

Назначение множественной регрессии. Коэффициент корреляции между двумя векторами. Определение наилучшего уравнения регрессии. Оценка параметров нулевого уравнения регрессии. Оптимальное количество независимых переменных. Использование метода включения.

Рубрика Экономико-математическое моделирование
Вид курсовая работа
Язык русский
Дата добавления 23.11.2013
Размер файла 352,4 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Министерство образования и науки Российской Федерации

Кафедра прикладной математики

Курсовой проект

по курсу «Методы планирования и анализа в экономических и социологических исследованиях»

Тема: «Выбор наилучшей регрессии»

Вариант: «Пошаговая регрессия»

Новосибирск

2006

Оглавление

Введение

1. Пошаговая регрессия

1.1 Описание метода

1.2 Алгоритм метода

2. Реализация

2.1 Входные данные

2.2 Представление результата

2.3 Определение наилучшего уравнения регрессии

2.4 Описание программного продукта

3. Тестирование

3.1 Тест №1: модель без шума

3.1.1 Входые данные

3.1.2 Результат

3.2 Тест №2: модель с шумом

3.2.1 Входные данные

3.2.2 Результат

3.3 Результаты тестирования

4. Решение практической задачи

4.1 Входные данные

4.2 Результат

5. Выводы

Литература

Приложение 1 «Тексты программы»

Введение

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

Оценивание производится по наблюдениям за входом (строки мартицы наблюдений ) и выходом (элементы вектора откликов ).

или то же самое в компактом виде:

.

Регрессионные коэффициенты представляют независимые вклады каждой независимой переменной в предсказание зависимой переменной. Для отбора окончательного уравнения регрессии обычно используют два противоположных критерия:

Чтобы сделать уравнение полезным для предсказания, мы должны стремиться включить в модель по возможности больше независимых переменных с тем, чтобы можно было более надежно определить прогнозируемые величины.

Из-за затрат, связанных с получением информации при большом числе и ее последующей проверкой, необходимо стремиться, чтобы уравнение включало как можно меньше независимых переменных.

Компромисс между этими критериями может быть достигнут за счет выбора "наилучшего" уравнения, включающего оптимальное количество независимых переменных. В работе для поиска "наилучшего" уравнения регрессии был применен шаговый метод (пошаговая регрессия).

1. Пошаговая регрессия

1.1 Описание метода

В методе пошаговой регрессии начинают с модели, состоящей из одной переменной.

Порядок включения определяется с помощью частного критерия

Так же, как и в методе включения, одна за другой добавляются остальные переменные, а порядок их включения определяют по частным коэффициентам корреляции с откликом, как по мерам важности переменных, еще не включенных в уравнение. Переменная, включенная на данном этапе, должна иметь максимальный частный коэффициент корреляции или частный критерий:

,

где , - остаточные суммы квадратов до и после включения в модель очередного регрессора соответственно. Но включенная переменная в модель на ранней стадии, на более поздней стадии может оказаться излишней из-за взаимосвязи между этой и другими переменными, содержащимися теперь в модели. Чтобы проверить это, на каждой стадии вычисляют частный критерий для каждой переменной уравнения и сравнивают его с заранее выбранной процентной точкой соответствующего распределения. Это позволяет вынести суждение о том, какой вклад может сделать каждая переменная в предположении, что она введена в модель последней, и безотносительно к тому, когда она была введена на самом деле. Любая переменная, которая дает незначимый вклад, исключается из модели.

Этот процесс продолжается до тех пор, пока уже никакие переменные не добавляются к уравнению и не исключаются из него.

1.2 Алгоритм метода

На вход алгоритма подаются матрица наблюдений размерности и вектор-столбец откликов размерности . Где - количество наблюдений (сколько строк в , столько же и значений выхода ), а - количество регрессоров, не считая свободный член.

0. Дополняем матрицу наблюдений слева единичным столбцом, соответствующим свободному члену. Вектор параметров будет иметь размерность .

1. Включаем в пустое, на начальном этапе, регрессионное уравнение переменную наиболее кореллированную с откликом. Для этого вычисляем корреляции между каждой входной переменной и откликом, после этого включаем в регрессионное уравнение переменную с максимальным коэффициентом корреляции.

Коэффициент корреляции между двумя векторами (-м столбцом матрицы , соответствующим -му регрессору и откликом ) вычилсяется по следующей формуле:

где:

- количество предложенных регрессоров вместе со свободным членом;

- количество наблюдений;

- вектор откликов;

- -ый столбец матрицы наблюдений;

,

- арифметические средние.

Номер шага .

2. Включаем в регрессионное уравнение «очередную» переменную, соответствующую максимальному значению из частных критериев всех еще не включенных в уравнение переменных.

Частный критерий для -переменной вычисляется по следующей формуле:

где

- количество наблюдений (по-прежнему);

- здесь - это количество уже включенных до этого момента (до -го шага) регрессоров;

- здесь - это остаточная сумма квадратов до включения в модель -го регрессора (то есть текущая - в начале -го шага);

- остаточная сумма квадратов после включения в текущую модель -го регрессора;

Вычисления этих величин производятся по формулам:

,

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

вычисляется аналогично , для этого в «добавляется» -ый столбец матрицы (ведь считаем для -го регрессора), а в соответствующее место «добавляется» параметр . Слово добавляется здесь указано в кавычках для того, чтобы не интерпретировать это действие как добавление в модель -го регрессора (мы просто вычисляем ).

Вектор оценки параметров является результатом решения СЛАУ следующего вида

,

аналогично вычисляются и :

.

3. Исключаем из модели те переменные, значения частных критериев которых меньше значения соответствующего распределения.

,

где

- здесь - это остаточная сумма квадратов после исключения из текущей модели -го регрессора;

- остаточная сумма квадратов до исключения из текущей модели -го регрессора.

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

4. Если на текущем шаге рассмотренные критерии настолько малы, что в модель больше нельзя добавить ни один регрессор, то процесс построения наилучшей модели закончен, иначе - переходим к пункту 2.

2. Реализация

2.1 Входные данные

Входные данные пользователь задает в текстовом файле, имеющем следующий формат:

где

- количество наблюдений;

- количество регрессоров;

- компоненты вектора откликов ;

- элементы матрицы наблюдений .

Вещественные числа должны задаваться с точкой, а не с запятой!!!

2.2 Представление результата

После применения процедуры метода в соответствеющем поле окна программы выдается результирующая модель в формате, выбранном пользователем. Это представление можно сохранить в файл, имя и расположение которого пользователь указывает в соответствующем диалоге сохранения.

Примеры представления модели в предлагаемых пользователю форматах:

Простейший

y=23.45+2.5*x(1)-8.4*x(2)

LaTeX 2.09 and later

y = 23.45 + 2.5 x_1 - 8.4 x_2

HTML

<i>y</i>=23.45+2.5<i>x</i><sub>1</sub>-8.4<i>x</i><sub>2</sub>

(для последнего результатом отображения в браузере будет строка:

y=23.45+2.5x1-8.4x2)

2.3 Определение наилучшего уравнения регрессии

Реализация производилась по алгоритму, описанному в п. 1.2 настоящего отчета.

Подготовка, основной цикл вичислений, и подготовка результатов производится в процедуре N2Click.

Эта процедура пользуется реализованными в этом же модуле функциями:

· определения номера столбца матрицы X максимально коррелированного с откликом

long MaxCorrellation(double & Max_rXjY, long & IndexOfMax_rXjY);

· определение номера регрессора, который следует добавить следующим, если возвращенный номер будет отрицательным, то добавлять нечего в соответствии с выбранным критерием

int WhichAddRegressor(double & _Max_Fj, long & _IndexOfMax_Fj);

· аналогично предыдущей функции, но для исключения регрессора

int WhichExpelRegressor(double & _Bad_Fj, long & _IndexOfBad_Fj);

· функция вычисления оценки вектора параметров включенных в модель в данный момент (для вычисления использует функцию решения СЛАУ прямым методом ThetaForInModelSlaeResolve, реализованную в этом же модуле)

int ThetaForInModel();

· функция решения СЛАУ методом LDU-декомпозиции

int ThetaForInModelSlaeResolve();

· вывод уравнения регрессии в «математическом» формате с указанием названия оного в качестве аргумента (будет выведена подпись)

int OutPutResult(AnsiString Mes);

· подсчет остаточной суммы квадратов для текущей модели

double RSSForInModel();

· функции добавления и исключения регрессора с указанным номером (устанавливают и снимают соответствующий флажок присутствия регрессора в модели, соответственно изменяют значение переменной, ответственную за хранение текущего количества регрессоров в модели, пересчитывают массив номеров регрессоров)

int AddRegressor(long NumOfAddRegressor);

int ExpelRegressor(long NumOfExpelRegressor);

2.4 Описание программного продукта

Программа реализована в среде Borland Builder C++ 6.0.

Вид окна приложения при запуске.

После нажатия на Ctrl+L или выбора соответствующего пункта главного меню, выбираем файл с входными данными.

Получаем подтверждение о загрузке данных:

Нажимаем Ctrl+D или выбираем пункт главного меню Вычислить (что можно сделать только прежде загрузив входные данные) и получаем вид уравнения регрессии:

При желании сохранить текст сообщений - это можно сделать нажав Ctrl+S или выбрав пункт главного меню «Сохранить как…» определить каталог и имя файла для сохранения.

3. Тестирование

3.1 Тест №1: модель без шума

Сгенерируем входные данные по модели:

Рассмотрим регрессоры .

3.1.1 Входые данные

30 4

-6.04978

5.305668

12.35394

7.879198

-36.2421

1.790057

7.884304

-15.8528

-3.39598

-38.303

3.556716

7.405929

25.26245

-3.01641

-29.868

-8.97831

1.809302

4.589457

2.820206

-14.1939

1.371203

2.174904

5.513024

2.922119

8.608813

4.757768

0.518986

18.27984

3.260665

30.98494

-1.56395

-2.07943

-5.55929

7.615385

37.00732

0.820803

11.44119

-5.3617

-0.59334

-70.604

-0.25544

5.591152

10.56075

-0.73019

-24.1543

-8.85667

18.66294

-7.76318

-6.9456

-155.46

2.284854

7.482671

-2.5788

1.475047

-33.6923

-12.1023

5.122194

9.684637

7.56752

-49.8321

-10.5465

14.53234

5.082708

10.71895

-124.988

-9.64485

4.352252

0.529601

4.266988

-37.221

8.346551

11.62195

13.51946

4.26486

-53.308

7.250988

11.92947

6.712292

0.364123

-58.6301

-0.89448

7.83901

8.52853

1.656476

-44.6339

13.89774

-2.93687

-2.93703

1.707294

82.86405

-1.61272

1.348426

0.739727

4.9592

8.091417

7.377849

0.309056

27.23145

-1.20366

39.29855

3.582792

6.550218

-6.06066

-2.23865

-22.6149

3.881856

-2.8873

3.684036

2.620629

57.40798

4.644711

6.614267

28.63922

-7.77557

-20.4981

3.849261

5.99552

9.460123

4.593201

-17.2892

-2.96632

8.701318

15.80272

5.312742

-57.0569

-4.8292

2.95825

10.41952

4.944267

-13.4723

9.880014

0.361968

17.78278

-0.40934

45.1095

6.213804

-3.25992

8.045958

-0.53261

66.36781

2.032274

-0.38545

19.1004

1.319217

31.76847

-3.94475

5.319264

18.59097

6.807419

-31.0937

3.1.2 Результат

Оценка параметров нулевого уравнения регрессии.

Нулевое уравнение регрессии:

y = -17.5216

RSS = 80556.2

В модель добавлен регрессор номер 2, максимально коррелированный с откликом (rXjY=0.957355).

Оценка параметров первого уравнения регрессии.

Первое уравнение регрессии:

y (x2) = 29.6766 -9.42182*x2

RSS = 6724.13

НА ДОБАВЛЕНИЕ

RSS=6724.13

RSSj=1.38913E-07

Fj=1.35535E+12

j=1

RSS=6724.13

RSSj=6580.02

Fj=0.613204

j=3

RSS=6724.13

RSSj=5004.16

Fj=9.62382

j=4

будет добавление...

В уравнение добавлен регрессор № 1.

Оценка параметров нового уравнения регрессии.

Новое уравнение регрессии:

y (x1, x2) = 23.45 +2.5*x1 -8.4*x2

RSS = 1.38913E-07

НА ИСКЛЮЧЕНИЕ

RSS=1.38913E-07

RSSj=7938.38

Fj=28

j=0

RSS=1.38913E-07

RSSj=6724.13

Fj=28

j=1

RSS=1.38913E-07

RSSj=51973.6

Fj=28

j=2

исключения не будет...

НА ДОБАВЛЕНИЕ

RSS=1.38913E-07

RSSj=1.34231E-07

Fj=0.941813

j=3

RSS=1.38913E-07

RSSj=1.03421E-07

Fj=9.26578

j=4

добавления не будет...

НА ИСКЛЮЧЕНИЕ

RSS=1.38913E-07

RSSj=7938.38

Fj=28

j=0

RSS=1.38913E-07

RSSj=6724.13

Fj=28

j=1

RSS=1.38913E-07

RSSj=51973.6

Fj=28

j=2

исключения не будет...

Полученное уравнение регрессии:

y (x1, x2) = 23.45 +2.5*x1 -8.4*x2

RSS = 1.38913E-07

3.2 Тест №2: модель с шумом

Сгенерируем входные данные по модели:

Рассмотрим регрессоры

3.2.1 Входные данные

30 5

-6.04978

5.305668

-32.0981

36.59986

28.15011

309.8153

1.790057

7.884304

14.11335

3.204302

62.16224

63.31429

3.556716

7.405929

26.34079

12.65023

54.84778

5.648274

-8.97831

1.809302

-16.2445

80.60997

3.273572

396.8297

1.371203

2.174904

2.982234

1.880196

4.730207

65.34221

4.757768

0.518986

2.469215

22.63635

0.269346

-46.6779

-1.56395

-2.07943

3.252113

2.445929

4.324019

151.0528

0.820803

11.44119

9.390961

0.673718

130.9008

101.5441

-0.25544

5.591152

-1.42821

0.06525

31.26098

124.392

-8.85667

18.66294

-165.292

78.44061

348.3055

426.6355

2.284854

7.482671

17.09681

5.220558

55.99037

46.63253

-12.1023

5.122194

-61.9901

146.4648

26.23687

503.7386

-10.5465

14.53234

-153.265

111.2287

211.1889

472.6194

-9.64485

4.352252

-41.9768

93.02313

18.94209

423.3167

8.346551

11.62195

97.00323

69.66491

135.0698

-139.667

7.250988

11.92947

86.50044

52.57683

142.3123

-103.884

-0.89448

7.83901

-7.01186

0.8001

61.45007

149.4049

13.89774

-2.93687

-40.8159

193.1471

8.625205

-346.977

-1.61272

1.348426

-2.17464

2.600877

1.818251

159.4803

7.377849

0.309056

2.280169

54.43266

0.095516

-131.195

3.582792

6.550218

23.46807

12.8364

42.90536

3.108813

3.881856

-2.8873

-11.2081

15.06881

8.336513

-25.3657

4.644711

6.614267

30.72136

21.57334

43.74853

-30.8497

3.849261

5.99552

23.07832

14.81681

35.94626

-6.55274

-2.96632

8.701318

-25.8109

8.799048

75.71293

217.6395

-4.8292

2.95825

-14.286

23.32113

8.751243

265.9522

9.880014

0.361968

3.576249

97.61468

0.131021

-211.406

6.213804

-3.25992

-20.2565

38.61136

10.62706

-100.963

2.032274

-0.38545

-0.78334

4.130136

0.148572

39.01312

-3.94475

5.319264

-20.9832

15.56104

28.29456

242.2854

3.2.2 Результат

Оценка параметров нулевого уравнения регрессии.

Нулевое уравнение регрессии:

y = 100.808

RSS = 1.29871E+06

В модель добавлен регрессор номер 1, максимально коррелированный с откликом (rXjY=0.998865).

Оценка параметров первого уравнения регрессии.

Первое уравнение регрессии:

y (x1) = 115.28 -32.6595*x1

RSS = 2945.95

НА ДОБАВЛЕНИЕ

RSS=2945.95

RSSj=0.000506646

Fj=1.62809E+08

j=2

RSS=2945.95

RSSj=2945.65

Fj=0.00280795

j=3

RSS=2945.95

RSSj=2943.4

Fj=0.0242056

j=4

RSS=2945.95

RSSj=743.966

Fj=82.8741

j=5

будет добавление...

В уравнение добавлен регрессор № 2.

Оценка параметров нового уравнения регрессии.

Новое уравнение регрессии:

y (x1, x2) = 105.014 -32.0998*x1 +1.99986*x2

RSS = 0.000506646

НА ИСКЛЮЧЕНИЕ

RSS=0.000506646

RSSj=159199

Fj=28

j=0

RSS=0.000506646

RSSj=1.10857E+06

Fj=28

j=1

RSS=0.000506646

RSSj=2945.95

Fj=28

j=2

исключения не будет...

НА ДОБАВЛЕНИЕ

RSS=0.000506646

RSSj=0.000498253

Fj=0.454775

j=3

RSS=0.000506646

RSSj=0.000506608

Fj=0.00199628

j=4

RSS=0.000506646

RSSj=0.000504425

Fj=0.118839

j=5

добавления не будет...

НА ИСКЛЮЧЕНИЕ

RSS=0.000506646

RSSj=159199

Fj=28

j=0

RSS=0.000506646

RSSj=1.10857E+06

Fj=28

j=1

RSS=0.000506646

RSSj=2945.95

Fj=28

j=2

исключения не будет...

Полученное уравнение регрессии:

y (x1, x2) = 105.014 -32.0998*x1 +1.99986*x2

RSS = 0.000506646

3.3 Результаты тестирования

множественный регрессия корреляция уравнение

Тестирование показало, что реализованный программный продукт на основе метода пошаговой регрессии получает адекватные результаты на тестах, и может использоваться для решения практических задач.

4. Решение практической задачи

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

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

Выбранные факторы:

· возраст (годы)

· пол (женский - 0, мужской - 1)

· рост (дюймы)

· отношение к курению (некурящий - 0, курящий - 1)

Откликом является величина равная объему воздуха, выдыхаемого человеком на первой секунде выдоха.

Кроме имеющихся факторов рассмотрим взаимодействие факторов.

Возраст(X1)

Пол(X2)

Рост(X3)

Курит(X4)

X4*X3

X4*X2

X4*X1

Y

15

1

65

1

65

1

15

7,69

20

1

65

1

65

1

20

8,04

15

1

65

0

0

0

0

7,7

20

1

65

0

0

0

0

8,05

15

1

75

1

75

1

15

9,09

20

1

75

1

75

1

20

9,44

20

1

75

0

0

0

0

9,05

15

0

65

1

65

0

15

7,54

20

0

65

1

65

0

20

7,89

15

0

65

0

0

0

0

7,55

20

0

65

0

0

0

0

7,9

15

0

75

1

75

0

15

8,94

20

0

75

1

75

0

20

9,29

20

0

75

0

0

0

0

8,9

4.1 Входные данные

15

1

65

1

65

1

15

7.69

20

1

65

1

65

1

20

8.04

15

1

65

0

0

0

0

7.7

20

1

65

0

0

0

0

8.05

15

1

75

1

75

1

15

9.09

20

1

75

1

75

1

20

9.44

20

1

75

0

0

0

0

9.05

15

0

65

1

65

0

15

7.54

20

0

65

1

65

0

20

7.89

15

0

65

0

0

0

0

7.55

20

0

65

0

0

0

0

7.9

15

0

75

1

75

0

15

8.94

20

0

75

1

75

0

20

9.29

20

0

75

0

0

0

0

8.9

4.2 Результат

Оценка параметров нулевого уравнения регрессии.

Нулевое уравнение регрессии:

y = 8.36214

RSS = 6.51224

В модель добавлен регрессор номер 3, максимально коррелированный с откликом (rXjY=0.960198).

Оценка параметров первого уравнения регрессии.

Первое уравнение регрессии:

y (x3) = -0.806667 +0.132333*x3

RSS = 0.508083

НА ДОБАВЛЕНИЕ

RSS=0.508083

RSSj=0.26147

Fj=11.3182

j=1

RSS=0.508083

RSSj=0.429333

Fj=2.20109

j=2

RSS=0.508083

RSSj=0.48675

Fj=0.525937

j=4

RSS=0.508083

RSSj=0.482501

Fj=0.636246

j=5

RSS=0.508083

RSSj=0.441809

Fj=1.80009

j=6

RSS=0.508083

RSSj=0.445801

Fj=1.67652

j=7

будет добавление...

В уравнение добавлен регрессор № 1.

Оценка параметров нового уравнения регрессии.

Новое уравнение регрессии:

y (x1, x3) = -1.464 +0.0544*x1 +0.1278*x3

RSS = 0.26147

НА ИСКЛЮЧЕНИЕ

RSS=0.26147

RSSj=0.396907

Fj=4.09478

j=0

RSS=0.26147

RSSj=0.508083

Fj=5.82456

j=1

RSS=0.26147

RSSj=5.70575

Fj=11.4501

j=3

исключения не будет...

НА ДОБАВЛЕНИЕ

RSS=0.26147

RSSj=0.18272

Fj=4.74086

j=2

RSS=0.26147

RSSj=0.19875

Fj=3.4713

j=4

RSS=0.26147

RSSj=0.186309

Fj=4.43759

j=5

RSS=0.26147

RSSj=0.163407

Fj=6.60125

j=6

RSS=0.26147

RSSj=0.192027

Fj=3.97797

j=7

добавления не будет...

НА ИСКЛЮЧЕНИЕ

RSS=0.26147

RSSj=0.396907

Fj=4.09478

j=0

RSS=0.26147

RSSj=0.508083

Fj=5.82456

j=1

RSS=0.26147

RSSj=5.70575

Fj=11.4501

j=3

исключения не будет...

Полученное уравнение регрессии:

y (x1, x3) = -1.464 +0.0544*x1 +0.1278*x3

RSS = 0.26147

Полученные результаты подтверждают наличие явной зависимости наблюдаемой величины от факторов x1 и x3.

Чем старше и выше человек, тем большим он обладает выдыхательным объемом, курящий он или нет.

5. Выводы

При выполнении курсового проекта был изучен и реализован алгоритм построения наилучшей регрессионной модели методом пошаговой регрессии.

Применение метода на конкретных тестовых примерах и реальных задачах показал его достаточную эффективность при построении регрессионной модели.

Литература

1. Дрейпер Н., Смит Г. Прикладной регрессионный анализ. - М.: Статистика, 1973.

2. Себер Дж. Линейный регрессионный анализ. - М.: Мир, 1980.

3. Методические указания к лабораторной работе №6 по курсу “Статистические методы анализа данных” Попов А.А..

Приложение 1 «Тексты программы»

StepRegressions.cpp

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

//---------------------------------------------------------------------------

USEFORM("StepRegressionsUnit1.cpp", FormMain);

//---------------------------------------------------------------------------

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

try

{

Application->Initialize();

Application->CreateForm(__classid(TFormMain), &FormMain);

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

catch (...)

{

try

{

throw Exception("");

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

}

return 0;

}

//---------------------------------------------------------------------------

StepRegressionsUnit1.h

//---------------------------------------------------------------------------

#ifndef StepRegressionsUnit1H

#define StepRegressionsUnit1H

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <Menus.hpp>

#include <Dialogs.hpp>

#include <ExtCtrls.hpp>

#include <ComCtrls.hpp>

//---------------------------------------------------------------------------

class TFormMain : public TForm

{

__published: // IDE-managed Components

TMainMenu *MainMenu1;

TMenuItem *N1;

TMenuItem *N2;

TMenuItem *N3;

TMenuItem *N4;

TMenuItem *N5;

TMenuItem *N6;

TMenuItem *N7;

TMenuItem *N8;

TOpenDialog *OpenDialog1;

TSaveDialog *SaveDialog1;

TRadioGroup *RadioGroup1;

TRadioButton *RadioButton1;

TRadioButton *RadioButton2;

TRadioButton *RadioButton3;

TMemo *Memo1;

TStatusBar *StatusBar1;

TComboBox *ComboBoxFontSize;

TButton *ButtonMemoClear;

TGroupBox *GroupBox1;

TCheckBox *CheckBox1;

TCheckBox *CheckBoxMaxCorr;

TCheckBox *CheckBoxSvob;

TCheckBox *CheckBoxCorrel;

TGroupBox *GroupBox2;

TEdit *EditFInp;

TLabel *LabelFinp;

TLabel *LabelFout;

TEdit *EditFOut;

void __fastcall FormDestroy(TObject *Sender);

void __fastcall N1Click(TObject *Sender);

void __fastcall N3Click(TObject *Sender);

void __fastcall N4Click(TObject *Sender);

void __fastcall N2Click(TObject *Sender);

void __fastcall ComboBoxFontSizeChange(TObject *Sender);

void __fastcall ButtonMemoClearClick(TObject *Sender);

private:

AnsiString StrMess; // строка сообщения для вывода в Memo1

long m; // количество наблюдений

long n; // количество исследуемых регрессоров

double * y; // вектор отклика размера m

double ** XT; // транспонированная матрица X(m*n) наблюдений размера n*m

double ** XTX; // произведение матриц XT на X для оценки вектора параметров

bool * jInModel; // вектор флажков о включении в модель соответствующего регрессора

bool * jInTemporaryModel; // --//-- о включении в пробную модель --//--

long nCurrent; // текущее количество регрессоров в модели

long * J; // массив размера nCurrent номеров узлов, включенных в модель

double * f; // призведение матрицы XT на Y - есть правая часть СЛАУ для df-ия theta

double * theta;

double RSS;

double MinCould_Max_Fj;

double Fin;

double Fout; // вектор параметров размера n

long MaxCorrellation(double & Max_rXjY, long & IndexOfMax_rXjY);

int WhichAddRegressor(double & _Max_Fj, long & _IndexOfMax_Fj);

int WhichExpelRegressor(double & _Bad_Fj, long & _IndexOfBad_Fj);

int ThetaForInModel(); // вычисление theta текущей модели

int ThetaForInModelSlaeResolve(); // решение СЛАУ в определении theta

int OutPutResult(AnsiString Mes); // вывод уравнения регрессии

double RSSForInModel(); // остаточная сумма квадратов для текущей модели

int AddRegressor(long NumOfAddRegressor);

int ExpelRegressor(long NumOfExpelRegressor);

public: // User declarations

__fastcall TFormMain(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TFormMain *FormMain;

//---------------------------------------------------------------------------

#endif

//---------------------------------------------------------------------------

StepRegressionsUnit1.cpp

//---------------------------------------------------------------------------

#include <stdio.h>

#include <math.h>

#include <vcl.h>

//---------------------------------------------------------------------------

#pragma hdrstop

//---------------------------------------------------------------------------

#include "StepRegressionsUnit1.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

//---------------------------------------------------------------------------

TFormMain *FormMain;

//-Конструктор формы---------------------------------------------------------

__fastcall TFormMain::TFormMain(TComponent* Owner)

: TForm(Owner)

{

nCurrent=0;

Memo1->Font->Size=ComboBoxFontSize->Text.ToInt();

MinCould_Max_Fj=3.28;

Fin=EditFInp->Text.ToDouble();

Fout=EditFOut->Text.ToDouble();

}

//-Деструктор формы----------------------------------------------------------

void __fastcall TFormMain::FormDestroy(TObject *Sender)

{

for(long j=0; j<n; j++)

delete [] XT[j];

delete [] XT;

delete [] y;

delete [] theta;

delete [] jInModel;

delete [] J;

}

//-Загрузка входных данных---------------------------------------------------

void __fastcall TFormMain::N1Click(TObject *Sender)

{

do

if(!OpenDialog1->Execute()) return;

while (OpenDialog1->FileName=="");

FILE *fi=NULL;

AnsiString FileName;

FileName=OpenDialog1->FileName;

if((fi=fopen(FileName.c_str(),"r"))==NULL)

{ ShowMessage("Файл\n"+FileName+"\nне открыт.\nЗагрузка провалена!!!");

return;

}

fscanf(fi,"%d %d",&m,&n);

n+=1;

XT=new double*[n];

for(long i=0; i<n; i++)

XT[i]=new double[m];

y=new double[m];

for(long i=0; i<m; i++)

{ XT[0][i]=1.0;

for(long j=1; j<n; j++)

fscanf(fi,"%lf",&XT[j][i]);

fscanf(fi,"%lf",&y[i]);

}

fclose(fi);

ShowMessage("Загрузка из файла\n"+FileName+"\nзавершена.");

N2->Enabled=true;

return;

}

//-Сохранение результатов в файл---------------------------------------------

void __fastcall TFormMain::N3Click(TObject *Sender)

{

do

if(!SaveDialog1->Execute()) return;

while (SaveDialog1->FileName=="");

AnsiString FileName;

FileName=SaveDialog1->FileName;

Memo1->Lines->SaveToFile(FileName);

ShowMessage("Сохранение в файл\n"+FileName+"\nзавершено.");

return;

}

//-ВЫХОД---------------------------------------------------------------------

void __fastcall TFormMain::N4Click(TObject *Sender)

{ // здесь зделать проверку на наличие изменений и запрос на сохранение

exit(0);

}

//-Вычисления----------------------------------------------------------------

void __fastcall TFormMain::N2Click(TObject *Sender)

{

Fin=EditFInp->Text.ToDouble();

Fout=EditFOut->Text.ToDouble();

theta=new double[n];

J=new long[n]; // на всякий случай берем по полной а не nCurrent

for(long j=0; j<n; j++)

J[j]=-1;

jInModel=new bool[n]; // текущая модель

for(long j=0; j<n; j++)

jInModel[j]=false;

if(CheckBoxSvob->Checked) // вкл. СЧ изначально

{

AddRegressor(0);

Memo1->Lines->Add(

"Оценка параметров нулевого уравнения регрессии.");

ThetaForInModel();

if(OutPutResult("Нулевое")==0)

{

StrMess.sprintf("RSS = %G",RSSForInModel());

Memo1->Lines->Add(StrMess);

}

Memo1->Lines->Add("");

}

// добавление регрессора, максимально коррелированного с откликом

if(CheckBoxMaxCorr->Checked)

{

double Max_rXjY;

long IndexOfMax_rXjY;

MaxCorrellation(Max_rXjY,IndexOfMax_rXjY);

AddRegressor(IndexOfMax_rXjY); // добавление "первого" регрессора

StrMess.sprintf("В модель добавлен регрессор номер %d, максимально "

"коррелированный с откликом (rXjY=%G).",IndexOfMax_rXjY,Max_rXjY);

Memo1->Lines->Add(StrMess);

Memo1->Lines->Add(

"Оценка параметров первого уравнения регрессии.");

ThetaForInModel();

if(OutPutResult("Первое")==0)

{

StrMess.sprintf("RSS = %G",RSSForInModel());

Memo1->Lines->Add(StrMess);

}

Memo1->Lines->Add("");

}

bool FlagEnd1=false, FlagEnd2=false;

while(1)

{ // определение очередного регрессора на добавление

double Max_Fj=0.0;

long IndexOfMax_Fj=-1;

// если больше нет возможности добавить хотя бы один

// регрессор, то вычисления закончились.

if(WhichAddRegressor(Max_Fj,IndexOfMax_Fj)==-1)

FlagEnd1=true; // нет для добавления сейчас

else

{

AddRegressor(IndexOfMax_Fj);

StrMess.sprintf("В уравнение добавлен регрессор № %d.",

IndexOfMax_Fj);

Memo1->Lines->Add(StrMess);

Memo1->Lines->Add(

"Оценка параметров нового уравнения регрессии.");

ThetaForInModel();

if(OutPutResult("Новое")==0)

{ StrMess.sprintf("RSS = %G",RSSForInModel());

Memo1->Lines->Add(StrMess);

}

Memo1->Lines->Add("");

}

// определение регрессоров на исключение

while(1)

{ double Bad_Fj;

long IndexOfBad_Fj;

WhichExpelRegressor(Bad_Fj,IndexOfBad_Fj);

if(IndexOfBad_Fj==-1)

{ FlagEnd2=true;

break; // исключать нечего

}

// иначе исключить

ExpelRegressor(IndexOfBad_Fj);

StrMess.sprintf("Из уравнения исключен регрессор № %d.",

IndexOfBad_Fj);

Memo1->Lines->Add(StrMess);

Memo1->Lines->Add(

"Оценка параметров нового уравнения регрессии.");

ThetaForInModel();

if(OutPutResult("Новое")==0)

{ StrMess.sprintf("RSS = %G",RSSForInModel());

Memo1->Lines->Add(StrMess);

}

Memo1->Lines->Add("");

}

if(FlagEnd1 && FlagEnd2) break;

FlagEnd1=false;

FlagEnd2=false;

/* // если больше не будет возможности добавить хоть один

// регрессор, то выйти из цикла.

if(NotCouldAddRegressor()) break;*/

}

if(CheckBox1->Checked) // вкл все регрессоры

{

for(long i=0; i<n; i++)

AddRegressor(i);

Memo1->Lines->Add("Принудительно включены все регрессоры.");

Memo1->Lines->Add("");

}

ThetaForInModel(); // оценка параметров определенного регрессионного уравнения

if(OutPutResult("Полученное")==0)

{

RSS=RSSForInModel();

StrMess.sprintf("RSS = %G",RSS);

Memo1->Lines->Add(StrMess);

}

Memo1->Lines->Add("=====================================================================");

N3->Enabled=true;

}

//-Определение фактора, максимально коррелированного с откликом--------------

long TFormMain::MaxCorrellation(double & _Max_rXjY, long & _IndexOfMax_rXjY)

{

// определение средних значений:

// отклика

double MiddleY=0.0;

for(long i=0;i<m;i++)

MiddleY+=y[i];

MiddleY/=m;

// столбца Xj в цикле df-ия max корреляции:

double Max_rXjY=0.0;

double IndexOfMax_rXjY=-1;

if(CheckBoxCorrel->Checked)

Memo1->Lines->Add("Вектор корреляций с откликом:");

for(long j=1; j<n; j++)

{ // if(j!=0) // для своб.чл.

double MiddleXj=0;

for(long i=0;i<m;i++)

MiddleXj+=XT[j][i];

MiddleXj/=m;

double S1=0.0, S2=0.0, S3=0.0;

for(long i=0; i<m; i++)

{ S1+=(XT[j][i]-MiddleXj)*(y[i]-MiddleY);

S2+=pow(XT[j][i]-MiddleXj,2);

S3+=pow(y[i]-MiddleY,2);

}

AnsiString StrMess;

if(S1==0.0 || S2==0.0 || S3==0.0)

{ StrMess=StrMess.sprintf("Не посчитан %d", j);

Memo1->Lines->Add(StrMess);

continue;

}

double rXjY=S1/sqrt(S2*S3);

if(CheckBoxCorrel->Checked)

{

StrMess.cat_sprintf("j=%d\t%f\t", j,rXjY);

Memo1->Lines->Add(StrMess);

}

rXjY=(rXjY<0)?-rXjY:rXjY;

if(rXjY>Max_rXjY)

{ Max_rXjY=rXjY;

IndexOfMax_rXjY=j;

}

}

// Максимальный коэффициент корреляции Max_rXjY

// Номер регрессора с максимальным коэффициентом корреляции

// относительно отклика

_Max_rXjY=Max_rXjY;

_IndexOfMax_rXjY=IndexOfMax_rXjY;

return 0;

}

//---------------------------------------------------------------------------

int TFormMain::WhichAddRegressor(double & _Max_Fj, long & _IndexOfMax_Fj)

{

double Max_Fj=0.0;

long IndexOfMax_Fj=-1;

ThetaForInModel();

RSS=RSSForInModel();

double RSSj;

double Fj;

Memo1->Lines->Add("НА ДОБАВЛЕНИЕ");

// по тем, которых нет в модели

for(long j=0; j<n; j++)

if(!jInModel[j])

{

AddRegressor(j); // временно

ThetaForInModel();

RSSj=RSSForInModel();

Fj=(RSS-RSSj)/(RSSj)*(m-(nCurrent-1));

if(Fj>Max_Fj)

{ Max_Fj=Fj;

IndexOfMax_Fj=j;

}

StrMess.sprintf("RSS=%G\tRSSj=%G\tFj=%G\tj=%d"

,RSS,RSSj,Fj,j);

Memo1->Lines->Add(StrMess);

ExpelRegressor(j); // временно

ThetaForInModel();

}

if(Max_Fj<Fin)

{ _Max_Fj=0.0;

_IndexOfMax_Fj=-1;

Memo1->Lines->Add("добавления не будет...");

Memo1->Lines->Add("");

return -1;

}

_Max_Fj=Max_Fj;

_IndexOfMax_Fj=IndexOfMax_Fj;

Memo1->Lines->Add("будет добавление...");

Memo1->Lines->Add("");

return 0;

}

//---------------------------------------------------------------------------

int TFormMain::WhichExpelRegressor(double & _Bad_Fj, long & _IndexOfBad_Fj)

{

double Bad_Fj=0.0;

double IndexOfBad_Fj=-1;

ThetaForInModel();

RSS=RSSForInModel();

double RSSj;

double Fj;

Memo1->Lines->Add("НА ИСКЛЮЧЕНИЕ");

// по тем, которые в модели

for(long j=0; j<n; j++)

if(jInModel[j])

{

ExpelRegressor(j); // временно

ThetaForInModel();

RSSj=RSSForInModel();

Fj=(RSSj-RSS)/(RSSj)*(m-nCurrent);

if(Fj<Bad_Fj)

{ Bad_Fj=Fj;

IndexOfBad_Fj=j;

}

StrMess.sprintf("RSS=%G\tRSSj=%G\tFj=%G\tj=%d",RSS,RSSj,Fj,j);

Memo1->Lines->Add(StrMess);

AddRegressor(j); // временно

ThetaForInModel();

}

if(Bad_Fj>Fout)

{ _Bad_Fj=0.0;

_IndexOfBad_Fj=-1;

Memo1->Lines->Add("исключения не будет...");

Memo1->Lines->Add("");

return -1;

}

_Bad_Fj=Bad_Fj;

_IndexOfBad_Fj=IndexOfBad_Fj;

Memo1->Lines->Add("исключение будет...");

Memo1->Lines->Add("");

return 0;

}

//---------------------------------------------------------------------------

int TFormMain::ThetaForInModel()

{

// Выделение памяти для матрицы СЛАУ

XTX=new double*[nCurrent]; // столбец указателей

for(long i=0; i<nCurrent; i++) // создание строк

XTX[i]=new double[nCurrent];

// Получение XTX=XT*X (перепроверить!!!)

for(long i=0; i<nCurrent; i++)

for(long j=0; j<nCurrent; j++)

{

XTX[i][j]=0.0;

for(long k=0; k<m; k++)

XTX[i][j]+=XT[J[i]][k]*XT[J[j]][k];

}

// создание правой части СЛАУ как произведение XT*Y

f=new double[nCurrent];

for(long i=0; i<nCurrent; i++)

{ f[i]=0.0;

for(long j=0; j<m; j++)

f[i]+=XT[J[i]][j]*y[j];

}

ThetaForInModelSlaeResolve();

for(long j=0; j<n; j++)

theta[j]=0.0;

for(long j=0; j<nCurrent; j++)

theta[J[j]]=f[j];

for(long j=0; j<nCurrent; j++)

delete [] XTX[j];

delete [] XTX;

delete [] f;

return 0;

}

//---------------------------------------------------------------------------

int TFormMain::ThetaForInModelSlaeResolve()

{ // LDU

for(long np=0; np<nCurrent; np++)

{ // диагональный:

for(long k=0; k<np; k++)

XTX[np][np]-=XTX[np][k]*XTX[k][k]*XTX[k][np];

// нижняя часть

long j=np;

for(long i=np+1; i<nCurrent; i++)

{

for(long k=0; k<j; k++)

XTX[i][j]-=XTX[i][k]*XTX[k][k]*XTX[k][j];

XTX[i][j]/=XTX[j][j];

}

// верхняя часть

long i=np;

for(long j=np+1; j<nCurrent; j++)

{

for(long k=0; k<i; k++)

XTX[i][j]-=XTX[i][k]*XTX[k][k]*XTX[k][j];

XTX[i][j]/=XTX[i][i];

}

}

// прямой ход:

for(long i=0; i<nCurrent; i++)

for(long j=0; j<i; j++)

f[i]-=XTX[i][j]*f[j];

// диагональный ход:

for(long i=0; i<nCurrent; i++)

f[i]/=XTX[i][i];

// обратный ход:

for(long i=nCurrent-1; i>=0; i--)

for(long j=i+1; j<nCurrent; j++)

f[i]-=XTX[i][j]*f[j];

return 0;

}

//---------------------------------------------------------------------------

int TFormMain::OutPutResult(AnsiString Mes)

{

AnsiString Str0;

if(Mes=="")

Str0="Уравнение регрессии: ";

else Str0=Mes+" уравнение регрессии: ";

AnsiString Str1="y ";

if(nCurrent>1 || !jInModel[0])

Str1.cat_sprintf("(");

AnsiString Str2;

bool FlagFirstPrintArgument=true;

for(long j=1; true; j++)

{ if(jInModel[j])

{ if(!FlagFirstPrintArgument)

Str2+=StrMess.sprintf(", x%d",j);

else

{ Str2+=StrMess.sprintf("x%d",j);

FlagFirstPrintArgument=false;

}

}

if(j<n-1);

else break;

}

AnsiString Str3;

if(nCurrent>1 || !jInModel[0])

Str3.cat_sprintf(") = ");

else

Str3="= ";

AnsiString Str4;

bool FlagFirstPrintSlagaemoe=true;

if(jInModel[0])

{ Str4+=StrMess.sprintf("%G",theta[0]);

FlagFirstPrintSlagaemoe=false;

}

for(long j=1; true; j++)

{ if(jInModel[j])

{

if(!FlagFirstPrintSlagaemoe)

Str4+=StrMess.sprintf(" %+G*x%d",theta[j],j);

else

{ Str4+=StrMess.sprintf("%G*x%d",theta[j],j);

FlagFirstPrintSlagaemoe=false;

}

}

if(j<n-1);

else break;

}

if(FlagFirstPrintArgument && FlagFirstPrintSlagaemoe)

{ StrMess="Уравнение неопределено.";

Memo1->Lines->Add(StrMess);

return 1;

}

else

{

Memo1->Lines->Add(Str0);

StrMess=Str1+Str2+Str3+Str4;

Memo1->Lines->Add(StrMess);

return 0;

}

}

//---------------------------------------------------------------------------

void __fastcall TFormMain::ComboBoxFontSizeChange(TObject *Sender)

{

Memo1->Font->Size=ComboBoxFontSize->Text.ToInt();

Memo1->Refresh();

}

//---------------------------------------------------------------------------

double TFormMain::RSSForInModel()

{

double *raznost;

raznost=new double[m];

// умножение матрицы X на вектор параметров theta

double rss=0;

for(long i=0; i<m; i++)

{ raznost[i]=0;

for(long j=0; j<nCurrent; j++)

raznost[i]-=XT[J[j]][i]*theta[J[j]];

// вычитание полученного из отклика

raznost[i]+=y[i];

rss+=pow(raznost[i],2);

}

delete [] raznost;

return rss;

}

//---------------------------------------------------------------------------

int TFormMain::AddRegressor(long NumOfAddRegressor)

{

jInModel[NumOfAddRegressor]=true;

// Подсчет количества регрессоров

long nCurr=0;

for(long j=0; j<n; j++)

if(jInModel[j]) nCurr+=1;

// Перепись массива номеров включенных регрессоров

long j1=0;

for(long j=0; j<n; j++)

if(jInModel[j])

{ J[j1]=j;

j1+=1;

}

// заполнение оставшейся части массива J

for(;j1<n; j1++)

J[j1]=-1;

nCurrent=nCurr; // ~nCurrent+=1;

return 0;

}

//---------------------------------------------------------------------------

int TFormMain::ExpelRegressor(long NumOfExpelRegressor)

{

jInModel[NumOfExpelRegressor]=false;

// Подсчет количества регрессоров

long nCurr=0;

for(long j=0; j<n; j++)

if(jInModel[j]) nCurr+=1;

// Перепись массива номеров включенных регрессоров

long j1=0;

for(long j=0; j<n; j++)

if(jInModel[j])

{ J[j1]=j;

j1+=1;

}

// заполнение оставшейся части массива J

for(;j1<n; j1++)

J[j1]=-1;

nCurrent=nCurr; // ~nCurrent-=1;

return 0;

}

//---------------------------------------------------------------------------

void __fastcall TFormMain::ButtonMemoClearClick(TObject *Sender)

{

Memo1->Clear();

}

//---------------------------------------------------------------------------

Размещено на Allbest.ru


Подобные документы

  • Основные параметры уравнения регрессии, оценка их параметров и значимость. Интервальная оценка для коэффициента корреляции. Анализ точности определения оценок коэффициентов регрессии. Показатели качества уравнения регрессии, прогнозирование данных.

    контрольная работа [222,5 K], добавлен 08.05.2014

  • Анализ метода наименьших квадратов для парной регрессии, как метода оценивания параметров линейной регрессии. Рассмотрение линейного уравнения парной регрессии. Исследование множественной линейной регрессии. Изучение ошибок коэффициентов регрессии.

    контрольная работа [108,5 K], добавлен 28.03.2018

  • Понятие модели множественной регрессии. Сущность метода наименьших квадратов, который используется для определения параметров уравнения множественной линейной регрессии. Оценка качества подгонки регрессионного уравнения к данным. Коэффициент детерминации.

    курсовая работа [449,1 K], добавлен 22.01.2015

  • Определение параметров линейной регрессии и корреляции с использованием формул и табличного процессора MS Excel. Методика расчета показателей парной нелинейной регрессии и корреляции. Вычисление значений линейных коэффициентов множественной детерминации.

    контрольная работа [110,4 K], добавлен 28.07.2012

  • Факторы, формирующие цену квартир в строящихся домах в Санкт-Петербурге. Составление матрицы парных коэффициентов корреляции исходных переменных. Тестирование ошибок уравнения множественной регрессии на гетероскедастичность. Тест Гельфельда-Квандта.

    контрольная работа [1,2 M], добавлен 14.05.2015

  • Уравнение нелинейной регрессии и вид уравнения множественной регрессии. Преобразованная величина признака-фактора. Преобразование уравнения в линейную форму. Определение индекса корреляции и числа степеней свободы для факторной суммы квадратов.

    контрольная работа [501,2 K], добавлен 27.06.2011

  • Расчет параметров A и B уравнения линейной регрессии. Оценка полученной точности аппроксимации. Построение однофакторной регрессии. Дисперсия математического ожидания прогнозируемой величины. Тестирование ошибок уравнения множественной регрессии.

    контрольная работа [63,3 K], добавлен 19.04.2013

  • Экономическая интерпретация коэффициента регрессии. Нахождение статочной суммы квадратов и оценка дисперсии остатков. Проверка значимости параметров уравнения регрессии с помощью t-критерия Стьюдента. Расчет средней относительной ошибки аппроксимации.

    контрольная работа [261,1 K], добавлен 23.03.2010

  • Расчет линейного коэффициента парной и частной корреляции. Статистическая значимость параметров регрессии и корреляции. Анализ корреляционного поля данных. Точность прогноза, расчет ошибки и доверительный интервал. Коэффициент множественной детерминации.

    контрольная работа [155,8 K], добавлен 11.12.2010

  • Построение уравнения множественной регрессии в линейной форме с полным набором факторов, отбор информативных факторов. Проверка значимости уравнения регрессии по критерию Фишера и статистической значимости параметров регрессии по критерию Стьюдента.

    лабораторная работа [217,9 K], добавлен 17.10.2009

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.