def ec1():
    return """
ЗАДАНИЕ 1 : 

 I. Постановка задачи

В данной задаче мы будем строить парную линейную регрессионную модель, которая позволит изучить взаимосвязь между двумя переменными. Основная цель заключается в том, чтобы определить, как изменение одной переменной (независимой) влияет на изменение другой переменной (эндогенной).
Эндогенная переменная — это переменная, которая объясняется в модели и зависит от других переменных. В качестве эндогенной переменной мы выберем, например, доход домохозяйств (Y). Ключевым моментом здесь будет понимание, что доход может зависеть от различных факторов, и мы сосредоточимся на одной из них.
Для парной линейной регрессии нам необходимо выбрать одну независимую переменную, которая будет влиять на эндогенную. В качестве независимой переменной выберем, например, уровень образования домохозяйства (X), измеряемый в годах обучения.

II. Спецификация модели

Таким образом, наша модель может быть задана следующим уравнением:
У=В+ВХ+е.

Где : 
 y— доход домохозяйства;
x — уровень образования домохозяйства в годах;
b0 — свободный член (значение дохода при нулевом уровне образования);
 b1— коэффициент при независимой переменной (показывает, как изменится доход по мере увеличения уровня образования на один год);
𝜖— случайная ошибка, учитывающая другие факторы, влияющие на доход.


 III. Предположения относительно знаков параметров модели

Предположения относительно знаков коэффициентов:
1. Коэффициент b0:
   - Предположительно,b0будет иметь положительное значение или ноль, что означает, что у домохозяйств с нулевым уровнем образования все равно может быть некоторый доход (например, за счет пособий или другой поддержки).
2. Коэффициент b1:
   - Мы ожидаем, что b1 будет положительным. Это предполагает, что с увеличением уровня образования доход домохозяйства будет расти. Образование часто связано с лучшими возможностями трудоустройства и, следовательно, с более высоким доходом.

ЗАДАНИЕ 4 : 
Тест Шапиро-Вилька : 
В этом тесте рассматриваются 2 гипотезы:
−  	Н0: случайные остатки имеют нормальное распределение;
−  	Н1: случайные остатки не имеют нормального распределения.
Чтобы осуществить этот тест ,  рассчитывается значение статистики (W) по формуле:



Посчитаем с помощью питона :
import numpy as np
from scipy.stats import shapiro
data = np.array([1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, 10.1])
stat, p = shapiro(data)
print(f"Статистика W: {stat}")
Получается W = 0,8638694828
Из таблиц теста Шапиро-Вилька выбирается критическое значение W*.


На основе имеющихся данных можно сделать вывод :
Так как W<W*, =>  H0 следует отклонить в пользу H1=>распределение остатков нельзя считать нормальным.



ЗАДАНИЕ 5 : 
⦁	В зависимости от результатов теста Шапиро-Уилка (п. 4), выберите подходящий тест для проверки гетероскедастичности.
⦁	Если данные соответствуют нормальному распределению , можно использовать тест Голдфелда-Квандта.
⦁	Если данные не соответствуют нормальному распределению , можно использовать тест Уайта.
Тест Голдфелда-Квандта состоит в следующем:
⦁	Все наблюдений упорядочиваются по величине .
⦁	Вся упорядоченная выборка после этого разбивается на три подвыборки размерностей   соответственно.
⦁	Оцениваются отдельные регрессии для первой подвыборки (  первых наблюдений) и для третьей подвыборки ( последних наблюдений). Для парной регрессии Голдфелд и Квандт предлагают следующие пропорции:   . Если предположение о пропорциональности дисперсий отклонений значениям верно, то дисперсия регрессии по первой подвыборке (рассчитываемая как   ) будет существенно меньше дисперсии регрессии по третьей подвыборке (рассчитываемой как   ).
⦁	Для сравнения соответствующих дисперсий строится соответствующая -статистика:   . Здесь   - число степеней свободы соответствующих выборочных дисперсий ( - количество объясняющих переменных в уравнении регрессии). Построенная -статистика имеет распределение Фишера с числом степеней свободы   .
⦁	Если   (где   , определяется по таблице, - выбранный уровень значимости), то гипотеза об отсутствии гетероскедастичности отклоняется.
Тест Уайта : 
H0 : гомоскедастичность 
H1 : гетероскедастичность 
Процедура теста Уайта
⦁	Выполнение регрессионного анализа:
⦁	Оценивается регрессионная модель и вычисляются остатки.
⦁	Построение вспомогательной регрессии:
⦁	Строится регрессия квадратов остатков на квадраты предсказанных значений и их произведения.
⦁	Включаются все возможные комбинации независимых переменных и их квадратов.
⦁	Расчет статистики теста:
⦁	Рассчитывается F-статистика и соответствующее p-значение для вспомогательной регрессии.
⦁	Сравнение p-значения с уровнем значимости:
⦁	Если p-значение меньше выбранного уровня значимости (например, 0.05), то нулевая гипотеза о гомоскедастичности отвергается, и это указывает на гетероскедастичность.
⦁	Если p-значение больше уровня значимости, то нулевая гипотеза не отвергается, и это указывает на отсутствие гетероскедастичности.
import numpy as np
import pandas as pd
import statsmodels.api as sm
from statsmodels.stats.diagnostic import het_white

data = pd.DataFrame({
   'X': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
   'Y': [2, 4, 5, 4, 5, 6, 7, 8, 9, 10]
})

data['const'] = 1

model = sm.OLS(data['Y'], data[['const', 'X']])
results = model.fit()

white_test = het_white(results.resid, results.model.exog)

labels = ['Тестовая статистика', 'p-значение', 'f-статистика', 'f p-значение']
print(dict(zip(labels, white_test)))
⦁	p-значение:
⦁	p-значение равно 0.4795.
⦁	Это значение больше, чем обычно используемый уровень значимости 0.05.
⦁	Следовательно, нет оснований отвергать нулевую гипотезу о гомоскедастичности.
⦁	f-статистика и f p-значение:
⦁	f p-значение равно 0.4895.
⦁	Это значение также больше, чем уровень значимости 0.05.
⦁	Следовательно, вспомогательная регрессия не является значимой на уровне 0.05.
"""
def ec2():
    return """
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.stats as sts
from statsmodels.stats.diagnostic import het_goldfeldquandt
from sklearn.linear_model import LinearRegression
import statsmodels.api as sm


file_path = 'дэмо_кр_эконометрика(25вар).xlsx'
data = pd.read_excel(file_path, engine='openpyxl')
data = data.replace(',', '.', regex=True)
pd.set_option('display.max_rows', None) 
pd.set_option('display.colheader_justify', 'right')
print(data.to_string(index=True))

url = 'https://drive.google.com/file/d/1UKVi-XBqZmGOQBcY6qX1EVt9HO23WzvM/view?usp=sharing'
path = 'https://drive.google.com/uc?export=download&id=' + url.split('/')[-2]
data = pd.read_csv(path, encoding='UTF-8', delimiter=';')
data = data.replace(',', '.', regex=True)
data


x = data['Индекс реальных инвестиций в основной капитал'].to_numpy('float64')
y = data['Индекс реального ВВП'].to_numpy('float64')

from sklearn.linear_model import LinearRegression

#1
# Сделай для себя копию x и y ( x.copy(), y.copy()), чтобы случайно для остальных не изменить данные

Цель: Исследовать взаимосвязь между двумя переменными:

Эндогенная переменная (зависимая переменная, y): data.columns[2]
Экзогенная переменная (независимая переменная, x): data.columns[1]
Задачи:

1. Исследование взаимосвязи:

Построить диаграмму рассеяния для визуализации взаимосвязи между x и y.
Рассчитать коэффициент корреляции Пирсона для количественной оценки тесноты и направления связи.
2. Построение модели:

Построить парную линейную регрессионную модель вида y = b0 + b1*x, где b0 - свободный член, b1 - коэффициент регрессии.
Оценить параметры модели (b0 и b1) с помощью метода наименьших квадратов.
3. Анализ результатов:

Проанализировать значимость коэффициентов регрессии.
Оценить качество модели с помощью коэффициента детерминации (R^2).
Сделать выводы о наличии и силе связи между переменными.

x_a, y_a = x.copy(), y.copy()

plt.scatter(x_a, y_a)
plt.xlabel(f'x ({data.columns[1]})')
plt.ylabel(f'y ({data.columns[2]})')
plt.title('Диаграмма рассеяния')
plt.show()

from scipy.stats import pearsonr

corr_coef, p_value = pearsonr(x_a, y_a)
print(f'Коэффициент корреляции Пирсона: {corr_coef:.2f}')

print(f"На основе диаграммы рассеяния и значения коэффициента корреляции можно сделать вывод о том, что линейная связь между {data.columns[1]} (x) и {data.columns[2]} (y) {'сильная ' if 0.7 < corr_coef < 1 else 'умеренная ' if 0.5 < corr_coef <= 0.7 else 'слабая ' if 0.3 < corr_coef <= 0.5 else 'практически отсутствует'}{'' if corr_coef <= 0.3 else 'прямая' if corr_coef > 0 else 'обратная'}.")


№2
x_b = data['Индекс реальных инвестиций в основной капитал'].to_numpy('float64')
y_b = data['Индекс реального ВВП'].to_numpy('float64')

import statsmodels.api as sm
X = sm.add_constant(x_b)
model = sm.OLS(y_b, X).fit()
summary = model.summary()
print(summary)


f_value = model.fvalue
p_value = model.f_pvalue
print(f'F-статистика: {f_value}')

dfn = 1
dfd = 38
alpha = 0.05

f_critical = sts.f.ppf(1 - alpha, dfn, dfd)
print(f'F-табличное: {f_critical}')
Так как полученное значение Фишера больше критического, то нулевая гипотеза отвергается, значит уравнение является качественным.

b_0 = model.params[0]
b_1 = model.params[1]
std_err_b_0 = model.bse[0]
std_err_b_1 = model.bse[1]
print(b_0/std_err_b_0,
b_1/std_err_b_1)
Так как tрасчетное коэффициента b0 больше критического значения, то нулевая гипотеза (b0 = 0) отвергается, значит коэффициент b0 является статистически значимым. Так как tрасчетное коэффициента b1 по модулю больше критического значения, то нулевая гипотеза (b1 = 0) отвергается, значит коэффициент b1 является статистически значимым.


y_pred = model.predict(X)
relative_error = np.mean(np.abs((y_b - y_pred) / y_b)) * 100
print(f'Средняя относительная ошибка: {relative_error:.2f}%')

Средняя ошибка аппроксимации равна 3,378 это меньше 5 значит построенная модель является точной.
Коэффициент детерминации (0,778) свидетельствует о том, что среди всего массива индекса ВВП 77,8% находятся под влиянием инвестиций

№3
x_c, y_c = x.copy(), y.copy()
x_c_r = x_c.reshape(-1, 1)
model = LinearRegression()
model.fit(x_c_r, y_c)

y_pred = model.predict(x_c_r)
model.score(x_c_r, y_c)

errors = y_c-y_pred
errors

Тест Д'Агостино
Наиболее эффективен для выборок среднего и большого размера (обычно от 50 наблюдений). Применяется, когда данные, вероятно, симметричны, но могут иметь отклонения в хвостах, или для проверки нормальности в распределениях с потенциальными выбросами.

print('H0: Случайные остатки соответсвует нормальному распределению')
print('H1: Случайные остатки не соответствует нормальному распределению. \n')
tst = sts.normaltest(errors)
nrm_True = tst.pvalue>0.05
print(P(три кавычки) значение {tst.pvalue:.3} {'больше' if nrm_True else 'меньше'} уровня значимость альфа = 0.05, следовательно
гипотеза H0 {'не ' if nrm_True else ''}может быть отвергнута, а значит по тесту Д'Агостино
{'у нас нет достаточных доказательств, чтобы утверждать, что ' if nrm_True else ''}случайные остатки не соответсвует нормальному распределению(три кавычки))

H0: Случайные остатки соответсвует нормальному распределению
H1: Случайные остатки не соответствует нормальному распределению. 

P значение 0.77 больше уровня значимость альфа = 0.05, следовательно
гипотеза H0 не может быть отвергнута, а значит по тесту Д'Агостино
у нас нет достаточных доказательств, чтобы утверждать, что случайные остатки не соответсвует нормальному распределению

Тест Колмогорова-Смирнова
Униыерсальный тест. Используется для больших выборок (более 50 наблюдений), но может показывать хорошие результаты и на выборках среднего размера (от 20 до 200). Подходит для проверки любых теоретических распределений, а не только нормального.

print('H0: Случайные остатки соответсвует нормальному распределению')
print('H1: Случайные остатки не соответствует нормальному распределению. \n')
kst = sts.kstest(errors, 'norm')
nrm_True = kst.pvalue>0.05
print(fP значение {kst.pvalue:.3} {'больше' if nrm_True else 'меньше'} уровня значимость альфа = 0.05, следовательно
гипотеза H0 {'не ' if nrm_True else ''}может быть отвергнута, а значит по тесту Колмогорова-Смирнова
{'у нас нет достаточных доказательств, чтобы утверждать, что ' if nrm_True else ''}случайные остатки не соответсвует нормальному распределению)

H0: Случайные остатки соответсвует нормальному распределению
H1: Случайные остатки не соответствует нормальному распределению. 

P значение 5.22e-07 меньше уровня значимость альфа = 0.05, следовательно
гипотеза H0 может быть отвергнута, а значит по тесту Колмогорова-Смирнова
случайные остатки не соответсвует нормальному распределению

Тест Шапиро-Вилька
Тест Шапиро-Вилька очень чувствителен к отклонениям от нормальности, особенно для небольших выборок (n<50)

print('H0: Случайные остатки соответсвует нормальному распределению')
print('H1: Случайные остатки не соответствует нормальному распределению. \n')
shp = sts.shapiro(errors)
nrm_True = shp.pvalue>0.05
print(fP значение {shp.pvalue:.3} {'больше' if nrm_True else 'меньше'} уровня значимость альфа = 0.05, следовательно
гипотеза H0 {'не ' if nrm_True else ''}может быть отвергнута, а значит по тесту Шапиро-Вилька
{'у нас нет достаточных доказательств, чтобы утверждать, что ' if nrm_True else ''}случайные остатки не соответсвует нормальному распределению)

H0: Случайные остатки соответсвует нормальному распределению
H1: Случайные остатки не соответствует нормальному распределению. 

P значение 0.452 больше уровня значимость альфа = 0.05, следовательно
гипотеза H0 не может быть отвергнута, а значит по тесту Шапиро-Вилька
у нас нет достаточных доказательств, чтобы утверждать, что случайные остатки не соответсвует нормальному распределению

Тест Jarque–Bera
Применяется для выборок среднего и крупного размера (обычно более 50 наблюдений). Лучше всего подходит для симметричных распределений, но может быть чувствителен к большим отклонениям в хвостах.

print('H0: Выборка соответсвует нормальному распределению')
print('H1: Выборка не соответствует нормальному распределению. \n')
jb = sts.jarque_bera(errors)
nrm_True = jb.pvalue>0.05
print(fP значение {jb.pvalue:.3} {'больше' if nrm_True else 'меньше'} уровня значимость альфа = 0.05, следовательно
гипотеза H0 {'не ' if nrm_True else ''}может быть отвергнута, а значит по тесту Jarque–Bera
{'у нас нет достаточных доказательств, чтобы утверждать, что ' if nrm_True else ''}случайные остатки не соответсвует нормальному распределению)

H0: Выборка соответсвует нормальному распределению
H1: Выборка не соответствует нормальному распределению. 

P значение 0.733 больше уровня значимость альфа = 0.05, следовательно
гипотеза H0 не может быть отвергнута, а значит по тесту Jarque–Bera
у нас нет достаточных доказательств, чтобы утверждать, что случайные остатки не соответсвует нормальному распределению

№4
x = data['Индекс реальных инвестиций в основной капитал'].to_numpy('float64')
y = data['Индекс реального ВВП'].to_numpy('float64')
residuals = np.array(errors)
df = pd.DataFrame({
   'Индекс реальных инвестиций в основной капитал': x,
    'Индекс реального ВВП': y
})
x= 'Индекс реальных инвестиций в основной капитал'
y = 'Индекс реального ВВП'
df.corr()


graf = pd.DataFrame({
    'ε': residuals,
    'x': df[x]

})
plt.plot(graf['x'], graf['ε'], 'o')
plt.xlabel('x')
plt.ylabel('ε')
plt.title('График зависимости ε от x')
plt.show()

graf = pd.DataFrame({
    'ε^2': residuals**2,
    'x': df[x]

})
plt.plot(graf['x'], graf['ε^2'], 'o')
plt.xlabel('x')
plt.ylabel('ε^2')
plt.title('График зависимости ε^2 от x')
plt.show()

тест ранговой корреляции Спирмена

corr, p_value = sts.spearmanr(residuals, df[x])

print('Коэффициент корреляции Спирмена: ',corr)
print('P-значение: ',p_value)
sts.spearmanr(df[x], df[y])
#Коэффициент ранговой корреляции статистически значим на уровне значимости при п >10, если статистика
t_corr = abs(corr)*(len(df[x])-2)**0.5/(1-corr**2)**0.5
print('t ',t_corr,' >',sts.t.ppf(1 - 0.05/2, len(df[x])))

Тест Голдфелда-Квандта

df_test = pd.DataFrame({x : df[x]})
test_statistic, p_value, _ = het_goldfeldquandt(residuals, df_test)
print('статистика ',test_statistic,' p_value ', p_value)
#p_value > 0,05

sts.f.ppf(1 - 0.05, 1, 40-2)

Тестовая F – статистика не превышает критическое значение . Нулевая гипотеза о гомоскедастичности не отвергается.

park = np.array(df[x])
park2 = np.log(park)
X___ = pd.DataFrame({
    'ln'+x : park2
})
Park= sm.add_constant(X___)
model_yait = sm.OLS(np.log(residuals**2), Park).fit()
summary = model_yait.summary()
summary

Коэффициент перед ln(x) не значим => гетероскедастичности нет

тест Уайта
yait = np.array(df[x])
yait2 = yait**2
X__ = np.vstack((yait, yait2))
X__ = pd.DataFrame({
    x : X__[0],
    x + '^2' :X__[1]
})
Yait = sm.add_constant(X__)
model_yait = sm.OLS(residuals**2, Yait).fit()
summary = model_yait.summary()
summary


# stat = R-квадрат * n
R = 0.045
stat_yiat = len(df[x])*R
stat_yiat

sts.chi2.ppf(1 - 0.05, 2)

№5
X = pd.DataFrame({x : df[x]})
Y = df[y]
mean_x = df[x].mean()

x_p = mean_x * 1.05
X_new = pd.DataFrame({x: [x_p]})
predicted_y = model.predict(X_new)


point_estimate = predicted_y[0]

sigma = np.sqrt(np.sum(residuals**2) / (len(df[x])-1))
se_pred = sigma * np.sqrt(1 + 1/len(df[x])) + (x_p - mean_x)**2 / np.sum((X[x] - mean_x)**2)

t_value = sts.t.ppf(1 - 0.05/2, len(df[x])-1)
interval_estimate = (point_estimate - t_value * se_pred, point_estimate + t_value * se_pred)
print(f"Точечная оценка: {point_estimate}")
print(f"Интервальная оценка (95% доверительный интервал): {interval_estimate}")
"""
