public async Task AddForecastingTaskRecord(string entityName, List <ForecastingTaskFieldValue> fields) { entityName = entityName?.Trim(); if (!await DoesForecastingTaskEntityExist(entityName)) { throw new DomainErrorException($"Forecasting task with name {entityName} doesn't exist!"); } var taskEntityDeclaration = await _forecastingTasksRepository.GetForecastingTaskFieldsDeclaration(entityName); if (taskEntityDeclaration.Count != fields.Select(x => x.FieldId).Distinct().Count()) { throw new DomainErrorException($"Forecasting task with name {entityName} and the request have a different count of fields!"); } for (int i = 0; i < fields.Count; i++) { if (!taskEntityDeclaration.Any(x => x.Id == fields[i].FieldId)) { throw new DomainErrorException($"Column {fields[i].FieldId} doesn't exist in forecasting task with name {entityName}!"); } fields[i].Value = fields[i].Value?.Trim(); var fieldDeclaration = taskEntityDeclaration.Single(x => x.Id == fields[i].FieldId); if (fieldDeclaration.Type != FieldType.InformationField && !float.TryParse(fields[i].Value, out _)) { throw new DomainErrorException($"Field {fieldDeclaration.Name} must to be filled with a number! But was filled with value: {fields[i].Value}"); } } await _forecastingTasksRepository.AddForecastingTaskRecord(entityName, fields); }
public async Task AddForecastingTaskRecordsViaCsv(string entityName, string csv) { entityName = entityName?.Trim(); if (!await DoesForecastingTaskEntityExist(entityName)) { throw new DomainErrorException($"Forecasting task with name {entityName} doesn't exist!"); } var taskEntityDeclaration = await _forecastingTasksRepository.GetForecastingTaskFieldsDeclaration(entityName); var rows = csv.Split("\r\n"); var fieldsOrder = new Dictionary <int, ForecastingTaskFieldDeclaration>(); // Checking csv header var headerColumns = rows.First().Split(','); if (taskEntityDeclaration.Count != headerColumns.Count()) { throw new DomainErrorException($"Forecasting task with name {entityName} and csv file have a different count of columns!"); } for (int i = 0; i < headerColumns.Length; i++) { if (!taskEntityDeclaration.Any(x => x.Name == headerColumns[i].Trim())) { throw new DomainErrorException($"Column {headerColumns[i].Trim()} doesn't exist in forecasting task with name {entityName}!"); } fieldsOrder.Add(i, taskEntityDeclaration.Single(x => x.Name == headerColumns[i].Trim())); } //Add fields values var fieldsValues = new List <List <ForecastingTaskFieldValue> >(); foreach (var row in rows.Skip(1)) { var factorsValue = new List <ForecastingTaskFieldValue>(); var columns = row.Split(','); for (int i = 0; i < columns.Length; i++) { columns[i] = columns[i]?.Trim(); if (fieldsOrder[i].Type != FieldType.InformationField && !float.TryParse(columns[i], out _)) { throw new DomainErrorException($"Field {fieldsOrder[i].Name} must to be filled with a number! But was filled with value: {columns[i]}"); } factorsValue.Add(new ForecastingTaskFieldValue { FieldId = fieldsOrder[i].Id, Value = columns[i] }); } fieldsValues.Add(factorsValue); } await _forecastingTasksRepository.AddBatchOfForecastingTaskRecords(entityName, fieldsValues); }
public async Task <float> PredictValueByFactors(string entityName, List <ForecastingTaskFieldValue> factors, bool isValidationNeeded = true) { entityName = entityName?.Trim(); if (isValidationNeeded) { if (factors.Count == 0) { throw new DomainErrorException($"Factor list is empty!"); } if (!DoMLModelFilesExist(entityName)) { throw new DomainErrorException("You didn't train the model! Please, do!"); } if (!await DoesForecastingTaskEntityExist(entityName)) { throw new DomainErrorException($"Forecasting task with name {entityName} doesn't exist!"); } } var taskEntityDeclaration = await _forecastingTasksRepository.GetForecastingTaskFieldsDeclaration(entityName); var nonInformationFields = taskEntityDeclaration.Where(x => x.Type != FieldType.InformationField).ToList(); var predictionValueId = taskEntityDeclaration.Single(x => x.Type == FieldType.PredictionField).Id; if (factors.Any(x => x.FieldId == predictionValueId)) { throw new DomainErrorException($"FieldId {predictionValueId} is incorrect! This is the prediction value!"); } var entity = new ClassBuilder(entityName, GetFieldsType(nonInformationFields)); var myClassInstance = entity.CreateObject(); foreach (var value in factors) { value.Value = value.Value?.Trim(); if (!nonInformationFields.Any(x => x.Id == value.FieldId)) { throw new DomainErrorException($"FieldId {value.FieldId} is incorrect!"); } var name = nonInformationFields.Single(x => x.Id == value.FieldId).Name; entity.SetPropertyValue(myClassInstance, name, float.Parse(value.Value)); } var predicatedValue = ForecastingTaskConsumeModel.Predict(myClassInstance, entityName, entity.Type); return((float)Math.Round(predicatedValue, 3, MidpointRounding.AwayFromZero)); }