Молекулы состоят из атомов, связанных химическими связями, и их поведение зависит от энергии. Энергия молекулы определяется её структурой, например, расстояниями между атомами и углами связей. Представьте, что молекула — это пружинная система, где энергия зависит от того, как "растянуты" или "сжаты" связи.
Цель: Использовать машинное обучение, чтобы предсказать энергию молекулы (в условных единицах) на основе её геометрических характеристик, таких как длины связей и углы. Это задача регрессии, где мы предсказываем число (энергию), а не категорию.
Машинное обучение — это метод, который позволяет компьютеру находить закономерности в данных. В нашем случае:
- Данные: Таблица с характеристиками молекул (длины связей, углы) и их энергией.
- Задача: Научить модель предсказывать энергию молекулы по её геометрическим признакам.
- Этапы:
- Загрузка и обработка данных.
- Преобразование геометрических данных в числовые признаки.
- Обучение модели ML.
- Оценка модели и визуализация результатов.
Основные шаги
- Загрузка данных: Получаем таблицу с геометрическими характеристиками молекул и их энергией.
- Предобработка: Преобразуем данные в числовой формат, подходящий для ML.
- Обучение модели: Используем алгоритм ML (например, линейную регрессию) для предсказания энергии.
- Визуализация: Строим графики, чтобы оценить точность модели.
- Анализ данных: Используем Pandas для исследования закономерностей.
Для простоты мы создадим датасет внутри кода, но вы можете использовать реальные данные из баз, таких как QM9, которые содержат информацию о молекулах.
Этапы работы код:
- Создание датасета:
- Мы создали синтетический датасет с 10 молекулами. Для каждой молекулы указаны:
- Длина связи (Bond_Length, в ангстремах).
- Угол связи (Bond_Angle, в градусах).
- Энергия (Energy, в условных единицах).
- В реальной жизни такие данные можно получить из баз, например, QM9.
- Предобработка:
- Выбираем числовые признаки (длина и угол связи) для модели ML.
- Разделение данных:
- Делим данные на обучающую (70%) и тестовую (30%) выборки, чтобы проверить модель.
- Обучение модели:
- Используем линейную регрессию — простой алгоритм ML для предсказания чисел (энергии).
- Оценка модели:
- Считаем среднеквадратичную ошибку (MSE) — меру, насколько предсказания отличаются от истины.
- Считаем R² — показатель, насколько модель объясняет данные (чем ближе к 1, тем лучше).
- Визуализация:
- Сравнение предсказаний: Точечный график, показывающий истинные и предсказанные энергии.
- Важность признаков: Гистограмма, показывающая, как длина и угол влияют на энергию.
- Зависимость энергии: График, показывающий, как энергия зависит от длины связи, с цветом по углу.
- Матрица корреляции: Тепловая карта, показывающая связи между признаками и энергией.
- Анализ данных:
- Считаем средние значения признаков и корреляцию между ними с помощью Pandas.
Вывод:
- Файл energy_prediction.png: График, сравнивающий истинные и предсказанные энергии.
- Файл feature_importance.png: Гистограмма, показывающая важность длины и угла связи.
- Файл energy_vs_length.png: График зависимости энергии от длины связи.
- Файл correlation_matrix.png: Тепловая карта корреляции между признаками.
- Вывод в консоли: Ошибка модели, R², средние значения признаков и корреляционная матрица.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
import seaborn as sns
# 1. Создаем синтетический датасет
# Признаки: длина связи (Bond_Length, Å), угол связи (Bond_Angle, градусы)
# Целевая переменная: энергия молекулы (Energy, условные единицы)
data = {
'Bond_Length': [1.2, 1.3, 1.1, 1.4, 1.2, 1.5, 1.3, 1.1, 1.4, 1.2],
'Bond_Angle': [120, 110, 115, 105, 118, 100, 112, 108, 106, 119],
'Energy': [50.2, 55.1, 48.7, 60.3, 51.0, 65.4, 56.2, 49.0, 61.5, 50.8]
}
df = pd.DataFrame(data)
# 2. Предобработка
# Выбираем признаки для модели
features = df[['Bond_Length', 'Bond_Angle']]
target = df['Energy']
# 3. Разделение данных на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(features, target, test_size=0.3, random_state=42)
# 4. Обучение модели линейной регрессии
model = LinearRegression()
model.fit(X_train, y_train)
# 5. Предсказание и оценка
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"Mean Squared Error (MSE): {mse:.2f}")
print(f"R^2 Score: {r2:.2f}")
# 6. Визуализация: сравнение предсказанных и истинных значений
plt.figure(figsize=(6, 4))
plt.scatter(y_test, y_pred, color='blue', s=100)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('True Energy (u.e.)')
plt.ylabel('Predicted Energy (u.e.)')
plt.title('True vs Predicted Molecular Energy')
plt.savefig('energy_prediction.png')
plt.close()
# Визуализация: важность признаков
feature_importance = pd.Series(model.coef_, index=features.columns)
plt.figure(figsize=(6, 4))
feature_importance.plot(kind='bar', color='skyblue')
plt.xlabel('Feature')
plt.ylabel('Coefficient (Importance)')
plt.title('Feature Importance for Energy Prediction')
plt.savefig('feature_importance.png')
plt.close()
# Визуализация: зависимость энергии от длины связи
plt.figure(figsize=(8, 6))
scatter = plt.scatter(df['Bond_Length'], df['Energy'], c=df['Bond_Angle'], cmap='viridis', s=100)
plt.colorbar(scatter, label='Bond Angle (degrees)')
plt.xlabel('Bond Length (Å)')
plt.ylabel('Energy (u.e.)')
plt.title('Energy vs Bond Length (Colored by Bond Angle)')
plt.savefig('energy_vs_length.png')
plt.close()
# 7. Анализ данных с Pandas
# Средние значения признаков
print("\nAverage values of features:")
print(df[['Bond_Length', 'Bond_Angle']].mean())
# Корреляция между признаками и энергией
correlation = df.corr()
print("\nCorrelation matrix:")
print(correlation)
# Визуализация корреляции
plt.figure(figsize=(6, 4))
sns.heatmap(correlation, annot=True, cmap='coolwarm', vmin=-1, vmax=1)
plt.title('Correlation Matrix')
plt.savefig('correlation_matrix.png')
plt.close()
Задания для практики
- Добавьте в датасет ещё один признак, например, массу молекулы, и проверьте, как это влияет на точность.
- Постройте график зависимости энергии от угла связи (аналогично energy_vs_length.png).
- Попробуйте другой алгоритм ML, например, RandomForestRegressor из sklearn, и сравните результаты.