Вы не можете выбрать более 25 тем
Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
119 строки
5.0 KiB
Python
119 строки
5.0 KiB
Python
import numpy as np
|
|
import pandas as pd
|
|
import matplotlib.pyplot as plt
|
|
from sklearn.linear_model import LinearRegression
|
|
from sklearn.metrics import r2_score
|
|
from scipy import stats
|
|
|
|
# === ЗАГРУЗКА ДАННЫХ ===
|
|
columns = ['Position', 'Height(inches)', 'Weight(pounds)', 'Age']
|
|
df = pd.read_csv('SOCR_Data_MLB_HeightsWeights.txt', sep='\t', nrows=115, usecols=columns)
|
|
|
|
# === ПАРНАЯ РЕГРЕССИЯ ===
|
|
# Выходная переменная — вес, входная — рост
|
|
X_single = df['Height(inches)'].values.reshape(-1, 1)
|
|
y = df['Weight(pounds)'].values
|
|
|
|
lr = LinearRegression().fit(X_single, y)
|
|
y_pred_single = lr.predict(X_single)
|
|
res_single = y - y_pred_single
|
|
|
|
# Визуализация
|
|
fig1, axes = plt.subplots(1, 3, figsize=(15, 5))
|
|
fig1.suptitle('Парная регрессия')
|
|
|
|
# 1. Линия регрессии
|
|
axes[0].scatter(df['Height(inches)'], df['Weight(pounds)'], color='blue', alpha=0.6)
|
|
axes[0].plot(df['Height(inches)'], y_pred_single, color='red', linewidth=2)
|
|
axes[0].set_xlabel('Height (inches)')
|
|
axes[0].set_ylabel('Weight (pounds)')
|
|
axes[0].set_title('Линейная зависимость')
|
|
|
|
# 2. Остатки
|
|
axes[1].scatter(y_pred_single, res_single, color='green', alpha=0.6)
|
|
axes[1].axhline(y=0, color='red', linestyle='--')
|
|
axes[1].set_xlabel('Предсказанные значения')
|
|
axes[1].set_ylabel('Остатки')
|
|
axes[1].set_title('Анализ остатков')
|
|
|
|
# 3. Гистограмма остатков
|
|
axes[2].hist(res_single, bins=15, color='gray', edgecolor='black')
|
|
axes[2].set_xlabel('Остатки')
|
|
axes[2].set_ylabel('Количество точек')
|
|
axes[2].set_title('Распределение остатков')
|
|
|
|
# Метрики
|
|
Qreg = np.sum((y_pred_single - y.mean()) ** 2)
|
|
Qres = np.sum((y - y_pred_single) ** 2)
|
|
Qtotal = np.sum((y - y.mean()) ** 2)
|
|
|
|
R2 = r2_score(y, y_pred_single)
|
|
AdjR2 = 1 - (1 - R2) * (115 - 1) / (115 - 1 - 1)
|
|
R = np.sqrt(R2)
|
|
StdErr = np.sqrt(Qres / (115 - 2))
|
|
|
|
print('\n=== Парная регрессия ===')
|
|
print('Коэффициент детерминации R²:', round(R2, 4))
|
|
print('Скорректированный R²:', round(AdjR2, 4))
|
|
print('Множественный коэффициент корреляции R:', round(R, 4))
|
|
print('Стандартная ошибка регрессии:', round(StdErr, 4))
|
|
print('Коэффициенты модели (b0 + b1*x):', lr.intercept_, lr.coef_)
|
|
|
|
# === МНОЖЕСТВЕННАЯ РЕГРЕССИЯ ===
|
|
# Кодируем категориальный признак Position в числовой формат
|
|
position_mapping = {pos: i for i, pos in enumerate(df['Position'].unique())}
|
|
df['Position_num'] = df['Position'].map(position_mapping)
|
|
|
|
# Входные переменные — позиция, рост и возраст
|
|
X_multi = df[['Position_num', 'Height(inches)', 'Age']].values
|
|
|
|
mr = LinearRegression().fit(X_multi, y)
|
|
y_pred_multi = mr.predict(X_multi)
|
|
res_multi = y - y_pred_multi
|
|
|
|
# Визуализация
|
|
fig2, axes = plt.subplots(1, 2, figsize=(12, 5))
|
|
fig2.suptitle('Множественная регрессия')
|
|
|
|
# Остатки
|
|
axes[0].scatter(y_pred_multi, res_multi, color='purple', alpha=0.6)
|
|
axes[0].axhline(y=0, color='red', linestyle='--')
|
|
axes[0].set_xlabel('Предсказанные значения')
|
|
axes[0].set_ylabel('Остатки')
|
|
axes[0].set_title('Анализ остатков')
|
|
|
|
# Гистограмма остатков
|
|
axes[1].hist(res_multi, bins=15, color='orange', edgecolor='black')
|
|
axes[1].set_xlabel('Остатки')
|
|
axes[1].set_ylabel('Количество точек')
|
|
axes[1].set_title('Распределение остатков')
|
|
|
|
# Метрики
|
|
Qreg_m = np.sum((y_pred_multi - y.mean()) ** 2)
|
|
Qres_m = np.sum((y - y_pred_multi) ** 2)
|
|
|
|
R2_m = r2_score(y, y_pred_multi)
|
|
AdjR2_m = 1 - (1 - R2_m) * (115 - 1) / (115 - 3 - 1)
|
|
R_m = np.sqrt(R2_m)
|
|
StdErr_m = np.sqrt(Qres_m / (115 - 3 - 1))
|
|
|
|
print('\n=== Множественная регрессия ===')
|
|
print('Коэффициент детерминации R²:', round(R2_m, 4))
|
|
print('Скорректированный R²:', round(AdjR2_m, 4))
|
|
print('Множественный коэффициент корреляции R:', round(R_m, 4))
|
|
print('Стандартная ошибка регрессии:', round(StdErr_m, 4))
|
|
print('Коэффициенты модели:', mr.intercept_, mr.coef_)
|
|
|
|
plt.tight_layout()
|
|
plt.show()
|
|
|
|
# === КРАТКИЕ ВЫВОДЫ ===
|
|
print('\n=== ВЫВОДЫ ===')
|
|
print('1. Парная регрессия показывает умеренную связь между ростом и весом (R ≈', round(R, 2), ').')
|
|
print('2. Множественная регрессия с учётом возраста и позиции улучшает качество модели (R² выше).')
|
|
print('3. Остатки распределены примерно нормально, значимых выбросов немного.')
|
|
print('4. Наиболее информативные переменные: рост и возраст.')
|
|
|
|
|
|
|