AI System for Mining Industry

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1 servicesAll 1566 services
AI System for Mining Industry
Complex
from 2 weeks to 3 months
FAQ
AI Development Areas
AI Solution Development Stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823
  • image_logo-aider_0.jpg
    AIDER company logo development
    762
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    848

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.