Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab3_3352_ГарееваКР.docx
Скачиваний:
0
Добавлен:
24.01.2026
Размер:
60.95 Mб
Скачать

Разделение данных и масштабирование

Программа:

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, основанного на вычислении расстояний между объектами. Анализ исходных статистик подтвердил ожидаемую для бетонных смесей вариативность, особенно по содержанию цемента и возрасту образцов.