- •Распределение классов прочности
- •Визуализация распределения классов прочности бетона
- •Анализ сбалансированных классов
- •Визуализация взаимосвязей между признаками
- •Предобработка данных
- •Разделение данных и масштабирование
- •Визуализация распределения признаков:
- •Метод kNn для классификации прочности бетона
- •Метод дерева решений для классификации прочности бетона
- •Обучение и оценка дерева решений для классификации бетона
- •Обучение и оценка дерева решений
- •Визуализация дерева решений
- •Кривые для оценки качества классификации бетона
- •Визуализация roc-кривых для классификации прочности бетона
Разделение данных и масштабирование
Программа:
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
print("РАЗДЕЛЕНИЕ ДАННЫХ И МАСШТАБИРОВАНИЕ")
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42, stratify=y
)
print(f"Размеры выборок:")
print(f" Обучающая выборка: X{X_train.shape}, y{y_train.shape}")
print(f" Тестовая выборка: X{X_test.shape}, y{y_test.shape}")
print("\nРаспределение классов прочности:")
def get_class_distribution(y_data, le_encoder):
unique, counts = np.unique(y_data, return_counts=True)
distribution = {}
for cls_idx, count in zip(unique, counts):
cls_name = le_encoder.inverse_transform([cls_idx])[0]
distribution[cls_name] = count
return distribution
train_dist = get_class_distribution(y_train, le_strength)
test_dist = get_class_distribution(y_test, le_strength)
print("Обучающая выборка:")
for cls_name, count in train_dist.items():
percentage = count / len(y_train) * 100
print(f" {cls_name:10}: {count:4} образцов ({percentage:5.1f}%)")
print("\nТестовая выборка:")
for cls_name, count in test_dist.items():
percentage = count / len(y_test) * 100
print(f" {cls_name:10}: {count:4} образцов ({percentage:5.1f}%)")
print("\nМАСШТАБИРОВАНИЕ ПРИЗНАКОВ:")
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
print("Признаки успешно масштабированы с использованием StandardScaler")
print("\nПараметры масштабирования:")
print(f" Средние значения признаков: {scaler.mean_.round(2)}")
print(f" Стандартные отклонения: {scaler.scale_.round(2)}")
print("\nВИЗУАЛИЗАЦИЯ РАСПРЕДЕЛЕНИЯ ПРИЗНАКОВ:")
fig, axes = plt.subplots(3, 3, figsize=(15, 12))
axes = axes.flatten()
features_to_plot = features[:9] if len(features) >= 9 else features
for idx, feature in enumerate(features_to_plot):
if idx < len(axes):
axes[idx].hist(X_train[feature], bins=30, alpha=0.5, label='До', color='blue', density=True)
feature_idx = features.index(feature)
axes[idx].hist(X_train_scaled[:, feature_idx], bins=30, alpha=0.5, label='После', color='red', density=True)
axes[idx].set_title(feature)
axes[idx].set_xlabel('Значение')
axes[idx].set_ylabel('Плотность')
axes[idx].legend()
axes[idx].grid(True, alpha=0.3)
for idx in range(len(features_to_plot), len(axes)):
axes[idx].set_visible(False)
plt.suptitle('СРАВНЕНИЕ РАСПРЕДЕЛЕНИЯ ПРИЗНАКОВ ДО И ПОСЛЕ МАСШТАБИРОВАНИЯ',
fontsize=14, fontweight='bold', y=1.02)
plt.tight_layout()
plt.show()
print("\nСТАТИСТИЧЕСКИЕ ХАРАКТЕРИСТИКИ ДО И ПОСЛЕ МАСШТАБИРОВАНИЯ:")
stats_comparison = []
for i, feature in enumerate(features):
original_mean = X_train[feature].mean()
original_std = X_train[feature].std()
scaled_mean = X_train_scaled[:, i].mean()
scaled_std = X_train_scaled[:, i].std()
stats_comparison.append({
'Признак': feature,
'Исходное среднее': original_mean,
'Исходное ст.откл.': original_std,
'После масштаб. среднее': scaled_mean,
'После масштаб. ст.откл.': scaled_std
})
stats_df = pd.DataFrame(stats_comparison)
print(stats_df.round(2).to_string(index=False))
print("ПРОВЕРКА КОРРЕКТНОСТИ РАЗДЕЛЕНИЯ:")
print("Соотношение классов между выборками:")
total_samples = len(y_train) + len(y_test)
for cls_name in le_strength.classes_:
cls_idx = le_strength.transform([cls_name])[0]
train_count = (y_train == cls_idx).sum()
test_count = (y_test == cls_idx).sum()
total_count = train_count + test_count
train_percentage = train_count / len(y_train) * 100
test_percentage = test_count / len(y_test) * 100
overall_percentage = total_count / total_samples * 100
print(f"\nКласс '{cls_name}':")
print(f" Всего в датасете: {total_count} ({overall_percentage:.1f}%)")
print(f" Обучающая выборка: {train_count} ({train_percentage:.1f}%)")
print(f" Тестовая выборка: {test_count} ({test_percentage:.1f}%)")
print("СОХРАНЕНИЕ РАЗДЕЛЕННЫХ ДАННЫХ:")
train_df = pd.DataFrame(X_train_scaled, columns=[f'{feat}_scaled' for feat in features])
train_df['Strength_Class_encoded'] = y_train.values
train_df['Strength_Class'] = le_strength.inverse_transform(y_train)
test_df = pd.DataFrame(X_test_scaled, columns=[f'{feat}_scaled' for feat in features])
test_df['Strength_Class_encoded'] = y_test.values
test_df['Strength_Class'] = le_strength.inverse_transform(y_test)
print(f"Обучающая выборка сохранена в train_df ({train_df.shape})")
print(f"Тестовая выборка сохранена в test_df ({test_df.shape})")
print("РАЗДЕЛЕНИЕ И МАСШТАБИРОВАНИЕ УСПЕШНО ЗАВЕРШЕНЫ!")
print("\nДанные готовы для обучения моделей машинного обучения.")
Результаты:
РАЗДЕЛЕНИЕ ДАННЫХ И МАСШТАБИРОВАНИЕ
Размеры выборок:
Обучающая выборка: X(721, 8), y(721,)
Тестовая выборка: X(309, 8), y(309,)
Распределение классов прочности:
Обучающая выборка:
Высокая : 265 образцов ( 36.8%)
Низкая : 207 образцов ( 28.7%)
Средняя : 249 образцов ( 34.5%)
Тестовая выборка:
Высокая : 114 образцов ( 36.9%)
Низкая : 88 образцов ( 28.5%)
Средняя : 107 образцов ( 34.6%)
Признаки успешно масштабированы с использованием StandardScaler
Параметры масштабирования:
Средние значения признаков: [279.29 75.58 52.95 181.3 6.25 972.07 774.98 46.94]
Стандартные отклонения: [102.13 86.4 63.51 21.7 5.97 77.34 80.08 66.02]
Разделение данных выполнено стратифицированным методом в соотношении 70/30, что обеспечило практически идентичное распределение классов прочности в обучающей и тестовой выборках (различия <0.2%). Это гарантирует репрезентативность обеих выборок и корректность оценки моделей.
Перед обучением все числовые признаки были стандартизированы с помощью StandardScaler для приведения к единому масштабу (среднее=0, ст.отклонение=1). Данная процедура особенно критична для алгоритма kNN, основанного на вычислении расстояний между объектами. Анализ исходных статистик подтвердил ожидаемую для бетонных смесей вариативность, особенно по содержанию цемента и возрасту образцов.
