import numpy as np import pandas as pd from sklearn.linear_model import LinearRegression from statsmodels.stats.stattools import durbin_watson from scipy import stats import seaborn as sns import matplotlib.pyplot as plt import statsmodels.api as sm # === Загружаем данные === columns = ['Position', 'Height(inches)', 'Weight(pounds)', 'Age'] df = pd.read_csv('SOCR_Data_MLB_HeightsWeights.txt', sep='\t', nrows=115, usecols=columns) # Кодируем категориальный признак "Position" df['Position_num'] = pd.factorize(df['Position'])[0] # === Множественная регрессия (Weight = f(Position, Height, Age)) === X = df[['Position_num', 'Height(inches)', 'Age']] y = df['Weight(pounds)'] model = LinearRegression().fit(X, y) y_pred = model.predict(X) # === Остатки === res2 = y - y_pred # === Проверка нормальности остатков === print('=== Проверка нормальности остатков ===') shapiro_stat, shapiro_p = stats.shapiro(res2) print(f"Статистика Шапиро–Уилка: {shapiro_stat:.4f}, p-value = {shapiro_p:.4f}") if shapiro_p > 0.05: print("→ Остатки распределены нормально (нет оснований отвергнуть H₀).") else: print("→ Остатки не распределены нормально (отвергаем H₀).") # === Графики остатков === plt.figure(figsize=(12, 5)) # Гистограмма plt.subplot(1, 2, 1) sns.histplot(res2, bins=20, kde=True, color='lightblue', edgecolor='black') plt.title('Гистограмма остатков') plt.xlabel('Остатки') # QQ-график plt.subplot(1, 2, 2) sm.qqplot(res2, line='s', ax=plt.gca()) plt.title('QQ-график остатков') plt.tight_layout() plt.show() # === Статистика Дурбина–Уотсона === dw_stat = durbin_watson(res2) # Явный вывод для отчёта print('\n=== Статистика Дурбина–Уотсона ===') print(f"Значение статистики Дурбина–Уотсона: {dw_stat:.4f}") # Интерпретация if dw_stat < 1.5: print("→ Наблюдается положительная автокорреляция остатков.") elif dw_stat > 2.5: print("→ Наблюдается отрицательная автокорреляция остатков.") else: print("→ Автокорреляция остатков отсутствует (остатки независимы).")