import numpy as np import pandas as pd from sklearn.datasets import load_iris from sklearn.linear_model import LinearRegression from statsmodels.stats.stattools import durbin_watson from scipy import stats import matplotlib.pyplot as plt # === Датасет Ирисы Фишера === iris = load_iris() iris_pd = pd.DataFrame(data=np.c_[iris['data'], iris['target']], columns=iris['feature_names'] + ['target']) # === Признаки и целевая переменная === x1 = iris_pd['sepal length (cm)'].values x2 = iris_pd['sepal width (cm)'].values x3 = iris_pd['petal length (cm)'].values x4 = iris_pd['petal width (cm)'].values # целевая переменная # === Парная регрессия: x3 -> x4 === lr = LinearRegression().fit(x3.reshape(-1,1), x4) y_pred1 = lr.predict(x3.reshape(-1,1)) residuals1 = x4 - y_pred1 # === Множественная регрессия: x1,x2,x3 -> x4 === X = np.vstack((x1, x2, x3)).T mr = LinearRegression().fit(X, x4) y_pred2 = mr.predict(X) residuals2 = x4 - y_pred2 # === Графики остатков === fig, axes = plt.subplots(1, 2, figsize=(12,5)) axes[0].hist(residuals1, bins=15, color='lightblue', edgecolor='black') axes[0].set_title('Остатки парной регрессии') axes[1].hist(residuals2, bins=15, color='lightgreen', edgecolor='black') axes[1].set_title('Остатки множественной регрессии') plt.show() # === Проверка нормальности остатков (Shapiro-Wilk) === print("=== Проверка нормальности остатков ===") for i, res in enumerate([residuals1, residuals2], start=1): stat, p = stats.shapiro(res) print(f"Регрессия {i}: Статистика Шапиро–Уилка = {stat:.4f}, p-value = {p:.4f}") if p > 0.05: print("→ Остатки распределены нормально (H0 не отвергается).") else: print("→ Остатки не распределены нормально (H0 отвергается).") # === Статистика Дурбина–Уотсона === from statsmodels.stats.stattools import durbin_watson print("\n=== Статистика Дурбина–Уотсона ===") dw1 = durbin_watson(residuals1) dw2 = durbin_watson(residuals2) print(f"Парная регрессия: DW = {dw1:.4f}") print(f"Множественная регрессия: DW = {dw2:.4f}") # Интерпретация def interpret_dw(dw): if dw < 1.5: return "→ Положительная автокорреляция остатков." elif dw > 2.5: return "→ Отрицательная автокорреляция остатков." else: return "→ Остатки независимы (автокорреляции нет)." print("Парная регрессия:", interpret_dw(dw1)) print("Множественная регрессия:", interpret_dw(dw2))