318 KiB
Начало лабораторной работы¶
import pandas as pd
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
print(df.columns)
Бизнес-цели¶
- Прогнозирование стоимости страховых взносов:
Цель: Разработать модель, которая будет предсказывать стоимость страховых взносов для новых клиентов на основе их характеристик (возраст, пол, ИМТ, количество детей, статус курения, регион проживания).
Применение: Клиенты могут получить представление о примерной стоимости страховки до обращения в компанию.
- Оптимизация тарифной сетки:
Цель: Определить оптимальные коэффициенты для различных факторов, влияющих на стоимость страховки (например, возраст, ИМТ, статус курения), чтобы максимизировать прибыль компании при сохранении конкурентоспособных тарифов.
Применение: Страховые компании могут использовать эти коэффициенты для корректировки тарифной сетки и повышения эффективности бизнеса.
- Прогнозирование стоимости страховых взносов:
import pandas as pd
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Устанавливаем случайное состояние
random_state = 42
# Рассчитываем среднее значение стоимости страховых взносов
average_charges = df['charges'].mean()
print(f"Среднее значение поля 'charges': {average_charges}")
# Создаем новую переменную, указывающую, превышает ли стоимость страховых взносов среднюю
df['above_average_charges'] = (df['charges'] > average_charges).astype(int)
# Рассчитываем волатильность (разницу между максимальной и минимальной стоимостью страховых взносов)
df['charges_volatility'] = df['charges'].max() - df['charges'].min()
# Выводим первые строки измененной таблицы для проверки
print(df.head())
- Оптимизация тарифной сетки:
import pandas as pd
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Устанавливаем случайное состояние
random_state = 42
# Рассчитываем среднюю стоимость страховых взносов для каждого значения каждого признака
for column in ['age', 'sex', 'bmi', 'children', 'smoker', 'region']:
print(f"Средняя стоимость страховых взносов для '{column}':")
print(df.groupby(column)['charges'].mean())
print()
# Рассчитываем среднюю стоимость страховых взносов для комбинаций признаков
# для комбинации 'age' и 'smoker'
print("Средняя стоимость страховых взносов для комбинации 'age' и 'smoker':")
print(df.groupby(['age', 'smoker'])['charges'].mean())
print()
# Рассчитываем среднюю стоимость страховых взносов для комбинации 'bmi' и 'smoker'
print("Средняя стоимость страховых взносов для комбинации 'bmi' и 'smoker':")
print(df.groupby(['bmi', 'smoker'])['charges'].mean())
print()
# Рассчитываем среднюю стоимость страховых взносов для комбинации 'region' и 'smoker'
print("Средняя стоимость страховых взносов для комбинации 'region' и 'smoker':")
print(df.groupby(['region', 'smoker'])['charges'].mean())
print()
Выбор ориентира для каждой задачи:¶
- Прогнозирование стоимости страховых взносов: Ориентир:
R² (коэффициент детерминации): 0.75 - 0.85
MAE (средняя абсолютная ошибка): 2000 - 3000 долларов
RMSE (среднеквадратичная ошибка): 3000 - 5000 долларов
Объяснение:
R²: Значение 0.75 - 0.85 будет означать, что модель объясняет 75-85% вариации стоимости страховых взносов, что является хорошим результатом для задачи регрессии.
MAE: Значение 2000 - 3000 долларов будет означать, что в среднем модель ошибается на 2000 - 3000 долларов при прогнозировании стоимости страховых взносов.
RMSE: Значение 3000 - 5000 долларов будет означать, что среднеквадратичная ошибка модели составляет 3000 - 4000 долларов.
- Оптимизация тарифной сетки: Ориентир:
Увеличение прибыли компании: 5% - 10%
Сохранение конкурентоспособных тарифов:
Средняя стоимость страховых взносов не должна увеличиваться более чем на 5% по сравнению с текущими тарифами.
Доля клиентов, считающих тарифы дорогими, не должна увеличиваться более чем на 2%.
Объяснение:
Увеличение прибыли компании: Цель оптимизации тарифной сетки - максимизировать прибыль компании. Ориентир в 5% - 10% увеличения прибыли является реалистичным и достижимым.
Сохранение конкурентоспособных тарифов: Важно, чтобы оптимизация тарифной сетки не привела к значительному увеличению стоимости страховых взносов для клиентов. Ориентир в 5% увеличения средней стоимости страховых взносов и 2% увеличения доли клиентов, считающих тарифы дорогими, позволяет сохранить конкурентоспособность компании.
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Преобразуем категориальные переменные в числовые
df = pd.get_dummies(df, columns=['sex', 'smoker', 'region'], drop_first=True)
# Разделяем данные на признаки (X) и целевую переменную (y)
X = df.drop('charges', axis=1)
y = df['charges']
# Разделяем данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Стандартизируем признаки
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# Обучаем модель линейной регрессии
model = LinearRegression()
model.fit(X_train, y_train)
# Делаем предсказания на тестовой выборке
y_pred = model.predict(X_test)
# Оцениваем качество модели
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = mean_squared_error(y_test, y_pred, squared=False)
r2 = r2_score(y_test, y_pred)
print(f"MAE: {mae}")
print(f"MSE: {mse}")
print(f"RMSE: {rmse}")
print(f"R²: {r2}")
# Проверяем, достигнуты ли ориентиры
if r2 >= 0.75 and mae <= 3000 and rmse <= 5000:
print("Ориентиры для прогнозирования стоимости страховых взносов достигнуты!")
else:
print("Ориентиры для прогнозирования стоимости страховых взносов не достигнуты.")
# Оптимизация тарифной сетки
# Убедитесь, что столбцы существуют
columns_to_group = ['age', 'bmi', 'children', 'sex_male', 'smoker_yes', 'region_northwest', 'region_southeast', 'region_southwest']
# Рассчитываем среднюю стоимость страховых взносов для каждого значения каждого признака
for column in columns_to_group:
print(f"Средняя стоимость страховых взносов для '{column}':")
print(df.groupby(column)['charges'].mean())
print()
# Рассчитываем среднюю стоимость страховых взносов для комбинаций признаков
# Например, для комбинации 'age' и 'smoker_yes'
print("Средняя стоимость страховых взносов для комбинации 'age' и 'smoker_yes':")
print(df.groupby(['age', 'smoker_yes'])['charges'].mean())
print()
# Рассчитываем среднюю стоимость страховых взносов для комбинации 'bmi' и 'smoker_yes'
print("Средняя стоимость страховых взносов для комбинации 'bmi' и 'smoker_yes':")
print(df.groupby(['bmi', 'smoker_yes'])['charges'].mean())
print()
# Рассчитываем среднюю стоимость страховых взносов для комбинации 'region_northwest' и 'smoker_yes'
print("Средняя стоимость страховых взносов для комбинации 'region_northwest' и 'smoker_yes':")
print(df.groupby(['region_northwest', 'smoker_yes'])['charges'].mean())
print()
Анализ применимости алгоритмов обучения с учителем для решения поставленных задач:¶
- Прогнозирование стоимости страховых взносов: Задача: Регрессия
Свойства алгоритмов:
Линейная регрессия: Применимость: Хорошо подходит для задач, где зависимость между признаками и целевой переменной линейна. Преимущества: Проста в реализации, интерпретируема. Недостатки: Может плохо работать, если зависимость нелинейна.
Деревья решений (регрессия): Применимость: Подходит для задач с нелинейными зависимостями. Преимущества: Может обрабатывать категориальные признаки, не требует масштабирования данных. Недостатки: Подвержены переобучению, могут давать нестабильные результаты.
Случайный лес (регрессия): Применимость: Хорошо подходит для задач с нелинейными зависимостями и большим количеством признаков. Преимущества: Устойчив к переобучению, может обрабатывать категориальные признаки. Недостатки: Менее интерпретируем, чем линейная регрессия.
Градиентный бустинг (регрессия): Применимость: Подходит для задач с нелинейными зависимостями и сложными взаимосвязями между признаками. Преимущества: Может достигать высокой точности, устойчив к переобучению. Недостатки: Сложнее в настройке, чем случайный лес, менее интерпретируем.
Нейронные сети (регрессия): Применимость: Подходит для задач с очень сложными зависимостями и большим количеством данных. Преимущества: Может моделировать очень сложные зависимости. Недостатки: Требует большого количества данных, сложнее в настройке и интерпретации.
Вывод:
Линейная регрессия: Может быть хорошим выбором для начала, особенно если зависимость между признаками и целевой переменной линейна.
Деревья решений и случайный лес: Подходят для задач с нелинейными зависимостями.
Градиентный бустинг: Может давать более высокую точность, чем случайный лес, но требует больше времени на настройку.
Нейронные сети: Могут быть излишними для этой задачи, если данных недостаточно много.
- Оптимизация тарифной сетки: Задача: Классификация (группировка клиентов по группам риска)
Свойства алгоритмов:
Логистическая регрессия: Применимость: Хорошо подходит для задач бинарной классификации, где зависимость между признаками и целевой переменной линейна. Преимущества: Проста в реализации, интерпретируема. Недостатки: Может плохо работать, если зависимость нелинейна.
Деревья решений (классификация): Применимость: Подходит для задач с нелинейными зависимостями. Преимущества: Может обрабатывать категориальные признаки, не требует масштабирования данных. Недостатки: Подвержены переобучению, могут давать нестабильные результаты.
Случайный лес (классификация): Применимость: Хорошо подходит для задач с нелинейными зависимостями и большим количеством признаков. Преимущества: Устойчив к переобучению, может обрабатывать категориальные признаки. Недостатки: Менее интерпретируем, чем линейная регрессия.
Градиентный бустинг (классификация): Применимость: Подходит для задач с нелинейными зависимостями и сложными взаимосвязями между признаками. Преимущества: Может достигать высокой точности, устойчив к переобучению. Недостатки: Сложнее в настройке, чем случайный лес, менее интерпретируем.
Нейронные сети (классификация): Применимость: Подходит для задач с очень сложными зависимостями и большим количеством данных. Преимущества: Может моделировать очень сложные зависимости. Недостатки: Требует большого количества данных, сложнее в настройке и интерпретации.
Вывод:
Логистическая регрессия: Может быть хорошим выбором для начала, особенно если зависимость между признаками и целевой переменной линейна.
Деревья решений и случайный лес: Подходят для задач с нелинейными зависимостями.
Градиентный бустинг: Может давать более высокую точность, чем случайный лес, но требует больше времени на настройку.
Нейронные сети: Могут быть излишними для этой задачи, если данных недостаточно много.
- Прогнозирование стоимости страховых взносов: Выбранные модели:
Линейная регрессия
Случайный лес (регрессия)
Градиентный бустинг (регрессия)
- Оптимизация тарифной сетки: Выбранные модели:
Логистическая регрессия
Случайный лес (классификация)
Градиентный бустинг (классификация)
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.ensemble import GradientBoostingRegressor, GradientBoostingClassifier
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score, accuracy_score
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Преобразуем категориальные переменные в числовые
df = pd.get_dummies(df, columns=['sex', 'smoker', 'region'], drop_first=True)
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи регрессии
X_reg = df.drop('charges', axis=1)
y_reg = df['charges']
# Разделяем данные на обучающую и тестовую выборки для задачи регрессии
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(X_reg, y_reg, test_size=0.2, random_state=42)
# Стандартизируем признаки для задачи регрессии
scaler_reg = StandardScaler()
X_train_reg = scaler_reg.fit_transform(X_train_reg)
X_test_reg = scaler_reg.transform(X_test_reg)
# Список моделей для задачи регрессии
models_reg = {
"Linear Regression": LinearRegression(),
"Random Forest Regression": RandomForestRegressor(),
"Gradient Boosting Regression": GradientBoostingRegressor()
}
# Обучаем и оцениваем модели для задачи регрессии
print("Результаты для задачи регрессии:")
for name, model in models_reg.items():
model.fit(X_train_reg, y_train_reg)
y_pred_reg = model.predict(X_test_reg)
mae = mean_absolute_error(y_test_reg, y_pred_reg)
mse = mean_squared_error(y_test_reg, y_pred_reg)
rmse = mean_squared_error(y_test_reg, y_pred_reg, squared=False)
r2 = r2_score(y_test_reg, y_pred_reg)
print(f"Model: {name}")
print(f"MAE: {mae}")
print(f"MSE: {mse}")
print(f"RMSE: {rmse}")
print(f"R²: {r2}")
print()
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи классификации
X_class = df.drop('charges', axis=1)
y_class = (df['charges'] > df['charges'].mean()).astype(int)
# Разделяем данные на обучающую и тестовую выборки для задачи классификации
X_train_class, X_test_class, y_train_class, y_test_class = train_test_split(X_class, y_class, test_size=0.2, random_state=42)
# Стандартизируем признаки для задачи классификации
scaler_class = StandardScaler()
X_train_class = scaler_class.fit_transform(X_train_class)
X_test_class = scaler_class.transform(X_test_class)
# Список моделей для задачи классификации
models_class = {
"Logistic Regression": LogisticRegression(),
"Random Forest Classification": RandomForestClassifier(),
"Gradient Boosting Classification": GradientBoostingClassifier()
}
# Обучаем и оцениваем модели для задачи классификации
print("Результаты для задачи классификации:")
for name, model in models_class.items():
model.fit(X_train_class, y_train_class)
y_pred_class = model.predict(X_test_class)
accuracy = accuracy_score(y_test_class, y_pred_class)
print(f"Model: {name}")
print(f"Accuracy: {accuracy}")
print()
- Прогнозирование стоимости страховых взносов: Конвейер для задачи регрессии:
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Определяем категориальные и числовые столбцы
categorical_cols = ['sex', 'smoker', 'region']
numerical_cols = ['age', 'bmi', 'children']
# Создаем преобразователь для категориальных и числовых столбцов
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(), categorical_cols),
('num', StandardScaler(), numerical_cols)
])
# Список моделей для задачи регрессии
models_reg = {
"Linear Regression": LinearRegression(),
"Random Forest Regression": RandomForestRegressor(),
"Gradient Boosting Regression": GradientBoostingRegressor()
}
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи регрессии
X_reg = df[categorical_cols + numerical_cols]
y_reg = df['charges']
# Разделяем данные на обучающую и тестовую выборки для задачи регрессии
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(X_reg, y_reg, test_size=0.2, random_state=42)
# Обучаем и оцениваем модели для задачи регрессии
print("Результаты для задачи регрессии:")
for name, model in models_reg.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
pipeline.fit(X_train_reg, y_train_reg)
y_pred_reg = pipeline.predict(X_test_reg)
mae = mean_absolute_error(y_test_reg, y_pred_reg)
mse = mean_squared_error(y_test_reg, y_pred_reg)
rmse = mean_squared_error(y_test_reg, y_pred_reg, squared=False)
r2 = r2_score(y_test_reg, y_pred_reg)
print(f"Model: {name}")
print(f"MAE: {mae}")
print(f"MSE: {mse}")
print(f"RMSE: {rmse}")
print(f"R²: {r2}")
print()
- Оптимизация тарифной сетки: Конвейер для задачи классификации:
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import accuracy_score
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Определяем категориальные и числовые столбцы
categorical_cols = ['sex', 'smoker', 'region']
numerical_cols = ['age', 'bmi', 'children']
# Создаем преобразователь для категориальных и числовых столбцов
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(), categorical_cols),
('num', StandardScaler(), numerical_cols)
])
# Список моделей для задачи классификации
models_class = {
"Logistic Regression": LogisticRegression(),
"Random Forest Classification": RandomForestClassifier(),
"Gradient Boosting Classification": GradientBoostingClassifier()
}
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи классификации
X_class = df[categorical_cols + numerical_cols]
y_class = (df['charges'] > df['charges'].mean()).astype(int)
# Разделяем данные на обучающую и тестовую выборки для задачи классификации
X_train_class, X_test_class, y_train_class, y_test_class = train_test_split(X_class, y_class, test_size=0.2, random_state=42)
# Обучаем и оцениваем модели для задачи классификации
print("Результаты для задачи классификации:")
for name, model in models_class.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
pipeline.fit(X_train_class, y_train_class)
y_pred_class = pipeline.predict(X_test_class)
accuracy = accuracy_score(y_test_class, y_pred_class)
print(f"Model: {name}")
print(f"Accuracy: {accuracy}")
print()
- Прогнозирование стоимости страховых взносов:
Настройка гиперпараметров для задачи регрессии:
import pandas as pd
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Определяем категориальные и числовые столбцы
categorical_cols = ['sex', 'smoker', 'region']
numerical_cols = ['age', 'bmi', 'children']
# Создаем преобразователь для категориальных и числовых столбцов
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(), categorical_cols),
('num', StandardScaler(), numerical_cols)
])
# Список моделей и их гиперпараметров для задачи регрессии
models_reg = {
"Linear Regression": (LinearRegression(), {}),
"Random Forest Regression": (RandomForestRegressor(), {
'model__n_estimators': [100, 200],
'model__max_depth': [None, 10, 20]
}),
"Gradient Boosting Regression": (GradientBoostingRegressor(), {
'model__n_estimators': [100, 200],
'model__learning_rate': [0.01, 0.1],
'model__max_depth': [3, 5]
})
}
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи регрессии
X_reg = df[categorical_cols + numerical_cols]
y_reg = df['charges']
# Разделяем данные на обучающую и тестовую выборки для задачи регрессии
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(X_reg, y_reg, test_size=0.2, random_state=42)
# Обучаем и оцениваем модели для задачи регрессии
print("Результаты для задачи регрессии:")
for name, (model, params) in models_reg.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
grid_search = GridSearchCV(pipeline, params, cv=5, scoring='neg_mean_absolute_error')
grid_search.fit(X_train_reg, y_train_reg)
best_model = grid_search.best_estimator_
y_pred_reg = best_model.predict(X_test_reg)
mae = mean_absolute_error(y_test_reg, y_pred_reg)
mse = mean_squared_error(y_test_reg, y_pred_reg)
rmse = mean_squared_error(y_test_reg, y_pred_reg, squared=False)
r2 = r2_score(y_test_reg, y_pred_reg)
print(f"Model: {name}")
print(f"Best Parameters: {grid_search.best_params_}")
print(f"MAE: {mae}")
print(f"MSE: {mse}")
print(f"RMSE: {rmse}")
print(f"R²: {r2}")
print()
- Оптимизация тарифной сетки:
Настройка гиперпараметров для задачи классификации:
import pandas as pd
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import accuracy_score
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Определяем категориальные и числовые столбцы
categorical_cols = ['sex', 'smoker', 'region']
numerical_cols = ['age', 'bmi', 'children']
# Создаем преобразователь для категориальных и числовых столбцов
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(), categorical_cols),
('num', StandardScaler(), numerical_cols)
])
# Список моделей и их гиперпараметров для задачи классификации
models_class = {
"Logistic Regression": (LogisticRegression(), {
'model__C': [0.1, 1, 10],
'model__solver': ['liblinear', 'lbfgs']
}),
"Random Forest Classification": (RandomForestClassifier(), {
'model__n_estimators': [100, 200],
'model__max_depth': [None, 10, 20]
}),
"Gradient Boosting Classification": (GradientBoostingClassifier(), {
'model__n_estimators': [100, 200],
'model__learning_rate': [0.01, 0.1],
'model__max_depth': [3, 5]
})
}
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи классификации
X_class = df[categorical_cols + numerical_cols]
y_class = (df['charges'] > df['charges'].mean()).astype(int)
# Разделяем данные на обучающую и тестовую выборки для задачи классификации
X_train_class, X_test_class, y_train_class, y_test_class = train_test_split(X_class, y_class, test_size=0.2, random_state=42)
# Обучаем и оцениваем модели для задачи классификации
print("Результаты для задачи классификации:")
for name, (model, params) in models_class.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
grid_search = GridSearchCV(pipeline, params, cv=5, scoring='accuracy')
grid_search.fit(X_train_class, y_train_class)
best_model = grid_search.best_estimator_
y_pred_class = best_model.predict(X_test_class)
accuracy = accuracy_score(y_test_class, y_pred_class)
print(f"Model: {name}")
print(f"Best Parameters: {grid_search.best_params_}")
print(f"Accuracy: {accuracy}")
print()
- Прогнозирование стоимости страховых взносов: Задача: Регрессия
Выбор метрик:
MAE (Mean Absolute Error): Средняя абсолютная ошибка. Показывает среднее отклонение предсказанных значений от фактических. Эта метрика легко интерпретируется, так как она измеряется в тех же единицах, что и целевая переменная (доллары).
MSE (Mean Squared Error): Среднеквадратичная ошибка. Показывает среднее квадратичное отклонение предсказанных значений от фактических. Эта метрика чувствительна к выбросам, так как ошибки возводятся в квадрат.
RMSE (Root Mean Squared Error): Квадратный корень из среднеквадратичной ошибки. Показывает среднее отклонение предсказанных значений от фактических в тех же единицах, что и целевая переменная. Эта метрика также чувствительна к выбросам, но легче интерпретируется, чем MSE.
R² (R-squared): Коэффициент детерминации. Показывает, какую долю дисперсии целевой переменной объясняет модель. Значение R² близкое к 1 указывает на хорошее качество модели.
Обоснование:
MAE: Хорошо подходит для задач, где важно понимать среднее отклонение предсказаний от фактических значений.
MSE и RMSE: Полезны для задач, где важно минимизировать влияние выбросов, так как они возводят ошибки в квадрат.
R²: Позволяет оценить, насколько хорошо модель объясняет вариацию целевой переменной.
- Оптимизация тарифной сетки: Задача: Классификация
Выбор метрик:
Accuracy: Доля правильных предсказаний среди всех предсказаний. Эта метрика показывает общую точность модели.
Precision: Доля правильных положительных предсказаний среди всех положительных предсказаний. Эта метрика важна, если важно минимизировать количество ложноположительных результатов.
Recall (Sensitivity): Доля правильных положительных предсказаний среди всех фактических положительных случаев. Эта метрика важна, если важно минимизировать количество ложноотрицательных результатов.
F1-score: Гармоническое среднее между precision и recall. Эта метрика показывает баланс между precision и recall.
Обоснование:
Accuracy: Хорошо подходит для задач, где классы сбалансированы.
Precision и Recall: Важны для задач, где важно минимизировать ошибки определенного типа (ложноположительные или ложноотрицательные).
F1-score: Позволяет оценить баланс между precision и recall.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.ensemble import GradientBoostingRegressor, GradientBoostingClassifier
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score, accuracy_score, precision_score, recall_score, f1_score, confusion_matrix, ConfusionMatrixDisplay
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Определяем категориальные и числовые столбцы
categorical_cols = ['sex', 'smoker', 'region']
numerical_cols = ['age', 'bmi', 'children']
# Создаем преобразователь для категориальных и числовых столбцов
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(), categorical_cols),
('num', StandardScaler(), numerical_cols)
])
# Список моделей и их гиперпараметров для задачи регрессии
models_reg = {
"Linear Regression": (LinearRegression(), {}),
"Random Forest Regression": (RandomForestRegressor(), {
'model__n_estimators': [100, 200],
'model__max_depth': [None, 10, 20]
}),
"Gradient Boosting Regression": (GradientBoostingRegressor(), {
'model__n_estimators': [100, 200],
'model__learning_rate': [0.01, 0.1],
'model__max_depth': [3, 5]
})
}
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи регрессии
X_reg = df[categorical_cols + numerical_cols]
y_reg = df['charges']
# Разделяем данные на обучающую и тестовую выборки для задачи регрессии
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(X_reg, y_reg, test_size=0.2, random_state=42)
# Обучаем и оцениваем модели для задачи регрессии
print("Результаты для задачи регрессии:")
for name, (model, params) in models_reg.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
grid_search = GridSearchCV(pipeline, params, cv=5, scoring='neg_mean_absolute_error')
grid_search.fit(X_train_reg, y_train_reg)
best_model = grid_search.best_estimator_
y_pred_reg = best_model.predict(X_test_reg)
mae = mean_absolute_error(y_test_reg, y_pred_reg)
mse = mean_squared_error(y_test_reg, y_pred_reg)
rmse = mean_squared_error(y_test_reg, y_pred_reg, squared=False)
r2 = r2_score(y_test_reg, y_pred_reg)
print(f"Model: {name}")
print(f"Best Parameters: {grid_search.best_params_}")
print(f"MAE: {mae}")
print(f"MSE: {mse}")
print(f"RMSE: {rmse}")
print(f"R²: {r2}")
print()
# Список моделей и их гиперпараметров для задачи классификации
models_class = {
"Logistic Regression": (LogisticRegression(), {
'model__C': [0.1, 1, 10],
'model__solver': ['liblinear', 'lbfgs']
}),
"Random Forest Classification": (RandomForestClassifier(), {
'model__n_estimators': [100, 200],
'model__max_depth': [None, 10, 20]
}),
"Gradient Boosting Classification": (GradientBoostingClassifier(), {
'model__n_estimators': [100, 200],
'model__learning_rate': [0.01, 0.1],
'model__max_depth': [3, 5]
})
}
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи классификации
X_class = df[categorical_cols + numerical_cols]
y_class = (df['charges'] > df['charges'].mean()).astype(int)
# Разделяем данные на обучающую и тестовую выборки для задачи классификации
X_train_class, X_test_class, y_train_class, y_test_class = train_test_split(X_class, y_class, test_size=0.2, random_state=42)
# Обучаем и оцениваем модели для задачи классификации
print("Результаты для задачи классификации:")
for name, (model, params) in models_class.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
grid_search = GridSearchCV(pipeline, params, cv=5, scoring='accuracy')
grid_search.fit(X_train_class, y_train_class)
best_model = grid_search.best_estimator_
y_pred_class = best_model.predict(X_test_class)
accuracy = accuracy_score(y_test_class, y_pred_class)
precision = precision_score(y_test_class, y_pred_class)
recall = recall_score(y_test_class, y_pred_class)
f1 = f1_score(y_test_class, y_pred_class)
print(f"Model: {name}")
print(f"Best Parameters: {grid_search.best_params_}")
print(f"Accuracy: {accuracy}")
print(f"Precision: {precision}")
print(f"Recall: {recall}")
print(f"F1-score: {f1}")
print()
# Визуализация матрицы ошибок
cm = confusion_matrix(y_test_class, y_pred_class)
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=['Less', 'More'])
disp.plot(cmap=plt.cm.Blues)
plt.title(f'Confusion Matrix for {name}')
plt.show()
Давайте проанализируем полученные значения метрик и определим, являются ли они нормальными или их можно улучшить.
Оценка смещения и дисперсии для задачи регрессии:¶
Вывод для задачи регрессии:¶
- Random Forest Regression демонстрирует наилучшие результаты по метрикам MAE и R², что указывает на высокую точность и стабильность модели.
- Linear Regression и Gradient Boosting Regression также показывают хорошие результаты, но уступают случайному лесу.
Вывод для задачи классификации:¶
- Random Forest Classification демонстрирует наилучшие результаты по всем метрикам (Accuracy, Precision, Recall, F1-score), что указывает на высокую точность и стабильность модели.
- Logistic Regression и Gradient Boosting Classification также показывают хорошие результаты, но уступают случайному лесу.
Для оценки смещения (bias) и дисперсии (variance) моделей можно использовать метод перекрестной проверки (cross-validation). Этот метод позволяет оценить, насколько хорошо модель обобщается на новых данных.
Оценка смещения и дисперсии для задачи регрессии: Для задачи регрессии мы будем использовать метрики MAE (Mean Absolute Error) и R² (R-squared) для оценки смещения и дисперсии.
Оценка смещения и дисперсии для задачи классификации: Для задачи классификации мы будем использовать метрики Accuracy, Precision, Recall и F1-score для оценки смещения и дисперсии.
Пример кода для оценки смещения и дисперсии:
import pandas as pd
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.ensemble import GradientBoostingRegressor, GradientBoostingClassifier
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Определяем категориальные и числовые столбцы
categorical_cols = ['sex', 'smoker', 'region']
numerical_cols = ['age', 'bmi', 'children']
# Создаем преобразователь для категориальных и числовых столбцов
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(), categorical_cols),
('num', StandardScaler(), numerical_cols)
])
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи регрессии
X_reg = df[categorical_cols + numerical_cols]
y_reg = df['charges']
# Список моделей для задачи регрессии
models_reg = {
"Linear Regression": LinearRegression(),
"Random Forest Regression": RandomForestRegressor(),
"Gradient Boosting Regression": GradientBoostingRegressor()
}
# Оценка смещения и дисперсии для задачи регрессии
print("Оценка смещения и дисперсии для задачи регрессии:")
for name, model in models_reg.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
mae_scores = -cross_val_score(pipeline, X_reg, y_reg, cv=5, scoring='neg_mean_absolute_error')
r2_scores = cross_val_score(pipeline, X_reg, y_reg, cv=5, scoring='r2')
print(f"Model: {name}")
print(f"MAE (Cross-Validation): Mean = {mae_scores.mean()}, Std = {mae_scores.std()}")
print(f"R² (Cross-Validation): Mean = {r2_scores.mean()}, Std = {r2_scores.std()}")
print()
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи классификации
X_class = df[categorical_cols + numerical_cols]
y_class = (df['charges'] > df['charges'].mean()).astype(int)
# Список моделей для задачи классификации
models_class = {
"Logistic Regression": LogisticRegression(),
"Random Forest Classification": RandomForestClassifier(),
"Gradient Boosting Classification": GradientBoostingClassifier()
}
# Оценка смещения и дисперсии для задачи классификации
print("Оценка смещения и дисперсии для задачи классификации:")
for name, model in models_class.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
accuracy_scores = cross_val_score(pipeline, X_class, y_class, cv=5, scoring='accuracy')
precision_scores = cross_val_score(pipeline, X_class, y_class, cv=5, scoring='precision')
recall_scores = cross_val_score(pipeline, X_class, y_class, cv=5, scoring='recall')
f1_scores = cross_val_score(pipeline, X_class, y_class, cv=5, scoring='f1')
print(f"Model: {name}")
print(f"Accuracy (Cross-Validation): Mean = {accuracy_scores.mean()}, Std = {accuracy_scores.std()}")
print(f"Precision (Cross-Validation): Mean = {precision_scores.mean()}, Std = {precision_scores.std()}")
print(f"Recall (Cross-Validation): Mean = {recall_scores.mean()}, Std = {recall_scores.std()}")
print(f"F1-score (Cross-Validation): Mean = {f1_scores.mean()}, Std = {f1_scores.std()}")
print()
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.ensemble import GradientBoostingRegressor, GradientBoostingClassifier
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
# Загружаем набор данных
df = pd.read_csv("..//static//csv//Medical_insurance.csv")
# Определяем категориальные и числовые столбцы
categorical_cols = ['sex', 'smoker', 'region']
numerical_cols = ['age', 'bmi', 'children']
# Создаем преобразователь для категориальных и числовых столбцов
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(), categorical_cols),
('num', StandardScaler(), numerical_cols)
])
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи регрессии
X_reg = df[categorical_cols + numerical_cols]
y_reg = df['charges']
# Список моделей для задачи регрессии
models_reg = {
"Linear Regression": LinearRegression(),
"Random Forest Regression": RandomForestRegressor(),
"Gradient Boosting Regression": GradientBoostingRegressor()
}
# Оценка смещения и дисперсии для задачи регрессии
mae_means = []
mae_stds = []
r2_means = []
r2_stds = []
for name, model in models_reg.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
mae_scores = -cross_val_score(pipeline, X_reg, y_reg, cv=5, scoring='neg_mean_absolute_error')
r2_scores = cross_val_score(pipeline, X_reg, y_reg, cv=5, scoring='r2')
mae_means.append(mae_scores.mean())
mae_stds.append(mae_scores.std())
r2_means.append(r2_scores.mean())
r2_stds.append(r2_scores.std())
# Визуализация результатов для задачи регрессии
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].bar(models_reg.keys(), mae_means, yerr=mae_stds, align='center', alpha=0.5, ecolor='black', capsize=10)
ax[0].set_ylabel('MAE')
ax[0].set_title('Mean Absolute Error (MAE) for Regression Models')
ax[0].yaxis.grid(True)
ax[1].bar(models_reg.keys(), r2_means, yerr=r2_stds, align='center', alpha=0.5, ecolor='black', capsize=10)
ax[1].set_ylabel('R²')
ax[1].set_title('R-squared (R²) for Regression Models')
ax[1].yaxis.grid(True)
plt.tight_layout()
plt.show()
# Разделяем данные на признаки (X) и целевую переменную (y) для задачи классификации
X_class = df[categorical_cols + numerical_cols]
y_class = (df['charges'] > df['charges'].mean()).astype(int)
# Список моделей для задачи классификации
models_class = {
"Logistic Regression": LogisticRegression(),
"Random Forest Classification": RandomForestClassifier(),
"Gradient Boosting Classification": GradientBoostingClassifier()
}
# Оценка смещения и дисперсии для задачи классификации
accuracy_means = []
accuracy_stds = []
precision_means = []
precision_stds = []
recall_means = []
recall_stds = []
f1_means = []
f1_stds = []
for name, model in models_class.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
accuracy_scores = cross_val_score(pipeline, X_class, y_class, cv=5, scoring='accuracy')
precision_scores = cross_val_score(pipeline, X_class, y_class, cv=5, scoring='precision')
recall_scores = cross_val_score(pipeline, X_class, y_class, cv=5, scoring='recall')
f1_scores = cross_val_score(pipeline, X_class, y_class, cv=5, scoring='f1')
accuracy_means.append(accuracy_scores.mean())
accuracy_stds.append(accuracy_scores.std())
precision_means.append(precision_scores.mean())
precision_stds.append(precision_scores.std())
recall_means.append(recall_scores.mean())
recall_stds.append(recall_scores.std())
f1_means.append(f1_scores.mean())
f1_stds.append(f1_scores.std())
# Визуализация результатов для задачи классификации
fig, ax = plt.subplots(2, 2, figsize=(12, 12))
ax[0, 0].bar(models_class.keys(), accuracy_means, yerr=accuracy_stds, align='center', alpha=0.5, ecolor='black', capsize=10)
ax[0, 0].set_ylabel('Accuracy')
ax[0, 0].set_title('Accuracy for Classification Models')
ax[0, 0].yaxis.grid(True)
ax[0, 1].bar(models_class.keys(), precision_means, yerr=precision_stds, align='center', alpha=0.5, ecolor='black', capsize=10)
ax[0, 1].set_ylabel('Precision')
ax[0, 1].set_title('Precision for Classification Models')
ax[0, 1].yaxis.grid(True)
ax[1, 0].bar(models_class.keys(), recall_means, yerr=recall_stds, align='center', alpha=0.5, ecolor='black', capsize=10)
ax[1, 0].set_ylabel('Recall')
ax[1, 0].set_title('Recall for Classification Models')
ax[1, 0].yaxis.grid(True)
ax[1, 1].bar(models_class.keys(), f1_means, yerr=f1_stds, align='center', alpha=0.5, ecolor='black', capsize=10)
ax[1, 1].set_ylabel('F1-score')
ax[1, 1].set_title('F1-score for Classification Models')
ax[1, 1].yaxis.grid(True)
plt.tight_layout()
plt.show()