90 KiB
Diamonds Prices¶
import pandas as pd
df = pd.read_csv(".//static//csv//Diamonds Prices2022.csv")
attributes = df.columns
for attribute in attributes:
print(attribute)
Бизнес-цели¶
1. Определение цены алмаза на основе его характеристик
Бизнес-цель: Разработать модель, которая позволяет прогнозировать цену алмаза на основе его характеристик (таких как карат, чистота, цвет и огранка).
Техническая цель: Создать и обучить модель машинного обучения, которая принимает на вход параметры алмаза и выдает предсказанную цену. Цель — минимизация ошибки предсказания.
2. Классификация качества алмаза на основе характеристик
Бизнес-цель: Определить качество алмаза (например, высокая, средняя, низкая) на основе его характеристик для автоматической сортировки.
Техническая цель: Создать модель классификации, которая принимает на вход характеристики алмаза и присваивает ему категорию качества. Цель — максимизация точности классификации.
Подготовка данных¶
import numpy as np
# Проверка на пропущенные значения
missing_data = df.isnull().sum()
print("Пропущенные данные по каждому столбцу:")
print(missing_data)
Пропущенных значений не найдено
Разбиение каждого набора данных на обучающую, контрольную и тестовую выборки¶
import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
# Разделение признаков (features) и целевой переменной (target)
X = df.drop(columns=['price']) # Признаки (все столбцы, кроме 'price')
y = df['price'] # Целевая переменная (цена)
# Разбиение на обучающую (60%), валидационную (20%) и тестовую (20%) выборки
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
# Проверка размеров выборок
print(f"Размеры выборок:")
print(f"Обучающая выборка: {X_train.shape[0]} записей")
print(f"Валидационная выборка: {X_val.shape[0]} записей")
print(f"Тестовая выборка: {X_test.shape[0]} записей")
# Визуализация распределения цен в каждой выборке
plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1)
plt.hist(y_train, bins=30, color='blue', alpha=0.7)
plt.title('Обучающая выборка')
plt.xlabel('Цена')
plt.ylabel('Количество')
plt.show()
Данные не сбалансированы, так как существует большая разница в количестве наблюдений для разных диапазонов цен. Это может привести к тому, что модель будет хуже предсказывать цены для более дорогих алмазов, так как таких данных меньше. Применим методы приращения.
import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from imblearn.under_sampling import RandomUnderSampler
from imblearn.over_sampling import SMOTE
# Разделение признаков (features) и целевой переменной (target)
X = df.drop(columns=['price']) # Признаки (все столбцы, кроме 'price')
y = df['price'] # Целевая переменная (цена)
# Применение one-hot encoding для категориальных признаков
X = pd.get_dummies(X, drop_first=True)
# Разбиение на обучающую (60%), валидационную (20%) и тестовую (20%) выборки
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
# Проверка размеров выборок
print(f"Размеры выборок:")
print(f"Обучающая выборка: {X_train.shape[0]} записей")
print(f"Валидационная выборка: {X_val.shape[0]} записей")
print(f"Тестовая выборка: {X_test.shape[0]} записей")
# Применение RandomUnderSampler для уменьшения размеров больших классов
undersampler = RandomUnderSampler(random_state=42)
X_undersampled, y_undersampled = undersampler.fit_resample(X_train, y_train)
# Применение SMOTE для увеличения сбалансированности
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X_undersampled, y_undersampled)
# Визуализация распределения цен в сбалансированной выборке
plt.figure(figsize=(10, 6))
plt.hist(y_resampled, bins=30, color='orange', alpha=0.7)
plt.title('Сбалансированная обучающая выборка')
plt.xlabel('Цена')
plt.ylabel('Количество')
plt.show()
Теперь данные намного более сбаланчированные.
Конструировании признаков¶
- Унитарное кодирование категориальных признаков (One-Hot Encoding)
Унитарное кодирование уже было пременено. Выведем имеющиеся столбцы
import pandas as pd
df1 = pd.read_csv(".//static//csv//Diamonds Prices2022.csv")
print("Данные до унитарного кодирования:")
print(df1.head())
# Применение унитарного кодирования для категориальных признаков
df_encoded = pd.get_dummies(df1, drop_first=True)
print("\nДанные после унитарного кодирования:")
print(df_encoded.head())
Видим что данные изменились.
- Дискретизация числовых признаков
import pandas as pd
df1 = pd.read_csv(".//static//csv//Diamonds Prices2022.csv")
print("Данные до дискретизации:")
print(df1.head())
bins = [0, 5000, 10000, 15000, 20000]
labels = ['0-5k', '5k-10k', '10k-15k', '15k-20k']
df1['price_bins'] = pd.cut(df1['price'], bins=bins, labels=labels, right=False)
print("\nДанные после дискретизации:")
print(df1[['price', 'price_bins']].head())
Видим, что данные изменились.
3. «Ручной» синтез признаков¶
import pandas as pd
# Загрузка данных
df1 = pd.read_csv(".//static//csv//Diamonds Prices2022.csv")
# Проверка первых строк данных
print("Данные до синтеза признака:")
print(df1.head())
# Создание нового признака 'price_per_carat' (цена за караты)
df1['price_per_carat'] = df1['price'] / df1['carat']
# Проверка первых строк данных после синтеза признака
print("\nДанные после синтеза признака 'price_per_carat':")
print(df1[['price', 'carat', 'price_per_carat']].head())
4. масштабирование признаков на основе нормировки и стандартизации.¶
import pandas as pd
from sklearn.preprocessing import MinMaxScaler, StandardScaler
df1 = pd.read_csv(".//static//csv//Diamonds Prices2022.csv")
# Создание нового признака 'price_per_carat' (цена за караты)
df1['price_per_carat'] = df1['price'] / df1['carat']
# Проверка первых строк данных до масштабирования
print("Данные до масштабирования:")
print(df1[['price', 'carat', 'price_per_carat']].head())
# Масштабирование признаков на основе нормировки
min_max_scaler = MinMaxScaler()
df1[['price', 'carat', 'price_per_carat']] = min_max_scaler.fit_transform(df1[['price', 'carat', 'price_per_carat']])
# Проверка первых строк данных после нормировки
print("\nДанные после нормировки:")
print(df1[['price', 'carat', 'price_per_carat']].head())
# Стандартизация признаков
standard_scaler = StandardScaler()
df1[['price', 'carat', 'price_per_carat']] = standard_scaler.fit_transform(df1[['price', 'carat', 'price_per_carat']])
# Проверка первых строк данных после стандартизации
print("\nДанные после стандартизации:")
print(df1[['price', 'carat', 'price_per_carat']].head())
конструирование признаков с применением фреймворка Featuretools.
import pandas as pd
import featuretools as ft
df1 = pd.read_csv(".//static//csv//Diamonds Prices2022.csv")
# Создание нового признака 'price_per_carat'
df1['price_per_carat'] = df1['price'] / df1['carat']
# Создание EntitySet
es = ft.EntitySet(id='diamonds')
# Добавление данных
es = es.add_dataframe(dataframe_name='diamonds_data', dataframe=df1, index='index')
# Конструирование признаков
features, feature_defs = ft.dfs(entityset=es, target_dataframe_name='diamonds_data', verbose=True)
# Проверка первых строк новых признаков
print("Новые признаки, созданные с помощью Featuretools:")
print(features.head())
Оценка качества¶
import pandas as pd
import time
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import numpy as np
# Загрузка данных
df1 = pd.read_csv(".//static//csv//Diamonds Prices2022.csv")
# Создание нового признака 'price_per_carat'
df1['price_per_carat'] = df1['price'] / df1['carat']
# Унитарное кодирование
X = pd.get_dummies(df1.drop(columns=['price']), drop_first=True)
y = df1['price']
# Разделение на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Оценка качества
def evaluate_model(X_train, X_test, y_train, y_test):
model = LinearRegression()
# Измерение времени обучения
start_time = time.time()
model.fit(X_train, y_train)
training_time = time.time() - start_time
# Прогнозирование
y_pred = model.predict(X_test)
# Оценка метрик
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# Корреляция
correlation = np.corrcoef(y_test, y_pred)[0, 1]
print(f"Время обучения: {training_time:.4f} секунд")
print(f"MAE: {mae:.2f}")
print(f"MSE: {mse:.2f}")
print(f"R^2: {r2:.2f}")
print(f"Корреляция: {correlation:.2f}")
# Оценка качества набора признаков
evaluate_model(X_train, X_test, y_train, y_test)
# Дополнительно: оценка надежности с помощью кросс-валидации
from sklearn.model_selection import cross_val_score
cv_scores = cross_val_score(LinearRegression(), X, y, cv=5, scoring='neg_mean_squared_error')
print(f"Среднее MSE (кросс-валидация): {-np.mean(cv_scores):.2f}")
Вывод:
Время обучения:
Время обучения модели составляет 0.0694 секунды, что является очень коротким. Это указывает на то, что модель обучается быстро и может эффективно обрабатывать данные.
Предсказательная способность:
MAE (Mean Absolute Error): 352.05 — это средняя абсолютная ошибка предсказаний модели. Значение MAE относительно невелико, что означает, что предсказанные значения в среднем отклоняются от реальных на 352.05. Это может быть приемлемым уровнем ошибки.
MSE (Mean Squared Error): 363100.29 — это среднее значение квадратов ошибок. Хотя MSE высокое, оно также может быть связано с большими значениями целевой переменной (цен).
R² (коэффициент детерминации): 0.98 — это очень высокий уровень, указывающий на то, что модель объясняет 98% вариации целевой переменной. Это свидетельствует о высокой предсказательной способности модели.
Корреляция:
Корреляция (0.99) между предсказанными и реальными значениями говорит о том, что предсказания модели имеют очень сильную линейную зависимость с реальными значениями. Это подтверждает, что модель хорошо обучена и делает точные прогнозы.
Надежность (кросс-валидация):
Среднее MSE (кросс-валидация): 885042.98 — это значительно выше, чем обычное MSE, что может указывать на потенциальные проблемы с переобучением. Модель может хорошо работать на обучающих данных, но ее производительность на новых данных (или в реальных условиях) может быть менее стабильной.