Binom.AutoML.IPCClient 1.1.5

There is a newer version of this package available.
See the version list below for details.
dotnet add package Binom.AutoML.IPCClient --version 1.1.5
                    
NuGet\Install-Package Binom.AutoML.IPCClient -Version 1.1.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Binom.AutoML.IPCClient" Version="1.1.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Binom.AutoML.IPCClient" Version="1.1.5" />
                    
Directory.Packages.props
<PackageReference Include="Binom.AutoML.IPCClient" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Binom.AutoML.IPCClient --version 1.1.5
                    
#r "nuget: Binom.AutoML.IPCClient, 1.1.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Binom.AutoML.IPCClient@1.1.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Binom.AutoML.IPCClient&version=1.1.5
                    
Install as a Cake Addin
#tool nuget:?package=Binom.AutoML.IPCClient&version=1.1.5
                    
Install as a Cake Tool

Binom.AutoML IPC Клиент

Версия: 1.1.2 Статус: Стабильный .NET: Standard 2.1 Протокол: Named Pipes с MessagePack сериализацией

Добро пожаловать в исчерпывающую документацию по Binom.AutoML.IPCClient. Этот клиент предоставляет современный, объектно-ориентированный .NET-интерфейс для взаимодействия с основным приложением Binom.AutoML через межпроцессное взаимодействие (IPC), позволяя полностью управлять жизненным циклом AutoML экспериментов.

📋 Содержание

  1. Начало работы
  2. Основные концепции
  3. Builder паттерны
  4. Типы экспериментов
  5. Алгоритмы машинного обучения
  6. Метрики оптимизации
  7. Продвинутые настройки
  8. Жизненный цикл эксперимента
  9. Управление данными
  10. События и мониторинг
  11. Предсказания
  12. Управление соединением
  13. Обработка ошибок
  14. Продвинутые примеры

1. Начало работы

1.1. Установка и зависимости

На данный момент клиент распространяется как часть основного решения. Просто добавьте ссылку на проект Binom.AutoML.IPCClient в вашем приложении.

Зависимости:

<PackageReference Include="Binom.AutoML.Contracts" Version="1.1.3" />
<PackageReference Include="PipeMethodCalls" Version="4.0.2" />
<PackageReference Include="PipeMethodCalls.MessagePack" Version="3.0.2" />

1.2. Базовое подключение к серверу

Основной точкой входа для взаимодействия с клиентом является класс BinomAutoMLClient.

using Binom.AutoML.IPCClient;
using System.Threading.Tasks;

// 1. Реализуйте или используйте существующий логгер
public class ConsoleLogger : IClientLogger
{
    public void LogDebug(string message, params object[] args) => 
        Console.WriteLine($"[DEBUG] {string.Format(message, args)}");
    public void LogError(Exception exception, string message, params object[] args) => 
        Console.WriteLine($"[ERROR] {string.Format(message, args)}\nException: {exception}");
    public void LogInformation(string message, params object[] args) => 
        Console.WriteLine($"[INFO] {string.Format(message, args)}");
    public void LogWarning(string message, params object[] args) => 
        Console.WriteLine($"[WARN] {string.Format(message, args)}");
}

public class MyApp
{
    private static BinomAutoMLClient? _client;
    private static readonly CancellationTokenSource Cts = new();

    public static async Task Main(string[] args)
    {
        var logger = new ConsoleLogger();
        
        // Создаем клиент с опциями
        var options = new BinomAutoMLClientOptions
        {
            Logger = logger,
            DiscoveryPipeName = "binom-automl-discovery" // Можно настроить
        };
        
        _client = new BinomAutoMLClient(options);

        // Примечание: событие ConnectionStatusChanged отсутствует в текущей версии
        // Для мониторинга статуса используйте свойство _client.CurrentStatus

        try
        {
            await _client.ConnectAsync(Cts.Token);
            logger.LogInformation("Successfully connected to Binom.AutoML server");
            
            // Запускаем полный цикл работы с экспериментом
            await RunFullExperimentCycleAsync(Cts.Token);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Failed to connect or operate.");
        }
        finally
        {
            if (_client != null)
            {
                await _client.DisconnectAsync();
                _client.Dispose();
            }
        }
    }
    
    // Пример полного цикла будет определен в следующем разделе
    public static async Task RunFullExperimentCycleAsync(CancellationToken cancellationToken)
    {
        // Будет реализован ниже
    }
}

1.3. Конфигурация клиента

BinomAutoMLClientOptions:

var options = new BinomAutoMLClientOptions
{
    // Имя pipe для обнаружения сервера
    DiscoveryPipeName = "custom-automl-discovery",
    
    // Пользовательский логгер (опционально)
    Logger = new CustomLogger()
};

var client = new BinomAutoMLClient(options);

2. Основные концепции

2.1. ConnectionStatusDto - Статусы соединения

public enum ConnectionStatusDto
{
    Disconnected,    // Не подключен
    Connecting,      // Подключается
    Connected,       // Подключен
    Error           // Ошибка соединения
}

2.2. OperationResultDto - Результаты операций

Все асинхронные операции возвращают OperationResultDto<T>:

public record OperationResultDto<T>(
    bool IsSuccess,           // Успешность операции
    T? Value,                // Возвращаемое значение
    string? ErrorMessage,     // Сообщение об ошибке
    int ErrorCode            // Код ошибки
);

// Шаблон использования
var result = await client.CreateExperimentAsync(settings, cancellationToken);
if (result.IsSuccess)
{
    var experiment = result.Value;
    // Работаем с экспериментом
}
else
{
    Console.WriteLine($"Error: {result.ErrorMessage}");
}

2.3. ExperimentStatusDto - Статусы эксперимента

public enum ExperimentStatusDto
{
    Created,              // Создан
    DataLoading,          // Загрузка данных
    DataProcessing,       // Обработка данных
    ReadyForTraining,     // Готов к обучению
    Training,             // Обучение в процессе
    Cancelling,           // Отмена обучения
    TrainingCompleted,    // Обучение завершено
    Failed,               // Ошибка
    Cancelled            // Отменен
}

3. Builder паттерны

Builder паттерны предоставляют удобный Fluent API для создания экспериментов с правильными настройками.

3.1. BaseExperimentLayoutBuilder

Основной билдер для создания любого типа эксперимента:

var client = new BinomAutoMLClient(logger);
await client.ConnectAsync(cancellationToken);

// Создаем базовый билдер
var experiment = await new BaseExperimentLayoutBuilder(client)
    .SetExperimentName("My ML Experiment")
    .SetOwnerID("user-123")
    .ForRegressionTask()  // или ForBinaryClassificationTask() или ForMulticlassClassificationTask()
    .SendToServerAsync(cancellationToken);

3.2. RegressionExperimentLayoutBuilder

Билдер специально для регрессионных задач:

var regressionExperiment = await new BaseExperimentLayoutBuilder(client)
    .SetExperimentName("House Price Prediction")
    .SetOwnerID("data-scientist")
    .ForRegressionTask()
    .SetOptimizationMetric(RegressionOptimizingMetricDto.RSquared)
    .WithAllowedTrainers(new List<RegressionTrainerDto>
    {
        RegressionTrainerDto.LightGbm,
        RegressionTrainerDto.FastTree,
        RegressionTrainerDto.Gam
    })
    .SendToServerAsync(cancellationToken);

3.3. BinaryClassificationExperimentLayoutBuilder

Билдер для бинарной классификации:

var binaryExperiment = await new BaseExperimentLayoutBuilder(client)
    .SetExperimentName("Spam Detection")
    .SetOwnerID("ml-engineer")
    .ForBinaryClassificationTask()
    .SetOptimizationMetric(BinaryClassificationOptimizingMetricDto.AreaUnderRocCurve)
    .WithAllowedTrainers(new List<BinaryClassificationTrainerDto>
    {
        BinaryClassificationTrainerDto.LightGbm,
        BinaryClassificationTrainerDto.FastTree,
        BinaryClassificationTrainerDto.LinearSvm
    })
    .SendToServerAsync(cancellationToken);

3.4. MulticlassClassificationExperimentLayoutBuilder

Билдер для мультиклассовой классификации:

var multiclassExperiment = await new BaseExperimentLayoutBuilder(client)
    .SetExperimentName("Document Classification")
    .SetOwnerID("nlp-specialist")
    .ForMulticlassClassificationTask()
    .SetOptimizationMetric(MulticlassClassificationOptimizingMetricDto.MicroAccuracy)
    .WithAllowedTrainers(new List<MulticlassClassificationTrainerDto>
    {
        MulticlassClassificationTrainerDto.LightGbm,
        MulticlassClassificationTrainerDto.SdcaMaximumEntropy,
        MulticlassClassificationTrainerDto.LbfgsMaximumEntropy
    })
    .SendToServerAsync(cancellationToken);

4. Типы экспериментов

4.1. ExperimentTypeDto

public enum ExperimentTypeDto
{
    Regression,                    // Регрессия
    BinaryClassification,         // Бинарная классификация
    MulticlassClassification      // Мультиклассовая классификация
}

4.2. Настройки экспериментов

ExperimentSettingsDto - полная структура:

var settings = new ExperimentSettingsDto
{
    // Основные параметры
    ExperimentName = "My Experiment",
    ExperimentType = ExperimentTypeDto.Regression,
    OwnerID = "user-123",
    MaxExperimentTimeInSeconds = 300,        // 5 минут
    MaxModelsToExplore = 20,                 // Количество моделей для проверки
    
    // Параметры разделения данных
    TrainTestSplitFraction = 0.2m,           // 20% для теста
    ValidationTrainSplitFraction = 0.2m,     // 20% для валидации
    ShuffleData = true,
    ShuffleType = ShuffleTypeDto.PseudoRandom,
    
    // Кросс-валидация
    UseCrossValidation = true,
    CrossValidationFolds = 5,
    
    // Балансировка данных (для классификации)
    BalancingStrategy = DataBalancingStrategyDto.None,
    
    // Настройки тюнера
    Tuner = TunerTypeDto.Heuristic,
    
    // Путь к начальным данным (опционально)
    InitialDataSourcePath = "path/to/data.csv"
};

5. Алгоритмы машинного обучения

5.1. RegressionTrainerDto - Регрессионные алгоритмы

public enum RegressionTrainerDto
{
    LbfgsPoissonRegression,    // Пуассоновская регрессия (LBFGS)
    LightGbm,                  // LightGBM градиентный бустинг
    FastTree,                  // Быстрые деревья решений
    FastTreeTweedie,          // FastTree с Tweedie распределением
    FastForest,                // Случайный лес
    Gam,                       // Обобщенная аддитивная модель
    Sdca,                     // Стохастический двойной координатный спуск
    Ols                        // Обычный метод наименьших квадратов
}

5.2. BinaryClassificationTrainerDto - Бинарная классификация

public enum BinaryClassificationTrainerDto
{
    AveragedPerceptron,                // Усредненный перцептрон
    FastForest,                        // Случайный лес
    FastTree,                          // Быстрые деревья решений
    LightGbm,                          // LightGBM градиентный бустинг
    LinearSvm,                         // Линейный метод опорных векторов
    LbfgsLogisticRegression,           // Логистическая регрессия (LBFGS)
    SdcaLogisticRegression,            // Логистическая регрессия (SDCA)
    SymbolicSgdLogisticRegression,     // Символический SGD логистическая регрессия
    Gam                                // Обобщенная аддитивная модель
}

5.3. MulticlassClassificationTrainerDto - Мультиклассовая классификация

public enum MulticlassClassificationTrainerDto
{
    AveragedPerceptron,                // Усредненный перцептрон
    FastForest,                        // Случайный лес
    FastTree,                          // Быстрые деревья решений
    LbfgsMaximumEntropy,               // Максимальная энтропия (LBFGS)
    LbfgsLogisticRegression,           // Логистическая регрессия (LBFGS)
    LightGbm,                          // LightGBM градиентный бустинг
    LinearSvm,                         // Линейный метод опорных векторов
    Prior,                             // Приоритетный классификатор
    SdcaMaximumEntropy,                // Максимальная энтропия (SDCA)
    SdcaLogisticRegression,            // Логистическая регрессия (SDCA)
    OneVersusAll,                      // Один против всех
    Gam                                // Обобщенная аддитивная модель
}

6. Метрики оптимизации

6.1. RegressionOptimizingMetricDto - Метрики регрессии

public enum RegressionOptimizingMetricDto
{
    RootMeanSquaredError,    // Корень из среднеквадратичной ошибки (RMSE)
    MeanAbsoluteError,       // Средняя абсолютная ошибка (MAE)
    MeanSquaredError,        // Среднеквадратичная ошибка (MSE)
    RSquared                 // Коэффициент детерминации (R²)
}

6.2. BinaryClassificationOptimizingMetricDto - Метрики бинарной классификации

public enum BinaryClassificationOptimizingMetricDto
{
    Accuracy,                           // Точность
    AreaUnderRocCurve,                 // Площадь под ROC-кривой (AUC-ROC)
    AreaUnderPrecisionRecallCurve,     // Площадь под PR-кривой (AUC-PR)
    F1Score,                           // F1-мера
    PositivePrecision,                 // Точность положительного класса
    PositiveRecall,                    // Полнота положительного класса
    NegativePrecision,                 // Точность отрицательного класса
    NegativeRecall                     // Полнота отрицательного класса
}

6.3. MulticlassClassificationOptimizingMetricDto - Метрики мультиклассовой классификации

public enum MulticlassClassificationOptimizingMetricDto
{
    MacroAccuracy,      // Макро-точность
    MicroAccuracy,      // Микро-точность
    LogLoss,           // Логарифмические потери
    LogLossReduction,  // Снижение логарифмических потерь
    TopKAccuracy       // Точность Top-K
}

7. Продвинутые настройки

7.1. TunerTypeDto - Типы тюнеров гиперпараметров

public enum TunerTypeDto
{
    Heuristic,       // Эвристический тюнер (быстрый)
    GridSearch,      // Поиск по сетке
    RandomSearch,    // Случайный поиск
    EciCostFrugal,   // Cost-frugal тюнер
    Smac,           // Sequential Model-based Algorithm Configuration
    CostFrugal,     // Экономичный тюнер
    AutoZero        // AutoZero тюнер
}

7.2. ShuffleTypeDto - Типы перемешивания данных

public enum ShuffleTypeDto
{
    PseudoRandom = 0,    // Псевдослучайное перемешивание
    Stratified = 1       // Стратифицированное перемешивание
}

7.3. DataBalancingStrategyDto - Стратегии балансировки данных

public enum DataBalancingStrategyDto
{
    None,                       // Без балансировки
    UndersampleDiverseMajority  // Андерсэмплинг разнообразного большинства
}

8. Жизненный цикл эксперимента

8.1. Создание эксперимента

// С помощью Builder паттерна
var settingsBuilder = new BaseExperimentLayoutBuilder(client)
    .SetExperimentName("Advanced Regression")
    .SetOwnerID("ml-expert")
    .ForRegressionTask();

var regressionBuilder = settingsBuilder
    .SetOptimizationMetric(RegressionOptimizingMetricDto.RSquared)
    .WithAllowedTrainers(new List<string> { "LightGbm", "FastTree" });

var experimentDto = await regressionBuilder.SendToServerAsync(cancellationToken);

// Или напрямую через настройки
var settings = new ExperimentSettingsDto
{
    ExperimentName = "Direct Creation",
    ExperimentType = ExperimentTypeDto.Regression,
    OwnerID = "direct-user",
    MaxExperimentTimeInSeconds = 600,
    MaxModelsToExplore = 50,
    TrainTestSplitFraction = 0.2m,
    ValidationTrainSplitFraction = 0.2m,
    ShuffleData = true,
    ShuffleType = ShuffleTypeDto.PseudoRandom,
    UseCrossValidation = true,
    CrossValidationFolds = 10,
    RegressionOptimizationMetric = RegressionOptimizingMetricDto.RSquared,
    AllowedRegressionTrainers = new List<RegressionTrainerDto>
    {
        RegressionTrainerDto.LightGbm,
        RegressionTrainerDto.FastTree,
        RegressionTrainerDto.Gam
    },
    BalancingStrategy = DataBalancingStrategyDto.None,
    Tuner = TunerTypeDto.Smac
};

var result = await client.CreateExperimentAsync(settings, cancellationToken);

8.2. Получение информации об экспериментах

// Получить все эксперименты
var allExperimentsResult = await client.GetAllExperimentsAsync(cancellationToken);
if (allExperimentsResult.IsSuccess)
{
    foreach (var experiment in allExperimentsResult.Value)
    {
        Console.WriteLine($"Experiment: {experiment.Name} (ID: {experiment.Id})");
        Console.WriteLine($"Type: {experiment.ExperimentType}");
        Console.WriteLine($"Status: {experiment.Status}");
        Console.WriteLine($"Created: {experiment.CreatedTimestamp}");
        Console.WriteLine($"Owner: {experiment.OwnerID}");
        Console.WriteLine();
    }
}

// Получить конкретный эксперимент
var experimentResult = await client.GetExperimentAsync("experiment-id", cancellationToken);
if (experimentResult.IsSuccess)
{
    var experiment = experimentResult.Value;
    Console.WriteLine($"Experiment Details:");
    Console.WriteLine($"Name: {experiment.Name}");
    Console.WriteLine($"Best Model: {experiment.BestModel?.TrainerName}");
    Console.WriteLine($"Model Metric: {experiment.BestModel?.MetricValue}");
}

8.3. Обновление настроек эксперимента

var newSettings = new ExperimentSettingsDto
{
    ExperimentName = "Updated Experiment Name",
    ExperimentType = ExperimentTypeDto.Regression,
    MaxExperimentTimeInSeconds = 900, // Увеличили время
    MaxModelsToExplore = 100,          // Увеличили количество моделей
    // ... остальные параметры
};

var updateResult = await client.UpdateExperimentSettingsAsync(
    "experiment-id", 
    newSettings, 
    cancellationToken
);

if (updateResult.IsSuccess)
{
    Console.WriteLine("Experiment settings updated successfully");
}

8.4. Удаление эксперимента

var deleteResult = await client.DeleteExperimentAsync("experiment-id", cancellationToken);
if (deleteResult.IsSuccess)
{
    Console.WriteLine("Experiment deleted successfully");
}

9. Управление данными

9.1. Импорт данных из файла

// Импорт CSV файла
var importResult = await client.ImportDataFromFileAsync(
    "experiment-id",
    @"C:\Data\housing_prices.csv",
    cancellationToken
);

if (importResult.IsSuccess)
{
    Console.WriteLine("Data imported successfully");
}
else
{
    Console.WriteLine($"Import failed: {importResult.ErrorMessage}");
}

9.2. Импорт данных из массива байт

// Читаем файл в байты
var fileBytes = await File.ReadAllBytesAsync(@"C:\Data\data.csv");

var importResult = await client.ImportDataAsync(
    "experiment-id",
    fileBytes,
    "data.csv",
    cancellationToken
);

9.3. Добавление отдельных точек данных

// Создание точки данных
var dataPoint = new GeneralDataPointDto
{
    Label = 250000.0f,  // Цена дома
    Features = new float[]
    {
        1500.0f,  // Площадь
        3.0f,     // Количество комнат
        2.0f,     // Количество ванных
        5.0f      // Возраст дома
    }
};

// Добавление точки данных
var addResult = await client.AddDataPointAsync(
    "experiment-id",
    dataPoint,
    cancellationToken
);

9.4. Получение информации о данных

var dataInfoResult = await client.GetDataInfoAsync("experiment-id", cancellationToken);
if (dataInfoResult.IsSuccess)
{
    var dataInfo = dataInfoResult.Value;
    Console.WriteLine($"Data source: {dataInfo.SourceDescription}");
    Console.WriteLine($"Row count: {dataInfo.RowCount}");
    Console.WriteLine($"Label field: {dataInfo.LabelField?.Name}");
    Console.WriteLine($"Feature field: {dataInfo.FeaturesField?.Name}");
    Console.WriteLine($"Feature vector size: {dataInfo.FeatureVectorSize}");
}

9.5. Завершение сбора данных

// После добавления всех точек данных или импорта файла
var finalizeResult = await client.FinalizeDataCollectionAsync(
    "experiment-id",
    cancellationToken
);

9.6. Экспорт данных

var exportResult = await client.ExportDataToFileAsync(
    "experiment-id",
    @"C:\ExportedData\",
    "exported_data.csv",  // опционально, если null - будет сгенерировано имя
    cancellationToken
);

if (exportResult.IsSuccess)
{
    Console.WriteLine($"Data exported to: {exportResult.Value}");
}

9.7. Очистка данных эксперимента

var clearResult = await client.ClearExperimentDataAsync(
    "experiment-id",
    cancellationToken
);

10. События и мониторинг

10.1. Подписка на события клиента

var client = new BinomAutoMLClient(logger);

// События экспериментов
client.OnExperimentCreatedEvent += async (experiment) =>
{
    Console.WriteLine($"Experiment created: {experiment.Name}");
    await Task.CompletedTask;
};

client.OnExperimentUpdatedEvent += async (experiment) =>
{
    Console.WriteLine($"Experiment updated: {experiment.Name}");
    await Task.CompletedTask;
};

client.OnExperimentDeletedEvent += async (experimentId) =>
{
    Console.WriteLine($"Experiment deleted: {experimentId}");
    await Task.CompletedTask;
};

client.OnExperimentStatusChangedEvent += async (statusEvent) =>
{
    Console.WriteLine($"Status changed for {statusEvent.ExperimentId}: {statusEvent.NewStatus}");
    await Task.CompletedTask;
};

// События обучения
client.OnTrainingProgressEvent += async (progressEvent) =>
{
    Console.WriteLine($"Training progress - Trial {progressEvent.TrialNumber}: {progressEvent.TrainerName}");
    Console.WriteLine($"Score: {progressEvent.Score}");
    Console.WriteLine($"Duration: {progressEvent.DurationInMilliseconds}ms");
    await Task.CompletedTask;
};

client.OnTrainingCompletedEvent += async (completedEvent) =>
{
    Console.WriteLine($"Training completed for {completedEvent.ExperimentId}");
    Console.WriteLine($"Success: {completedEvent.IsSuccess}");
    if (!completedEvent.IsSuccess)
    {
        Console.WriteLine($"Error: {completedEvent.ErrorMessage}");
    }
    await Task.CompletedTask;
};

client.OnTrainingFailedEvent += async (trainingResult) =>
{
    Console.WriteLine($"Training failed for {trainingResult.ExperimentId}");
    Console.WriteLine($"Error: {trainingResult.ErrorMessage}");
    await Task.CompletedTask;
};

client.OnTrainingCancelledEvent += async (experimentId) =>
{
    Console.WriteLine($"Training cancelled for {experimentId}");
    await Task.CompletedTask;
};

// Логи обучения
client.OnTrainingLogReceivedEvent += async (experimentId, message) =>
{
    Console.WriteLine($"[{experimentId}] {message}");
    await Task.CompletedTask;
};

// Метрики производительности
client.OnPerformanceMetricsUpdatedEvent += async (metricsEvent) =>
{
    Console.WriteLine($"Performance metrics for {metricsEvent.ExperimentId}:");
    Console.WriteLine($"CPU Usage: {metricsEvent.CpuUsage}%");
    Console.WriteLine($"RAM Usage: {metricsEvent.RamUsage}%");
    Console.WriteLine($"GPU Usage: {metricsEvent.GpuUsage}");
    await Task.CompletedTask;
};

10.2. MonitoringTrainingProgressEventDto - Детальный прогресс

client.OnTrainingProgressEvent += async (progress) =>
{
    Console.WriteLine($"Trial #{progress.TrialNumber}");
    Console.WriteLine($"Trainer: {progress.TrainerName}");
    Console.WriteLine($"Optimization Metric: {progress.OptimizationMetricName}");
    Console.WriteLine($"Score: {progress.Score:F4}");
    Console.WriteLine($"Duration: {TimeSpan.FromMilliseconds(progress.DurationInMilliseconds):g}");
    
    // Дополнительные метрики валидации
    if (progress.AllValidationMetrics?.Any() == true)
    {
        Console.WriteLine("Validation Metrics:");
        foreach (var metric in progress.AllValidationMetrics)
        {
            Console.WriteLine($"  {metric.Key}: {metric.Value:F4}");
        }
    }
    
    // Метрики теста
    if (progress.AllTestMetrics?.Any() == true)
    {
        Console.WriteLine("Test Metrics:");
        foreach (var metric in progress.AllTestMetrics)
        {
            Console.WriteLine($"  {metric.Key}: {metric.Value:F4}");
        }
    }
    
    // Результаты кросс-валидации
    if (progress.FoldResults?.Any() == true)
    {
        Console.WriteLine($"Cross-Validation Results ({progress.FoldResults.Count} folds):");
        foreach (var fold in progress.FoldResults)
        {
            Console.WriteLine($"  Fold {fold.FoldNumber}:");
            foreach (var metric in fold.Metrics)
            {
                Console.WriteLine($"    {metric.Key}: {metric.Value:F4}");
            }
        }
    }
    
    await Task.CompletedTask;
};

10.3. Получение статуса обучения

var statusResult = await client.GetTrainingStatusAsync("experiment-id", cancellationToken);
if (statusResult.IsSuccess)
{
    var status = statusResult.Value;
    Console.WriteLine($"Training status: {status.Status}");
}

11. Предсказания

11.1. Получение лучшей модели

var bestModelResult = await client.GetBestModelAsync("experiment-id", cancellationToken);
if (bestModelResult.IsSuccess)
{
    var model = bestModelResult.Value;
    Console.WriteLine($"Best Model: {model.TrainerName}");
    Console.WriteLine($"Metric: {model.MetricName} = {model.MetricValue}");
    Console.WriteLine($"Model Path: {model.ModelFilePath}");
    Console.WriteLine($"Experiment Type: {model.ExperimentType}");
    Console.WriteLine($"Is Cross-Validated: {model.IsCrossValidated}");
    
    if (model.StandardDeviation.HasValue)
    {
        Console.WriteLine($"Standard Deviation: {model.StandardDeviation:F4}");
    }
    
    // Результаты по фолдам кросс-валидации
    if (model.FoldResults?.Any() == true)
    {
        Console.WriteLine("Cross-Validation Fold Results:");
        foreach (var fold in model.FoldResults)
        {
            Console.WriteLine($"  Fold {fold.FoldNumber}:");
            foreach (var metric in fold.Metrics)
            {
                Console.WriteLine($"    {metric.Key}: {metric.Value:F4}");
            }
        }
    }
}

11.2. Выполнение предсказания

// Подготовка данных для предсказания
var predictionData = new PredictionDataDto
{
    Features = new Dictionary<string, object>
    {
        {"feature_1", 10.5},
        {"feature_2", 2.5},
        {"feature_3", 1500.0},
        {"feature_4", 3.0}
    }
};

// Выполнение предсказания
var predictionResult = await client.PredictAsync(
    "experiment-id",
    predictionData,
    cancellationToken
);

if (predictionResult.IsSuccess)
{
    var result = predictionResult.Value;
    
    if (result.PredictedValue != null)
    {
        Console.WriteLine($"Predicted Value: {result.PredictedValue}");
    }
    
    // Для классификации - вероятности классов
    if (result.Scores?.Any() == true)
    {
        Console.WriteLine("Class Probabilities:");
        foreach (var score in result.Scores.OrderByDescending(x => x.Value))
        {
            Console.WriteLine($"  {score.Key}: {score.Value:F4}");
        }
    }
}

12. Управление соединением

12.1. Мониторинг состояния соединения

// Проверка статуса соединения
Console.WriteLine($"Current status: {client.CurrentStatus}");

// Примечание: событие ConnectionStatusChanged отсутствует в текущей версии
// Для мониторинга статуса используйте периодическую проверку свойства CurrentStatus

12.2. Базовое управление соединением

// Подключение к серверу
await client.ConnectAsync(cancellationToken);

// Отключение от сервера
await client.DisconnectAsync(cancellationToken);

// Проверка текущего статуса
var status = client.CurrentStatus;
Console.WriteLine($"Connection status: {status}");

12.3. Рекомендации по обработке соединений

public class ConnectionManager
{
    private readonly BinomAutoMLClient _client;
    private readonly Timer _statusCheckTimer;
    private ConnectionStatusDto _lastStatus = ConnectionStatusDto.Disconnected;

    public ConnectionManager(IClientLogger logger)
    {
        _client = new BinomAutoMLClient(logger);
        _statusCheckTimer = new Timer(CheckConnectionStatus, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
    }

    private async void CheckConnectionStatus(object? state)
    {
        var currentStatus = _client.CurrentStatus;
        if (currentStatus != _lastStatus)
        {
            Console.WriteLine($"Connection status changed from {_lastStatus} to {currentStatus}");
            _lastStatus = currentStatus;

            if (currentStatus == ConnectionStatusDto.Error)
            {
                // Попытка переподключения
                try
                {
                    await _client.ConnectAsync();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Reconnect failed: {ex.Message}");
                }
            }
        }
    }
}

13. Обработка ошибок

13.1. Типы исключений

try
{
    var result = await client.CreateExperimentAsync(settings, cancellationToken);
}
catch (BinomClientConnectionException ex)
{
    Console.WriteLine($"Connection error: {ex.Message}");
    // Обработка ошибок соединения
}
catch (BinomClientException ex)
{
    Console.WriteLine($"Client error: {ex.Message}");
    // Обработка ошибок клиента
}
catch (BinomServerOperationException ex)
{
    Console.WriteLine($"Server operation error: {ex.Message}");
    // Обработка ошибок операций сервера
}
catch (ExperimentConfigurationException ex)
{
    Console.WriteLine($"Configuration error: {ex.Message}");
    // Обработка ошибок конфигурации эксперимента
}

13.2. Рекомендации по обработке ошибок

public async Task<T> SafeOperation<T>(Func<Task<T>> operation, string operationName)
{
    try
    {
        var result = await operation();
        if (result.IsSuccess)
        {
            return result.Value;
        }
        else
        {
            throw new InvalidOperationException(
                $"{operationName} failed: {result.ErrorMessage}");
        }
    }
    catch (BinomClientConnectionException ex)
    {
        // Попытка переподключения
        await TryReconnect();
        return await SafeOperation(operation, operationName);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Unexpected error in {operationName}: {ex}");
        throw;
    }
}

// Использование
var experiments = await SafeOperation(
    () => client.GetAllExperimentsAsync(cancellationToken),
    "GetAllExperiments"
);

14. Продвинутые примеры

14.1. Полный цикл регрессионного эксперимента

public async Task RunCompleteRegressionExperiment()
{
    var logger = new ConsoleLogger();
    var client = new BinomAutoMLClient(logger);
    var cts = new CancellationTokenSource();

    try
    {
        // 1. Подключение
        await client.ConnectAsync(cts.Token);
        
        // 2. Создание эксперимента с расширенными настройками
        var settings = new ExperimentSettingsDto
        {
            ExperimentName = "House Price Prediction Advanced",
            ExperimentType = ExperimentTypeDto.Regression,
            OwnerID = "advanced-user",
            MaxExperimentTimeInSeconds = 1800, // 30 минут
            MaxModelsToExplore = 100,
            TrainTestSplitFraction = 0.15m,    // 15% для теста
            ValidationTrainSplitFraction = 0.15m, // 15% для валидации
            ShuffleData = true,
            ShuffleType = ShuffleTypeDto.PseudoRandom,
            UseCrossValidation = true,
            CrossValidationFolds = 10,
            RegressionOptimizationMetric = RegressionOptimizingMetricDto.RSquared,
            AllowedRegressionTrainers = new List<RegressionTrainerDto>
            {
                RegressionTrainerDto.LightGbm,
                RegressionTrainerDto.FastTree,
                RegressionTrainerDto.Gam,
                RegressionTrainerDto.FastForest
            },
            BalancingStrategy = DataBalancingStrategyDto.None,
            Tuner = TunerTypeDto.Smac,
            InitialDataSourcePath = ""
        };

        // 3. Создание эксперимента
        var createResult = await client.CreateExperimentAsync(settings, cts.Token);
        if (!createResult.IsSuccess)
            throw new InvalidOperationException($"Failed to create experiment: {createResult.ErrorMessage}");

        var experimentId = createResult.Value.Id;
        Console.WriteLine($"Created experiment: {experimentId}");

        // 4. Импорт данных
        var importResult = await client.ImportDataFromFileAsync(
            experimentId,
            @"C:\Data\housing_prices.csv",
            cts.Token
        );

        if (!importResult.IsSuccess)
            throw new InvalidOperationException($"Failed to import data: {importResult.ErrorMessage}");

        // 5. Получение информации о данных
        var dataInfoResult = await client.GetDataInfoAsync(experimentId, cts.Token);
        if (dataInfoResult.IsSuccess)
        {
            var dataInfo = dataInfoResult.Value;
            Console.WriteLine($"Data source: {dataInfo.SourceDescription}");
            Console.WriteLine($"Row count: {dataInfo.RowCount}");
            Console.WriteLine($"Label field: {dataInfo.LabelField?.Name}");
            Console.WriteLine($"Feature field: {dataInfo.FeaturesField?.Name}");
            Console.WriteLine($"Feature vector size: {dataInfo.FeatureVectorSize}");
        }

        // 6. Настройка обработки событий
        var trainingCompleted = new TaskCompletionSource<bool>();
        
        client.OnTrainingCompletedEvent += async (e) =>
        {
            if (e.ExperimentId == experimentId)
            {
                if (e.IsSuccess)
                    trainingCompleted.SetResult(true);
                else
                    trainingCompleted.SetException(new InvalidOperationException(e.ErrorMessage ?? "Training failed"));
            }
        };

        client.OnTrainingProgressEvent += async (e) =>
        {
            if (e.ExperimentId == experimentId)
            {
                Console.WriteLine($"Trial {e.TrialNumber}: {e.TrainerName} - Score: {e.Score:F4}");
            }
        };

        // 7. Запуск обучения
        Console.WriteLine("Starting training...");
        var startResult = await client.StartTrainingAsync(experimentId, cts.Token);
        if (!startResult.IsSuccess)
            throw new InvalidOperationException($"Failed to start training: {startResult.ErrorMessage}");

        // 8. Ожидание завершения
        await trainingCompleted.Task;
        Console.WriteLine("Training completed successfully!");

        // 9. Получение результатов
        var resultsResult = await client.GetTrainingResultsAsync(experimentId, cts.Token);
        if (resultsResult.IsSuccess)
        {
            var results = resultsResult.Value;
            Console.WriteLine($"Training completed");
            Console.WriteLine($"Status: {results.Status}");
            
            Console.WriteLine("All trial results:");
            foreach (var trial in results.TrialResults.OrderByDescending(t => t.MetricValue).Take(5))
            {
                Console.WriteLine($"  {trial.TrainerName}: {trial.MetricValue:F4}");
            }
        }

        // 10. Получение лучшей модели и предсказания
        var bestModelResult = await client.GetBestModelAsync(experimentId, cts.Token);
        if (bestModelResult.IsSuccess)
        {
            var bestModel = bestModelResult.Value;
            Console.WriteLine($"Best model details:");
            Console.WriteLine($"  Trainer: {bestModel.TrainerName}");
            Console.WriteLine($"  Metric: {bestModel.MetricName} = {bestModel.MetricValue:F4}");
            Console.WriteLine($"  Path: {bestModel.ModelFilePath}");

            // Тестовое предсказание
            var testPrediction = new PredictionDataDto
            {
                Features = new Dictionary<string, object>
                {
                    {"feature_1", 2000},
                    {"feature_2", 3},
                    {"feature_3", 2},
                    {"feature_4", 5}
                }
            };

            var predictionResult = await client.PredictAsync(experimentId, testPrediction, cts.Token);
            if (predictionResult.IsSuccess)
            {
                var prediction = predictionResult.Value;
                Console.WriteLine($"Predicted house price: ${prediction.PredictedValue:N0}");
            }
        }

        // 11. Очистка (опционально)
        // await client.DeleteExperimentAsync(experimentId, cts.Token);
    }
    finally
    {
        await client.DisconnectAsync();
        client.Dispose();
        cts.Dispose();
    }
}

14.2. Бинарная классификация с балансировкой

public async Task RunBinaryClassificationWithBalancing()
{
    var client = new BinomAutoMLClient(new ConsoleLogger());
    await client.ConnectAsync();

    // Создание эксперимента бинарной классификации с балансировкой
    var settings = new ExperimentSettingsDto
    {
        ExperimentName = "Fraud Detection with Balancing",
        ExperimentType = ExperimentTypeDto.BinaryClassification,
        OwnerID = "fraud-analyst",
        MaxExperimentTimeInSeconds = 1200,
        MaxModelsToExplore = 50,
        TrainTestSplitFraction = 0.2m,
        ValidationTrainSplitFraction = 0.2m,
        ShuffleData = true,
        ShuffleType = ShuffleTypeDto.Stratified, // Стратифицированное перемешивание
        UseCrossValidation = true,
        CrossValidationFolds = 5,
        BinaryClassificationOptimizationMetric = BinaryClassificationOptimizingMetricDto.AreaUnderRocCurve,
        AllowedBinaryClassificationTrainers = new List<BinaryClassificationTrainerDto>
        {
            BinaryClassificationTrainerDto.LightGbm,
            BinaryClassificationTrainerDto.FastTree,
            BinaryClassificationTrainerDto.LinearSvm
        },
        BalancingStrategy = DataBalancingStrategyDto.UndersampleDiverseMajority, // Балансировка
        Tuner = TunerTypeDto.Heuristic,
        InitialDataSourcePath = ""
    };

    var createResult = await client.CreateExperimentAsync(settings);
    if (createResult.IsSuccess)
    {
        var experimentId = createResult.Value.Id;
        
        // Импорт несбалансированных данных
        await client.ImportDataFromFileAsync(experimentId, @"C:\Data\transactions.csv");
        
        // Запуск обучения
        await client.StartTrainingAsync(experimentId);
        
        Console.WriteLine("Binary classification experiment with balancing started!");
    }
}

14.3. Мультиклассовая классификация с GridSearch

public async Task RunMulticlassClassificationWithGridSearch()
{
    var client = new BinomAutoMLClient(new ConsoleLogger());
    await client.ConnectAsync();

    var settings = new ExperimentSettingsDto
    {
        ExperimentName = "Document Classification with Grid Search",
        ExperimentType = ExperimentTypeDto.MulticlassClassification,
        OwnerID = "nlp-engineer",
        MaxExperimentTimeInSeconds = 2400, // 40 минут для GridSearch
        MaxModelsToExplore = 200, // Больше моделей для GridSearch
        TrainTestSplitFraction = 0.25m,
        ValidationTrainSplitFraction = 0.25m,
        ShuffleData = true,
        ShuffleType = ShuffleTypeDto.Stratified,
        UseCrossValidation = true,
        CrossValidationFolds = 7,
        MulticlassClassificationOptimizationMetric = MulticlassClassificationOptimizingMetricDto.MicroAccuracy,
        AllowedMulticlassClassificationTrainers = new List<MulticlassClassificationTrainerDto>
        {
            MulticlassClassificationTrainerDto.LightGbm,
            MulticlassClassificationTrainerDto.SdcaMaximumEntropy,
            MulticlassClassificationTrainerDto.LbfgsMaximumEntropy
        },
        BalancingStrategy = DataBalancingStrategyDto.None,
        Tuner = TunerTypeDto.GridSearch, // Используем GridSearch
        InitialDataSourcePath = ""
    };

    var createResult = await client.CreateExperimentAsync(settings);
    if (createResult.IsSuccess)
    {
        var experimentId = createResult.Value.Id;
        await client.ImportDataFromFileAsync(experimentId, @"C:\Data\documents.csv");
        await client.StartTrainingAsync(experimentId);
        
        Console.WriteLine("Multiclass classification with GridSearch started!");
    }
}

14.4. Реализация оптимизации гиперпараметров

public async Task RunHyperparameterOptimization()
{
    var client = new BinomAutoMLClient(new ConsoleLogger());
    await client.ConnectAsync();

    // Создаем несколько экспериментов с разными тюнерами для сравнения
    var tuners = new[]
    {
        TunerTypeDto.Heuristic,
        TunerTypeDto.RandomSearch,
        TunerTypeDto.Smac,
        TunerTypeDto.CostFrugal
    };

    var experimentIds = new List<string>();

    foreach (var tuner in tuners)
    {
        var settings = new ExperimentSettingsDto
        {
            ExperimentName = $"Hyperparameter Optimization - {tuner}",
            ExperimentType = ExperimentTypeDto.Regression,
            OwnerID = "hyperparameter-analyst",
            MaxExperimentTimeInSeconds = 900,
            MaxModelsToExplore = 30,
            Tuner = tuner,
            RegressionOptimizationMetric = RegressionOptimizingMetricDto.RSquared,
            TrainTestSplitFraction = 0.2m,
            ValidationTrainSplitFraction = 0.2m,
            ShuffleData = true,
            ShuffleType = ShuffleTypeDto.PseudoRandom,
            UseCrossValidation = true,
            CrossValidationFolds = 5,
            BalancingStrategy = DataBalancingStrategyDto.None,
            InitialDataSourcePath = ""
        };

        var result = await client.CreateExperimentAsync(settings);
        if (result.IsSuccess)
        {
            experimentIds.Add(result.Value.Id);
            await client.ImportDataFromFileAsync(result.Value.Id, @"C:\Data\dataset.csv");
            await client.StartTrainingAsync(result.Value.Id);
        }
    }

    Console.WriteLine($"Started {experimentIds.Count} hyperparameter optimization experiments");
    
    // Мониторинг и сравнение результатов
    client.OnTrainingCompletedEvent += async (e) =>
    {
        if (experimentIds.Contains(e.ExperimentId))
        {
            var results = await client.GetTrainingResultsAsync(e.ExperimentId);
            if (results.IsSuccess)
            {
                Console.WriteLine($"{e.ExperimentId}: Training completed");
            }
        }
    };
}

🚀 Заключение

Binom.AutoML.IPCClient предоставляет мощный и гибкий интерфейс для автоматизации машинного обучения с широкими возможностями:

  • Полная поддержка AutoML - от создания экспериментов до предсказаний
  • Builder паттерны для удобной конфигурации
  • Все основные алгоритмы ML.NET для регрессии и классификации
  • Продвинутые техники - кросс-валидация, тюнинг гиперпараметров, балансировка данных
  • Мониторинг в реальном времени через события
  • Надежная обработка ошибок и переподключения
  • Гибкое управление данными - импорт, экспорт, манипуляция точками данных

Клиент построен на современных .NET практиках и обеспечивает высокую производительность через Named Pipes и MessagePack сериализацию.


Версия документации: 2.1.0 Последнее обновление: 2025-01-08

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.4 202 11/23/2025
1.2.3 405 11/19/2025
1.2.2 155 11/8/2025
1.2.1 199 10/23/2025
1.1.6 189 10/15/2025
1.1.5 176 10/12/2025