conversation contextx, not finished yet.

This commit is contained in:
Oceania2018 2018-10-24 16:57:48 -05:00
parent 6d8da2ae5e
commit b1b88b331a
8 changed files with 112 additions and 19 deletions

View file

@ -3,6 +3,7 @@ using BotSharp.Platform.Models;
using CSRedis;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
@ -76,6 +77,11 @@ namespace BotSharp.Core.AgentStorage
{
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.Indented,
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Converters = new List<JsonConverter>
{
new Newtonsoft.Json.Converters.StringEnumConverter()
}
});
string dataPath = Path.Combine(storageDir, agent.Id + ".json");

View file

@ -22,7 +22,7 @@ namespace BotSharp.Core.Engines
{
public async Task<NlpDoc> Predict(AgentBase agent, AiRequest request)
{
// load model
// load model per context
var dir = Path.Combine(request.AgentDir, request.Model);
Console.WriteLine($"Load model from {dir}");
var metaJson = File.ReadAllText(Path.Combine(dir, "model-meta.json"));

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
@ -94,6 +95,9 @@ namespace BotSharp.Core.Engines
for (int pipeIdx = 0; pipeIdx < pipelines.Count; pipeIdx++)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var pipe = TypeHelper.GetInstance(pipelines[pipeIdx], assemblies) as INlpTrain;
// set configuration to current section
pipe.Configuration = provider.Configuration.GetSection(pipelines[pipeIdx]);
@ -105,8 +109,11 @@ namespace BotSharp.Core.Engines
Time = DateTime.UtcNow
};
meta.Pipeline.Add(pipeModel);
await pipe.Train(agent, data, pipeModel);
stopwatch.Stop();
Console.WriteLine($"Executed pipe {pipeModel.Name} elapsed {stopwatch.Elapsed}");
}
// save model meta data
@ -118,8 +125,6 @@ namespace BotSharp.Core.Engines
});
File.WriteAllText(Path.Combine(settings.ModelDir, "model-meta.json"), metaJson);
Console.WriteLine(metaJson);
return meta;
}
}

View file

@ -1,6 +1,9 @@
using BotSharp.Core.Engines;
using BotSharp.Models.NLP;
using BotSharp.Platform.Abstraction;
using BotSharp.Platform.Models;
using BotSharp.Platform.Models.AiRequest;
using BotSharp.Platform.Models.AiResponse;
using BotSharp.Platform.Models.MachineLearning;
using DotNetToolkit;
using Microsoft.Extensions.Configuration;
@ -16,6 +19,8 @@ namespace BotSharp.Core
{
public abstract class PlatformBuilderBase<TAgent> where TAgent : AgentBase
{
public TAgent Agent { get; set; }
public IAgentStorage<TAgent> Storage { get; set; }
private readonly IAgentStorageFactory<TAgent> agentStorageFactory;
@ -58,6 +63,8 @@ namespace BotSharp.Core
Console.WriteLine($"Loaded agent: {agent.Name} {agent.Id}");
Agent = agent;
return agent;
}
@ -95,12 +102,81 @@ namespace BotSharp.Core
options.Model = "model_" + DateTime.UtcNow.ToString("yyyyMMdd");
}
var trainer = new BotTrainer(settings);
agent.Corpus = corpus;
ModelMetaData meta = null;
var info = await trainer.Train(agent, options);
// train by contexts
corpus.UserSays.GroupBy(x => x.ContextHash).Select(g => new
{
Context = g.Key,
Corpus = new TrainingCorpus
{
Entities = corpus.Entities,
UserSays = corpus.UserSays.Where(x => x.ContextHash == g.Key).ToList()
}
})
.ToList()
.ForEach(async c =>
{
var trainer = new BotTrainer(settings);
agent.Corpus = c.Corpus;
return info;
meta = await trainer.Train(agent, new BotTrainOptions
{
AgentDir = options.AgentDir,
Model = options.Model + $"{Path.DirectorySeparatorChar}{c.Context}"
});
});
meta.Pipeline.Clear();
meta.Model = options.Model;
return meta;
}
public virtual async Task<TResult> TextRequest<TResult>(AiRequest request)
{
string contexts = String.Join("_", request.Contexts);
string contextHash = contexts.GetMd5Hash();
Console.WriteLine($"TextRequest: {request.Text}, {contexts}, {request.SessionId}");
// Load agent
var projectPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Projects", request.AgentId);
var model = Directory.GetDirectories(projectPath).Where(x => x.Contains("model_")).Last().Split(Path.DirectorySeparatorChar).Last();
var modelPath = Path.Combine(projectPath, model);
request.AgentDir = projectPath;
request.Model = model + $"{Path.DirectorySeparatorChar}{contextHash}";
Agent = await GetAgentById(request.AgentId);
var preditor = new BotPredictor();
var doc = await preditor.Predict(Agent, request);
var parameters = new Dictionary<String, Object>();
if (doc.Sentences[0].Entities == null)
{
doc.Sentences[0].Entities = new List<NlpEntity>();
}
doc.Sentences[0].Entities.ForEach(x => parameters[x.Entity] = x.Value);
var predictedIntent = doc.Sentences[0].Intent;
var aiResponse = new AiResponse
{
ResolvedQuery = request.Text,
Score = predictedIntent.Confidence,
Source = predictedIntent.Classifier,
Intent = predictedIntent.Label
};
Console.WriteLine($"TextResponse: {aiResponse.Intent}, {request.SessionId}");
return await AssembleResult<TResult>(aiResponse);
}
public virtual async Task<TResult> AssembleResult<TResult>(AiResponse response)
{
throw new NotImplementedException();
}
public virtual async Task<bool> SaveAgent(TAgent agent)

View file

@ -12,6 +12,8 @@ namespace BotSharp.Platform.Abstraction
/// </summary>
public interface IPlatformBuilder<TAgent>
{
TAgent Agent { get; set; }
/// <summary>
/// Agent storage
/// </summary>
@ -48,5 +50,7 @@ namespace BotSharp.Platform.Abstraction
Task<ModelMetaData> Train(TAgent agent, TrainingCorpus corpus, BotTrainOptions options);
Task<TResult> TextRequest<TResult>(AiRequest request);
Task<TResult> AssembleResult<TResult>(AiResponse response);
}
}

View file

@ -6,12 +6,19 @@ namespace BotSharp.Platform.Models.AiRequest
{
public class AiRequest
{
public AiRequest()
{
Contexts = new List<string>();
}
public string AgentId { get; set; }
public string Text { get; set; }
public string SessionId { get; set; }
public List<String> Contexts { get; set; }
public bool ResetContexts { get; set; }
/// <summary>

View file

@ -6,8 +6,12 @@ namespace BotSharp.Platform.Models.AiResponse
{
public class AiResponse
{
public string Speech { get; set; }
public String ResolvedQuery { get; set; }
public string Intent { get; set; }
public string Source { get; set; }
public double Score { get; set; }
}
}

View file

@ -32,16 +32,7 @@ namespace BotSharp.Platform.Models.Intents
/// Get input contexts hash
/// </summary>
[NotMapped]
public String ContextHash
{
get
{
return string.Empty;
/*return Contexts == null || Contexts.Count == 0
? Guid.Empty.ToString("N")
: $"{String.Join(",", Contexts.OrderBy(x => x.Name).Select(x => x.Name))}".GetMd5Hash();*/
}
}
public String ContextHash { get; set; }
[ForeignKey("IntentId")]
public List<IntentExpression> UserSays { get; set; }