AI-система для горнодобывающей промышленности
Горная добыча — отрасль с экстремальными условиями, высокими капитальными затратами и низкой маржой при волатильных ценах на сырьё. AI смещает фокус от реактивного устранения поломок к предиктивному управлению активами, от геологических догадок к точным моделям недр, от ручного планирования — к оптимизированным производственным графикам.
Предиктивное обслуживание горного оборудования
Диагностика экскаваторов, буровых установок и конвейеров:
Горное оборудование работает в условиях абразивного износа, ударных нагрузок и пыли. MTBF (mean time between failures) одного карьерного экскаватора — 300–500 часов. Внеплановый простой = потери 1–3 млн руб. в сутки.
import pandas as pd
import numpy as np
from sklearn.ensemble import IsolationForest, GradientBoostingClassifier
from sklearn.preprocessing import StandardScaler
class MiningEquipmentPredictor:
"""Предиктивная диагностика горного оборудования по телеметрии"""
def __init__(self, equipment_id: str, equipment_type: str):
self.equipment_id = equipment_id
self.equipment_type = equipment_type
self.anomaly_detector = IsolationForest(contamination=0.03, n_estimators=200)
self.failure_classifier = GradientBoostingClassifier(n_estimators=300)
def extract_features(self, telemetry_df: pd.DataFrame) -> pd.DataFrame:
"""
Признаки из телеметрии: вибрация, температура, ток, давление.
Сдвиги: 1ч, 4ч, 8ч (смена), 24ч.
"""
features = telemetry_df.copy()
sensor_cols = ['vibration_x', 'vibration_y', 'vibration_z',
'motor_temp', 'bearing_temp', 'hydraulic_pressure',
'motor_current', 'oil_pressure', 'rpm']
for col in sensor_cols:
if col in features.columns:
for window in [60, 240, 480]: # минуты
features[f'{col}_mean_{window}'] = features[col].rolling(window).mean()
features[f'{col}_std_{window}'] = features[col].rolling(window).std()
features[f'{col}_max_{window}'] = features[col].rolling(window).max()
# Тренд: производная
features[f'{col}_trend'] = features[col].diff(60)
# Вибрационные признаки (FFT-статистики если есть raw)
if 'vibration_x' in features.columns:
features['vibration_rms'] = np.sqrt(
features[['vibration_x', 'vibration_y', 'vibration_z']].pow(2).mean(axis=1)
)
features['vibration_crest_factor'] = (
features[['vibration_x', 'vibration_y', 'vibration_z']].abs().max(axis=1) /
(features['vibration_rms'] + 1e-6)
)
return features.dropna()
def detect_anomalies(self, features_df: pd.DataFrame) -> pd.Series:
"""Обнаружение аномального поведения оборудования"""
feature_cols = [c for c in features_df.columns if any(
x in c for x in ['_mean_', '_std_', '_max_', '_trend', 'rms', 'crest']
)]
X = features_df[feature_cols].fillna(0)
scores = self.anomaly_detector.decision_function(X)
return pd.Series(-scores, index=features_df.index, name='anomaly_score')
def predict_failure_probability(self, features_df, horizon_hours=24):
"""P(отказ в течение horizon_hours) → порог 0.7 = предупреждение"""
feature_cols = [c for c in features_df.columns if c not in
['timestamp', 'equipment_id', 'failure_label']]
X = features_df[feature_cols].fillna(0)
proba = self.failure_classifier.predict_proba(X)[:, 1]
return proba
Специфика по типу оборудования:
| Оборудование | Ключевые датчики | Типичные отказы | Предупреждение |
|---|---|---|---|
| Карьерный экскаватор | Вибрация ковша, ток подъёма | Разрушение ковша, отказ КВГ | 12–24 часа |
| Шаровая мельница | Вибрация, шум, крутящий момент | Износ футеровки, торцевые трещины | 24–72 часа |
| Ленточный конвейер | Пробуксовка, смещение ленты | Обрыв ленты, завал роликов | 2–8 часов |
| Буровая установка | Нагрузка на долото, крутящий момент | Прихват бурильной колонны | Реальное время |
| Насосы водоотлива | Давление, вибрация, ток | Кавитация, абразивный износ | 6–24 часа |
Геологическое моделирование и оценка запасов
ML-интерпретация геологических данных:
Традиционный подход: геолог вручную коррелирует скважины. AI автоматизирует интерполяцию и добавляет вероятностную оценку:
from pykrige.ok import OrdinaryKriging
import numpy as np
from sklearn.ensemble import RandomForestRegressor
class OregradePredictor:
"""Прогноз содержания металла в рудном теле"""
def build_grade_model(self, drillhole_data):
"""
drillhole_data: DataFrame с координатами x,y,z и содержанием металла
Метод: Ordinary Kriging для интерполяции + ML для учёта литологии
"""
# Геостатистика: Ordinary Kriging
ok = OrdinaryKriging(
drillhole_data['x'], drillhole_data['y'],
drillhole_data['grade'],
variogram_model='spherical',
variogram_parameters={'sill': drillhole_data['grade'].var(),
'range': 50, # метры
'nugget': 0.1}
)
# Сетка для предсказания
grid_x = np.arange(drillhole_data['x'].min(), drillhole_data['x'].max(), 5)
grid_y = np.arange(drillhole_data['y'].min(), drillhole_data['y'].max(), 5)
z_pred, z_var = ok.execute('grid', grid_x, grid_y)
return {
'grade_grid': z_pred,
'variance_grid': z_var, # неопределённость → где нужны доп. скважины
'grid_x': grid_x,
'grid_y': grid_y
}
def classify_lithology(self, geophysical_logs):
"""
Автоматическая классификация литологии по ГИС (каротажным кривым).
Входные данные: GR (гамма), SP, resistivity, density, neutron
"""
features = ['gr', 'sp', 'res_deep', 'res_shallow', 'density', 'neutron']
X = geophysical_logs[features]
rf = RandomForestRegressor(n_estimators=200)
# Обучение на размеченных интервалах керна
# Предсказание литологии в необсаженных интервалах
return rf
Поиск новых месторождений:
- Мультиспектральные снимки Sentinel-2 + геохимия → аномалии
- Обработка сейсмических данных нейронными сетями (замена ручной интерпретации)
- Transfer learning: модель, обученная на одном месторождении, адаптируется к соседнему за 10–20 дополнительных скважин
Оптимизация горного планирования
Карьерное планирование (Open Pit Scheduling):
Задача: последовательность выемки блоков при ограничениях на борт карьера, производительность, экономику:
from ortools.sat.python import cp_model
def optimize_mining_sequence(blocks, time_periods=12, capacity_per_period=1000000):
"""
Оптимизация последовательности добычи блоков.
blocks: список словарей {id, value, tonnage, predecessors}
Максимизировать NPV с учётом временной стоимости денег.
"""
model = cp_model.CpModel()
discount_rate = 0.10 / 12 # месячная ставка
# Бинарные переменные: добывается ли блок в период t
x = {}
for block in blocks:
for t in range(time_periods):
x[block['id'], t] = model.NewBoolVar(f"x_{block['id']}_{t}")
# Каждый блок добывается не более одного раза
for block in blocks:
model.AddAtMostOne([x[block['id'], t] for t in range(time_periods)])
# Ограничение производительности по периодам
for t in range(time_periods):
model.Add(
sum(x[b['id'], t] * b['tonnage'] for b in blocks) <= capacity_per_period
)
# Предшественники: нельзя добыть блок раньше вышележащего (slope stability)
for block in blocks:
for pred_id in block.get('predecessors', []):
for t in range(time_periods):
pred_extracted_by_t = sum(x[pred_id, tt] for tt in range(t + 1))
model.Add(pred_extracted_by_t >= x[block['id'], t])
# Целевая функция: NPV
objective_terms = []
for block in blocks:
for t in range(time_periods):
discounted_value = int(block['value'] / (1 + discount_rate) ** t)
objective_terms.append(x[block['id'], t] * discounted_value)
model.Maximize(sum(objective_terms))
solver = cp_model.CpSolver()
solver.parameters.max_time_in_seconds = 120
status = solver.Solve(model)
schedule = {}
if status in [cp_model.OPTIMAL, cp_model.FEASIBLE]:
for block in blocks:
for t in range(time_periods):
if solver.Value(x[block['id'], t]):
schedule[block['id']] = t
return schedule
Управление качеством руды (Grade Control)
Реального времени контроль содержания:
- XRF-анализаторы на конвейере + CV → онлайн-анализ руды без лабораторных задержек
- Blending optimization: смешение руды из разных забоев для стабилизации состава на входе обогатительной фабрики
- Динамическая диспетчеризация самосвалов: высококачественная руда → фабрика, бедная → склад/отвал
Оптимизация обогащения:
Процесс флотации — нелинейный, зависит от гранулометрии, реагентов, pH. ML-оптимизация:
from scipy.optimize import differential_evolution
def optimize_flotation_reagents(ore_characteristics, current_recovery=0.82):
"""
Оптимизация дозировки реагентов флотации.
Цель: максимизировать извлечение при минимальном расходе реагентов.
"""
# Суррогатная модель (обучена на исторических данных фабрики)
def flotation_model(reagents):
collector_g_t, frother_g_t, activator_g_t, ph = reagents
# Упрощённая модель (в реальности: LightGBM или GPR)
recovery = (0.75 + 0.08 * np.log(1 + collector_g_t / 50)
+ 0.05 * (1 - abs(ph - 10.5) / 2)
+ 0.02 * np.log(1 + frother_g_t / 20))
cost = collector_g_t * 0.15 + frother_g_t * 0.25 + activator_g_t * 0.10
return -(recovery - 0.001 * cost) # негатив для минимизации
bounds = [(20, 150), # collector г/т
(10, 60), # frother г/т
(0, 80), # activator г/т
(9.5, 11.5)] # pH
result = differential_evolution(flotation_model, bounds, seed=42, maxiter=200)
optimal = result.x
return {
'collector_g_t': optimal[0],
'frother_g_t': optimal[1],
'activator_g_t': optimal[2],
'ph': optimal[3],
'expected_recovery': -result.fun
}
Безопасность и мониторинг среды
AI-мониторинг газовой обстановки (для подземных рудников):
- Мультисенсорные узлы: CH4, CO, CO2, O2, H2S — исторические данные + ML-прогноз концентрации
- Геомеханика: акустическая эмиссия + ML → предупреждение обрушений за 1–6 часов
- Computer Vision на видеопотоках: каска, жилет, нахождение в запрещённой зоне
Экологический мониторинг:
- PM2.5/PM10 от взрывных работ и транспорта → ML прогноз рассеивания с учётом метеоусловий
- Мониторинг гидрохимии хвостохранилища: pH, тяжёлые металлы → автоматические оповещения при превышении ПДК
Срок разработки: 6–9 месяцев для комплексной AI-платформы горнодобывающего предприятия с предиктивной диагностикой, геологическим моделированием и оптимизацией планирования.







