AI system for the mining industry
Mining is an industry with extreme conditions, high capital expenditures, and low margins amid volatile commodity prices. AI is shifting the focus from reactive breakdown repair to predictive asset management, from geological guesswork to precise subsurface models, and from manual planning to optimized production schedules.
Predictive maintenance of mining equipment
Diagnostics of excavators, drilling rigs and conveyors:
Mining equipment operates in conditions of abrasive wear, impact loads, and dust. The mean time between failures (MTBF) of a single quarry excavator is 300–500 hours. Unscheduled downtime results in losses of 1–3 million rubles per day.
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
Specifics by equipment type:
| Оборудование | Ключевые датчики | Типичные отказы | Предупреждение |
|---|---|---|---|
| Карьерный экскаватор | Вибрация ковша, ток подъёма | Разрушение ковша, отказ КВГ | 12–24 часа |
| Шаровая мельница | Вибрация, шум, крутящий момент | Износ футеровки, торцевые трещины | 24–72 часа |
| Ленточный конвейер | Пробуксовка, смещение ленты | Обрыв ленты, завал роликов | 2–8 часов |
| Буровая установка | Нагрузка на долото, крутящий момент | Прихват бурильной колонны | Реальное время |
| Насосы водоотлива | Давление, вибрация, ток | Кавитация, абразивный износ | 6–24 часа |
Geological modeling and reserve assessment
ML interpretation of geological data:
The traditional approach: a geologist manually correlates wells. AI automates the interpolation and adds probabilistic assessment:
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
Search for new deposits:
- Multispectral Sentinel-2 images + geochemistry → anomalies - Processing of seismic data with neural networks (replacing manual interpretation) - Transfer learning: a model trained on one field adapts to a neighboring one in 10–20 additional wells
Optimization of mine planning
Career Planning (Open Pit Scheduling):
Task: sequence of block extraction under quarry wall constraints, productivity, economics:
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
Real-time content control:
- XRF analyzers on the conveyor + CV → online ore analysis without laboratory delays - Blending optimization: mixing ore from different faces to stabilize the composition at the entrance to the processing plant - Dynamic dispatching of dump trucks: high-quality ore → plant, low-grade ore → stockpile/dump
Enrichment Optimization:
The flotation process is nonlinear and depends on particle size distribution, reagents, and pH. ML optimization:
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
}
Security and environmental monitoring
AI-monitoring of gas conditions (for underground mines):
- Multisensor nodes: CH4, CO, CO2, O2, H2S — historical data + ML-prediction of concentration - Geomechanics: acoustic emission + ML → collapse warning in 1–6 hours - Computer Vision on video streams: helmet, vest, presence in a prohibited area
Environmental monitoring:
- PM2.5/PM10 from blasting operations and transport → ML dispersion forecast taking into account weather conditions - Monitoring the hydrochemistry of the tailings storage facility: pH, heavy metals → automatic alerts when the maximum permissible concentration is exceeded
Development timeline: 6-9 months for a comprehensive mining AI platform with predictive diagnostics, geological modeling, and planning optimization.







