/// <summary> /// Saves the prediction values to entity. /// </summary> /// <typeparam name="T">The type of predicted values.</typeparam> /// <param name="schemaUId">The entity schema's identifier, which should be saved.</param> /// <param name="entityId">The entity identifier.</param> /// <param name="predictedValues">The predicted values of entity for the several models.</param> /// <param name="valueTransformer"> /// Optional mapping function, that should be applied to predicted value before saving. /// </param> /// <returns> /// <c>true</c> if the entity was saved, otherwise - <c>false</c>. /// </returns> protected virtual bool SaveEntityPredictedValues <T>(Guid schemaUId, Guid entityId, Dictionary <MLModelConfig, T> predictedValues, Func <T, object> valueTransformer) { if (predictedValues.IsNullOrEmpty()) { return(false); } Entity entity = GetEntity(schemaUId, entityId); if (entity == null) { return(false); } foreach (KeyValuePair <MLModelConfig, T> prediction in predictedValues) { MLModelConfig model = prediction.Key; EntitySchemaColumn column = entity.FindEntityColumnValue(model.PredictedResultColumnName).Column; if (valueTransformer != null) { object transformedPredictionValue = valueTransformer(prediction.Value); entity.SetColumnValue(column, transformedPredictionValue); } else { entity.SetColumnValue(column, prediction.Value); } } return(entity.Save()); }
private void AddQueryOutputColumn(Select query, MLModelConfig modelConfig) { string metadataOutputName = GetMetadataOutputName(); if (metadataOutputName.IsNotNullOrEmpty()) { return; } if (GetIsCFModel(modelConfig)) { query.Column(Column.Const(1)).As(DefaultOutputColumnAlias); return; } if (query.Columns.ExistsByAlias(DefaultOutputColumnAlias)) { return; } if (modelConfig.TrainingOutputFilterData?.Length > 0) { _queryBuilder.AddTrainingOutputExpression(query, modelConfig.TrainingOutputFilterData, DefaultOutputColumnAlias); return; } if (_modelConfig.TrainingTargetColumnName.IsNullOrEmpty()) { throw new ValidateException($"No output defined for the model {_modelConfig.Id}"); } string sourceExpressionAlias = query.SourceExpression.Alias ?? query.SourceExpression.SchemaName; query.Column(sourceExpressionAlias, _modelConfig.TrainingTargetColumnName).As(DefaultOutputColumnAlias); }
private static void ReadCollaborativeFilteringModelColumns(MLModelConfig modelConfig, List <MLColumnExpression> columns) { columns.Add(new MLColumnExpression { ColumnPath = modelConfig.CFItemColumnPath, Alias = "item_id" }); columns.Add(new MLColumnExpression { ColumnPath = modelConfig.CFUserColumnPath, Alias = "user_id" }); if (modelConfig.CFInteractionValueColumnPath.IsNotNullOrEmpty()) { columns.Add(new MLColumnExpression { ColumnPath = modelConfig.CFInteractionValueColumnPath, Alias = "value" }); } else { columns.Add(new MLColumnExpression { ExpressionType = EntitySchemaQueryExpressionType.Parameter, Parameter = new Parameter { DataValueType = Nui.ServiceModel.DataContract.DataValueType.Integer, Value = 1 }, Alias = "value" }); } }
private static MLModelConfig FetchModelConfig(UserConnection userConnection, IDataReader reader) { DateTime batchPredictedOn = reader.GetColumnValue <DateTime>("BatchPredictedOn"); batchPredictedOn = DateTime.SpecifyKind(batchPredictedOn, DateTimeKind.Utc); var rootSchemaUId = reader.GetColumnValue <Guid>("RootSchemaUId"); var targetColumnUId = FindValue <Guid>(reader, "TargetColumnUId", Guid.Empty); var modelConfig = new MLModelConfig { Id = reader.GetColumnValue <Guid>("Id"), MetaData = reader.GetColumnValue <string>("MetaData"), TrainingSetQuery = reader.GetColumnValue <string>("TrainingSetQuery"), ServiceUrl = reader.GetColumnValue <string>("ServiceUrl"), PredictionEndpoint = reader.GetColumnValue <string>("PredictionEndpoint"), TrainingEndpoint = reader.GetColumnValue <string>("TrainingEndpoint"), BatchPredictionQuery = reader.GetColumnValue <string>("BatchPredictionQuery"), ProblemType = reader.GetColumnValue <Guid>("MLProblemTypeId"), ModelInstanceUId = reader.GetColumnValue <Guid>("ModelInstanceUId"), TrainingFilterData = reader.GetColumnValue <byte[]>("TrainingFilterData"), BatchPredictionFilterData = reader.GetColumnValue <byte[]>("BatchPredictionFilterData"), TrainingTargetColumnName = FindEntityColumnValueName(userConnection, rootSchemaUId, targetColumnUId), EntitySchemaId = rootSchemaUId, BatchPredictedOn = batchPredictedOn }; if (modelConfig.BatchPredictionQuery.IsNullOrEmpty() && modelConfig.TrainingSetQuery.IsNotNullOrEmpty()) { modelConfig.BatchPredictionQuery = modelConfig.TrainingSetQuery; } SetPredictedResultColumnName(modelConfig, userConnection, reader); modelConfig.CurrentState = GetTypedState(reader.GetColumnValue <string>("StateCode")); LoadMLModelColumns(userConnection, modelConfig); return(modelConfig); }
private static void SetPredictedResultColumnName(MLModelConfig modelConfig, UserConnection userConnection, IDataReader reader) { if (modelConfig.PredictedResultColumnName.IsNotNullOrEmpty()) { return; } Guid predictedResultColumnUId = FindValue <Guid>(reader, "PredictedResultColumnUId", Guid.Empty); if (predictedResultColumnUId.IsNotEmpty()) { modelConfig.PredictedResultColumnName = FindEntityColumnValueName(userConnection, modelConfig.EntitySchemaId, predictedResultColumnUId); return; } if (modelConfig.TrainingTargetColumnName.IsNotNullOrEmpty()) { modelConfig.PredictedResultColumnName = modelConfig.TrainingTargetColumnName; return; } //TODO #CRM-40303 Remove when PredictedResultColumnUId will be set for all known customer models ModelSchemaMetadata metadata = modelConfig.GetModelSchemaMetadata(); string outputName = metadata.Output?.Name; if (IsEntityColumnExists(userConnection.EntitySchemaManager, modelConfig.EntitySchemaId, outputName)) { _log.Warn("Neither PredictedResultColumnUId nor TargetColumnUId is set. " + $"Using metadata's output as PredictedResultColumn in model {modelConfig.Id}"); modelConfig.PredictedResultColumnName = outputName; } }
/// <summary> /// Tries to load the model for prediction by its id. /// </summary> /// <param name="userConnection">The user connection.</param> /// <param name="modelId">The model identifier.</param> /// <param name="model">The model.</param> /// <returns><c>true</c> - if model successfully loaded, otherwise - <c>false</c>.</returns> public bool TryLoadModelForPrediction(UserConnection userConnection, Guid modelId, out MLModelConfig model) { userConnection.LicHelper.CheckHasOperationLicense(MLConsts.LicOperationCode); var select = (Select)GetModelBaseSelectQuery(userConnection) .Where("m", "Id").IsEqual(Column.Parameter(modelId, "Guid")); MLModelConfig modelConfig = null; select.ExecuteReader(reader => { bool isPredictionEnabled = reader.GetColumnValue <bool>("PredictionEnabled"); if (!isPredictionEnabled) { _log.WarnFormat("Prediction is not enabled for model with id {0}", modelId); return; } string modelInstanceUId = reader.GetColumnValue <string>("ModelInstanceUId"); if (modelInstanceUId.IsNullOrEmpty()) { _log.WarnFormat("Instance uid is not set for model with id {0}", modelId); return; } modelConfig = FetchModelConfig(userConnection, reader); }); model = modelConfig; return(model != null); }
/// <summary> /// Predicts numeric value for the specified model. /// </summary> /// <param name="model">The model.</param> /// <param name="dataForPrediction">The data for prediction.</param> /// <param name="proxy">The proxy.</param> /// <returns> /// Numeric value result. /// </returns> protected override List <double> Predict(MLModelConfig model, IList <Dictionary <string, object> > dataForPrediction, IMLServiceProxy proxy) { List <double> predictionResults = proxy.Regress(model.ModelInstanceUId, dataForPrediction); return(predictionResults); }
/// <summary> /// Predicts data by the specified machine learning model. /// </summary> /// <param name="modelConfig">Machine learning model configuration.</param> /// <param name="chunkPredictedHandler">Handler on each chunk predicted event. Invokes with dictionary where /// key is entity identifier and value is predicted result for that entity.</param> /// <exception cref="AggregateException">When at least one of chunk failed to predict.</exception> public void Predict(MLModelConfig modelConfig, Action <Dictionary <Guid, object> > chunkPredictedHandler) { var parameters = new Dictionary <string, object> { { "BatchPredictedOn", modelConfig.BatchPredictedOn } }; int chunkNumber = 0; var exceptions = new List <Exception>(); Guid modelId = modelConfig.Id; var modelQueryAssembler = ClassFactory.Get <IMLModelQueryBuilder>( new ConstructorArgument("userConnection", _userConnection)); Select select = modelQueryAssembler.BuildSelect(modelConfig.EntitySchemaId, modelConfig.BatchPredictionQuery, modelConfig.ColumnExpressions, modelConfig.BatchPredictionFilterData, parameters); DataLoader.LoadDataForPrediction(select, dataForPrediction => { chunkNumber++; if (dataForPrediction.Count == 0) { return; } IList <TOut> predictedValues; try { predictedValues = Predict(modelConfig, dataForPrediction); } catch (Exception ex) { _log.Warn($"Batch predict for chunk #{chunkNumber} failed - skipping. ModelId = {modelId}", ex); exceptions.Add(ex); return; } var results = new Dictionary <Guid, object>(); for (int i = 0; i < dataForPrediction.Count; i++) { Dictionary <string, object> record = dataForPrediction[i]; if (record.TryGetValue("Id", out object id) && Guid.TryParse(id.ToString(), out Guid recordId)) { if (results.ContainsKey(recordId)) { _log.Warn($"Prediction results for model " + $"{modelId} already contain key {recordId}. Check that select query " + $"for batch prediction returns unique value for column Id"); } else { results.Add(recordId, predictedValues[i]); SavePredictionResult(modelId, modelConfig.ModelInstanceUId, recordId, predictedValues[i]); } } else { exceptions.Add(new Exception($"Rowset for model {modelId} contains a record without Id")); } } chunkPredictedHandler(results); }); if (!exceptions.IsNullOrEmpty()) { throw new AggregateException(exceptions); } }
/// <summary> /// Scores value for the specified model. /// </summary> /// <param name="model">The model.</param> /// <param name="dataForPrediction">The data for prediction.</param> /// <param name="proxy">The proxy.</param> /// <returns> /// Numeric value result. /// </returns> protected override List <double> Predict(MLModelConfig model, IList <Dictionary <string, object> > dataForPrediction, IMLServiceProxy proxy) { List <ScoringOutput> predictionResults = proxy.Score(model, dataForPrediction, false); List <double> scores = predictionResults.Select(output => output.Score).ToList(); return(scores); }
private static void UpdateBatchDate(MLModelConfig modelConfig, UserConnection userConnection) { var query = new Update(userConnection, "MLModel") .Set("BatchPredictedOn", Column.Parameter(modelConfig.BatchPredictedOn)) .Where("Id").IsEqual(Column.Parameter(modelConfig.Id)); query.Execute(); }
/// <summary> /// Saves the predicted result in entity. /// </summary> /// <param name="model">The model.</param> /// <param name="entityId">The entity identifier.</param> /// <param name="predictedResult">The predicted result.</param> protected override void SaveEntityPredictedValues(MLModelConfig model, Guid entityId, double predictedResult) { var predictedValues = new Dictionary <MLModelConfig, double> { { model, predictedResult } }; PredictionSaver.SaveEntityRegressionValues(model.EntitySchemaId, entityId, predictedValues); }
/// <summary> /// Predicts data for the given list of records. /// </summary> /// <param name="model">The model.</param> /// <param name="dataList">The data for prediction.</param> /// <returns>Batch prediction result list.</returns> protected virtual List <TOut> Predict(MLModelConfig model, IList <Dictionary <string, object> > dataList) { var connectionArg = new ConstructorArgument("userConnection", _userConnection); var predictor = ClassFactory.Get <IMLPredictor <TOut> >(model.ProblemType.ToString().ToUpper(), connectionArg); return(predictor.Predict(model, dataList)); }
/// <summary> /// Saves the predicted result in entity. /// </summary> /// <param name="model">The model.</param> /// <param name="entityId">The entity identifier.</param> /// <param name="predictedResult">The predicted result.</param> protected override void SaveEntityPredictedValues(MLModelConfig model, Guid entityId, ScoringOutput predictedResult) { var predictedValues = new Dictionary <MLModelConfig, double> { { model, predictedResult.Score } }; PredictionSaver.SaveEntityScoredValues(model.EntitySchemaId, entityId, predictedValues); }
/// <summary> /// Tries to load the model by its id. /// </summary> /// <param name="userConnection">The user connection.</param> /// <param name="modelId">Identifier of the model.</param> /// <param name="model">Loaded model.</param> /// <returns><c>true</c> - if model successfully loaded, otherwise - <c>false</c>.</returns> public bool TryLoadModel(UserConnection userConnection, Guid modelId, out MLModelConfig model) { var models = LoadModels(userConnection, false, false, new List <Guid> { modelId }); model = models.FirstOrDefault(); return(model != null); }
/// <summary> /// Predicts using the specified proxy. /// </summary> /// <param name="proxy">The proxy.</param> /// <param name="model">The model.</param> /// <param name="data">The input data.</param> /// <returns> /// Predicted result. /// </returns> protected override double Predict(IMLServiceProxy proxy, MLModelConfig model, Dictionary <string, object> data) { var wrappedData = new List <Dictionary <string, object> > { data }; return(proxy.Regress(model.ModelInstanceUId, wrappedData).FirstOrDefault()); }
/// <summary> /// Saves the predicted data to entities. /// </summary> /// <param name="modelConfig">Machine learning model configuration.</param> /// <param name="predictedData">Dictionary where key is entity identifier and value is predicted /// result for that entity.</param> public void SavePredictedData(MLModelConfig modelConfig, Dictionary <Guid, object> predictedData) { if (predictedData.IsNullOrEmpty()) { _log.Info("MLBatchNumericPredictor.SavePredictedData: predictedData is empty. " + $"Model {modelConfig.Id}"); return; } UpdateEntitiesTargetColumn(modelConfig, predictedData); }
/// <summary> /// Scores rates for list of items with the given data using the specified model. /// </summary> /// <param name="model">Model, that should perform scoring.</param> /// <param name="dataList">The list of data of items that should be scored.</param> /// <param name="predictContributions"> /// Indicates, if service should return individual feature contributions to overall prediction. /// </param> /// <returns>Predicted score rates.</returns> public List <ScoringOutput> Score(MLModelConfig model, IList <Dictionary <string, object> > dataList, bool predictContributions) { int count = Math.Min(1, dataList.Count); int timeout = Math.Max(ScoreTimeoutSec * count, BatchScoreTimeoutSec); ScoringResponse response = Predict <ScoringRequest, ScoringResponse>(model.ModelInstanceUId, dataList, model.PredictionEndpoint, timeout, predictContributions); return(response.Outputs); }
/// <summary> /// Scores rate for item with the given data using the specified model. /// </summary> /// <param name="model">Model, that should perform scoring.</param> /// <param name="data">The data of the item that should be scored.</param> /// <param name="predictContributions"> /// Indicates, if service should return individual feature contributions to overall prediction. /// </param> /// <returns>Predicted score rate.</returns> public ScoringOutput Score(MLModelConfig model, Dictionary <string, object> data, bool predictContributions) { ScoringResponse response = Predict <ScoringRequest, ScoringResponse>(model.ModelInstanceUId, new List <Dictionary <string, object> > { data }, model.PredictionEndpoint, ScoreTimeoutSec, predictContributions); return(response.Outputs.FirstOrDefault()); }
private MLModelConfig GetModelConfig(Guid modelId) { MLModelConfig model = _modelLoader.LoadModelForTraining(UserConnection, modelId); if (model == null) { throw new ItemNotFoundException($"Model not found by id {modelId}"); } return(model); }
protected override void SaveEntityPredictedValues(MLModelConfig model, Guid entityId, List <ClassificationResult> predictedResult) { var connectionArg = new ConstructorArgument("userConnection", _userConnection); var filter = ClassFactory.Get <MLBasePredictedValueFilter>(connectionArg); var predictedValues = new Dictionary <MLModelConfig, List <ClassificationResult> > { { model, predictedResult } }; PredictionSaver.SaveEntityPredictedValues(model.EntitySchemaId, entityId, predictedValues, filter.OnSetupPredictedValue); }
private static void LoadMLModelColumns(UserConnection userConnection, MLModelConfig modelConfig) { modelConfig.ColumnUIds = new List <Guid>(); var columnExpressions = new List <MLColumnExpression>(); modelConfig.ColumnExpressions = columnExpressions; if (modelConfig.ProblemType == new Guid(MLConsts.CollaborativeFiltering)) { ReadCollaborativeFilteringModelColumns(modelConfig, columnExpressions); return; } var esq = new EntitySchemaQuery(userConnection.EntitySchemaManager, "MLModelColumn") { IgnoreDisplayValues = true }; esq.AddAllSchemaColumns(skipSystemColumns: true); esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "MLModel", modelConfig.Id)); var entities = esq.GetEntityCollection(userConnection); var rootSchema = userConnection.EntitySchemaManager.FindInstanceByUId(modelConfig.EntitySchemaId); foreach (var entity in entities) { Guid columnUId = entity.GetTypedColumnValue <Guid>("ColumnUId"); string columnPath = entity.GetTypedColumnValue <string>("ColumnPath"); string subFilters = entity.GetTypedColumnValue <string>("SubFilters") ?? string.Empty; if (columnPath.IsNotNullOrEmpty()) { columnExpressions.Add(new MLColumnExpression { ColumnPath = columnPath, AggregationType = (AggregationType)entity.GetTypedColumnValue <int>("AggregationType"), SubFilters = JsonConvert.DeserializeObject <Filters>(subFilters), Caption = entity.GetTypedColumnValue <string>("Caption") }); } else if (columnUId.IsNotEmpty()) { var column = rootSchema.Columns.FindByUId(columnUId); if (column == null) { _log.WarnFormat("Column '{0}' was not found in schema {1} while loading columns for model {2}", columnUId, rootSchema.Name, modelConfig.Id); } else { columnExpressions.Add(new MLColumnExpression { ColumnPath = column.Name, Caption = entity.GetTypedColumnValue <string>("Caption") }); } } } }
private static void SetupTrainingInfo(UserConnection userConnection, MLModelConfig modelConfig, IDataReader reader) { modelConfig.TrainingMinimumRecordsCount = reader.GetColumnValue <int>("TrainingMinimumRecordsCount"); if (modelConfig.TrainingMinimumRecordsCount == 0) { modelConfig.TrainingMinimumRecordsCount = SysSettings.GetValue(userConnection, TrainingMinimumRecordsCountSysSettingsName, 0); } modelConfig.TrainSessionId = reader.GetColumnValue <Guid>("TrainSessionId"); modelConfig.MetricThreshold = reader.GetColumnValue <double>("MetricThreshold"); modelConfig.TrainingOutputFilterData = reader.GetColumnValue <byte[]>("TrainingOutputFilterData"); }
/// <summary> /// Initializes a new instance of the <see cref="MLModelTrainer"/> class. /// </summary> /// <param name="userConnection">The user connection.</param> /// <param name="modelConfig">The model configuration.</param> public MLModelTrainer(UserConnection userConnection, MLModelConfig modelConfig) { userConnection.CheckArgumentNull("userConnection"); modelConfig.CheckArgumentNull("modelConfig"); modelConfig.Id.CheckArgumentEmpty("MLModelConfig.Id"); _userConnection = userConnection; _modelConfig = modelConfig; _proxy = InitServiceProxy(); ConstructorArgument userConnectionArg = new ConstructorArgument("userConnection", _userConnection); _modelEventsNotifier = ClassFactory.Get <MLModelEventsNotifier>(userConnectionArg); _metadataGenerator = ClassFactory.Get <IMLMetadataGenerator>(); _queryBuilder = ClassFactory.Get <IMLModelQueryBuilder>(userConnectionArg); }
private IList <MLModelConfig> LoadModels(UserConnection userConnection, bool enabledForPredictionOnly, bool useAutoBatchMode, IList <Guid> modelIds = null, bool safe = false) { userConnection.LicHelper.CheckHasOperationLicense(MLConsts.LicOperationCode); var select = GetModelBaseSelectQuery(userConnection); var mlModelConfigs = new List <MLModelConfig>(); if (enabledForPredictionOnly) { select .Where("PredictionEnabled").IsEqual(Column.Parameter(true, "Boolean")) .And(Func.Len("ModelInstanceUId")).IsGreater(Column.Const(0)) .And(Func.Len("ServiceUrl")).IsGreater(Column.Const(0)); } if (modelIds != null) { var condition = new QueryCondition(QueryConditionType.In) { LeftExpression = new QueryColumnExpression("m", "Id") }; condition.RightExpressions.AddExpressionsRange(Column.Parameters(modelIds)); AddCondition(select, condition); } if (useAutoBatchMode) { var condition = new QueryCondition(QueryConditionType.Equal) { LeftExpression = new QueryColumnExpression("m", "BatchPredictionStartMethodId") }; condition.RightExpressions.Add(Column.Parameter(new Guid(MLConsts.MaintenanceWindowStartMethod))); AddCondition(select, condition); } select.ExecuteReader(reader => { if (useAutoBatchMode && !CheckBatchFrequency(reader, userConnection)) { return; } try { MLModelConfig modelConfig = FetchModelConfig(userConnection, reader); mlModelConfigs.Add(modelConfig); } catch (Exception e) { _log.Error($"Failed to load model {reader.GetColumnValue<Guid>("Id")}. Exception is {e}"); if (!safe) { throw; } } }); return(mlModelConfigs); }
/// <summary> /// Loads the model metadata captions. Sets enriched metadata to <see cref="MLModelConfig.MetaData"/> property. /// </summary> /// <param name="userConnection">The user connection.</param> /// <param name="model">Loaded model.</param> public void LoadModelMetadataCaptions(UserConnection userConnection, MLModelConfig model) { if (model.MetaData.IsNullOrEmpty()) { return; } ModelSchemaMetadata metadata = model.GetModelSchemaMetadata(); if (metadata.Inputs.IsNullOrEmpty() && metadata.Output == null) { return; } var modelSchema = userConnection.EntitySchemaManager.GetInstanceByName("MLModel"); var modelEntity = modelSchema.CreateEntity(userConnection); modelEntity.PrimaryColumnValue = model.Id; if (!modelEntity.FetchFromDB(new[] { "MetaDataLcz" }, false)) { return; } string serializedMetadataLcz = modelEntity.GetTypedColumnValue <string>("MetaDataLcz"); if (serializedMetadataLcz.IsNullOrEmpty()) { return; } ModelSchemaMetadata metaDataLcz; try { metaDataLcz = JsonConvert.DeserializeObject <ModelSchemaMetadata>(serializedMetadataLcz); } catch (Exception e) { _log.Warn($"Can't localize metadata for {model.Id}, because MetaDataLcz has incorrect format: " + serializedMetadataLcz, e); return; } metadata.Inputs?.ForEach(input => { var inputLcz = metaDataLcz.Inputs.Find(schemaInput => schemaInput.Name == input.Name); if (inputLcz == null) { return; } input.Caption = inputLcz.Caption; }); if (metadata.Output != null) { metadata.Output.Caption = metaDataLcz.Output?.Caption; } model.MetaData = JsonConvert.SerializeObject(metadata, Formatting.Indented); }
private void UpdateEntitiesTargetColumn(MLModelConfig model, Dictionary <Guid, object> predictedData) { if (predictedData.IsNullOrEmpty()) { return; } var entitySchema = _userConnection.EntitySchemaManager.GetInstanceByUId(model.EntitySchemaId); var entitySchemaName = entitySchema.Name; foreach (KeyValuePair <Guid, object> prediction in predictedData) { Guid entityId = prediction.Key; double value = Convert.ToDouble(prediction.Value); UpdateEntityTargetColumn(entitySchemaName, model.PredictedResultColumnName, entityId, value); } }
/// <summary> /// Loads the ml model config by id with fields needed for training. /// </summary> /// <param name="userConnection">The user connection.</param> /// <param name="modelId">The model identifier.</param> /// <returns>Loaded model.</returns> public MLModelConfig LoadModelForTraining(UserConnection userConnection, Guid modelId) { userConnection.LicHelper.CheckHasOperationLicense(MLConsts.LicOperationCode); var select = (Select)GetModelBaseSelectQuery(userConnection) .Column("m", "TrainingMinimumRecordsCount") .Column("m", "TrainSessionId") .Column("m", "MetricThreshold") .Column("m", "TrainingOutputFilterData") .Where("m", "Id").IsEqual(Column.Parameter(modelId, "Guid")); MLModelConfig modelConfig = null; select.ExecuteReader(reader => { modelConfig = FetchModelConfig(userConnection, reader); SetupTrainingInfo(userConnection, modelConfig, reader); }); return(modelConfig); }
private static MLModelConfig FetchModelConfig(UserConnection userConnection, IDataReader reader) { DateTime batchPredictedOn = reader.GetColumnValue <DateTime>("BatchPredictedOn"); batchPredictedOn = DateTime.SpecifyKind(batchPredictedOn, DateTimeKind.Utc); var rootSchemaUId = reader.GetColumnValue <Guid>("RootSchemaUId"); var targetColumnUId = FindValue <Guid>(reader, "TargetColumnUId", Guid.Empty); var modelConfig = new MLModelConfig { Id = reader.GetColumnValue <Guid>("Id"), MetaData = reader.GetColumnValue <string>("MetaData"), TrainingSetQuery = reader.GetColumnValue <string>("TrainingSetQuery"), ServiceUrl = reader.GetColumnValue <string>("ServiceUrl"), PredictionEndpoint = reader.GetColumnValue <string>("PredictionEndpoint"), TrainingEndpoint = reader.GetColumnValue <string>("TrainingEndpoint"), BatchPredictionQuery = reader.GetColumnValue <string>("BatchPredictionQuery"), ProblemType = reader.GetColumnValue <Guid>("MLProblemTypeId"), ModelInstanceUId = reader.GetColumnValue <Guid>("ModelInstanceUId"), TrainingFilterData = reader.GetColumnValue <byte[]>("TrainingFilterData"), BatchPredictionFilterData = reader.GetColumnValue <byte[]>("BatchPredictionFilterData"), TrainingTargetColumnName = FindEntityColumnValueName(userConnection, rootSchemaUId, targetColumnUId), EntitySchemaId = rootSchemaUId, BatchPredictedOn = batchPredictedOn, ConfidentValueMethodId = reader.GetColumnValue <Guid>("MLConfidentValueMethodId"), ConfidentValueLowEdge = reader.GetColumnValue <double>("ConfidentValueLowEdge"), CFItemColumnPath = reader.GetColumnValue <string>("CFItemColumnPath"), CFUserColumnPath = reader.GetColumnValue <string>("CFUserColumnPath"), CFInteractionValueColumnPath = reader.GetColumnValue <string>("CFInteractionValueColumnPath"), CFResultSchemaUId = reader.GetColumnValue <Guid>("CFResultSchemaUId"), CFResultUserColumnName = reader.GetColumnValue <string>("CFResultUserColumnName"), CFResultItemColumnName = reader.GetColumnValue <string>("CFResultItemColumnName"), CFResultValueColumnName = reader.GetColumnValue <string>("CFResultValueColumnName"), CFResultModelColumnName = reader.GetColumnValue <string>("CFResultModelColumnName"), CFResultTimestampColumnName = reader.GetColumnValue <string>("CFResultTimestampColumnName") }; modelConfig.RegularizationValues = ParseValueListColumnAsHashSet <double>(reader, "RegularizationValues"); modelConfig.FactorsCounts = ParseValueListColumnAsHashSet <int>(reader, "FactorsCounts"); if (modelConfig.BatchPredictionQuery.IsNullOrEmpty() && modelConfig.TrainingSetQuery.IsNotNullOrEmpty()) { modelConfig.BatchPredictionQuery = modelConfig.TrainingSetQuery; } SetPredictedResultColumnName(modelConfig, userConnection, reader); modelConfig.CurrentState = GetTypedState(reader.GetColumnValue <string>("StateCode")); LoadMLModelColumns(userConnection, modelConfig); return(modelConfig); }
/// <summary> /// Loads the ready for training models on the check point date. /// </summary> /// <param name="userConnection">The user connection.</param> /// <param name="checkPoint">The check point.</param> /// <returns>List of models.</returns> public virtual IList <MLModelConfig> LoadReadyForTrainingModels(UserConnection userConnection, DateTime checkPoint) { userConnection.LicHelper.CheckHasOperationLicense(MLConsts.LicOperationCode); var mlModelConfigs = new List <MLModelConfig>(); object[] needToTrainModelStates = { TrainSessionState.NotStarted.ToString(), TrainSessionState.Done.ToString(), TrainSessionState.Error.ToString() }; var select = (Select)GetModelBaseSelectQuery(userConnection) .Column("m", "TrainFrequency") .Column("m", "TriedToTrainOn") .Column("m", "TrainingMinimumRecordsCount") .Column("m", "TrainingMaxRecordsCount") .Column("m", "TrainSessionId") .Column("m", "MetricThreshold") .Column("m", "TrainingOutputFilterData") .Where(Func.Len("ServiceUrl")).IsGreater(Column.Const(0)) .And(Func.Len("MetaData")).IsGreater(Column.Const(0)) .And("TrainFrequency").IsGreater(Column.Const(0)) .And(Func.Len("TrainingSetQuery")).IsGreater(Column.Const(0)) .And("s", "Code").In(Column.Parameters(needToTrainModelStates)); select.ExecuteReader(reader => { DateTime triedToTrainOn = reader.GetColumnValue <DateTime>("TriedToTrainOn"); int trainFrequencyDays = reader.GetColumnValue <int>("TrainFrequency"); Guid modelId = reader.GetColumnValue <Guid>("Id"); if (triedToTrainOn != default(DateTime)) { DateTime plannedDate = triedToTrainOn.AddDays(trainFrequencyDays); if (plannedDate > checkPoint) { _log.DebugFormat("Training for model id '{0}' not started. PlannedDate is {1}.", modelId, plannedDate); return; } } MLModelConfig modelConfig = FetchModelConfig(userConnection, reader); SetupTrainingInfo(userConnection, modelConfig, reader); mlModelConfigs.Add(modelConfig); }); return(mlModelConfigs); }
private List <double> Predict(MLModelConfig model, IList <Dictionary <string, object> > dataForPrediction) { var apiKey = BpmonlineCloudEngine.GetAPIKey(_userConnection); var serviceUrlArg = new ConstructorArgument("serviceUrl", model.ServiceUrl); var apiKeyArg = new ConstructorArgument("apiKey", apiKey); IMLServiceProxy proxy; try { proxy = ClassFactory.Get <IMLServiceProxy>(serviceUrlArg, apiKeyArg); } catch (IncorrectConfigurationException ex) { _log.WarnFormat($"Can't predict value for model {model.Id}", ex); throw; } var predictionResults = Predict(model, dataForPrediction, proxy); return(predictionResults); }