164 lines
4.6 KiB
C#
164 lines
4.6 KiB
C#
using Microsoft.CSharp;
|
|
using Microsoft.ML;
|
|
using Microsoft.ML.Data;
|
|
using System;
|
|
using System.CodeDom.Compiler;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace testML
|
|
{
|
|
public static class DictionaryToObjectConverter
|
|
{
|
|
public static IEnumerable<object> Convert(List<Dictionary<string, object>> data, string toPredict, string objectFilename, out Type classType, out Type classPredictionType, out DataViewSchema schema)
|
|
{
|
|
var regexCR = new Regex(@"_CR\d+");
|
|
var currentCR = regexCR.Match(toPredict).Groups[0].Value;
|
|
|
|
var schemaBuilder = new DataViewSchema.Builder();
|
|
|
|
var definition = new Dictionary<string, Type>();
|
|
|
|
var sample = data.FirstOrDefault();
|
|
if (sample != null)
|
|
{
|
|
foreach (var key in sample.Keys)
|
|
{
|
|
if (!key.Contains(currentCR))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//Buscamos el tipo
|
|
var sampleValue = (from x in data where x.ContainsKey(key) && x[key] != null select x[key]).FirstOrDefault();
|
|
if (sampleValue != null)
|
|
{
|
|
var keyType = sampleValue.GetType();
|
|
definition.Add(key, keyType);
|
|
|
|
if (keyType == typeof(string))
|
|
{
|
|
schemaBuilder.AddColumn(key, TextDataViewType.Instance);
|
|
}
|
|
else if (keyType == typeof(double))
|
|
{
|
|
schemaBuilder.AddColumn(key, NumberDataViewType.Double);
|
|
}
|
|
else if (keyType == typeof(float))
|
|
{
|
|
schemaBuilder.AddColumn(key, NumberDataViewType.Single);
|
|
}
|
|
else if (keyType == typeof(int))
|
|
{
|
|
schemaBuilder.AddColumn(key, NumberDataViewType.Int32);
|
|
}
|
|
else if (keyType == typeof(long))
|
|
{
|
|
schemaBuilder.AddColumn(key, NumberDataViewType.Int64);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var className = "OBJ"+ Path.GetFileNameWithoutExtension(objectFilename).Replace(".", "_");
|
|
|
|
Assembly dllAssembly = null;
|
|
if (File.Exists(Path.Combine(Environment.CurrentDirectory, objectFilename)))
|
|
{
|
|
dllAssembly = Assembly.LoadFrom(Path.Combine(Environment.CurrentDirectory, objectFilename));
|
|
}
|
|
else
|
|
{
|
|
var converter = new DictionaryToObjectConverterClass()
|
|
{
|
|
ClassName = className,
|
|
ToPredict = toPredict,
|
|
Definition = definition
|
|
};
|
|
|
|
var classCode = converter.TransformText();
|
|
|
|
File.WriteAllText(Path.Combine(Environment.CurrentDirectory, objectFilename + ".cs"), classCode, Encoding.UTF8);
|
|
|
|
string exDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory().Trim(Path.DirectorySeparatorChar);
|
|
CompilerParameters compilerParameters = new CompilerParameters
|
|
{
|
|
GenerateExecutable = false,
|
|
GenerateInMemory = false,
|
|
IncludeDebugInformation = true,
|
|
TreatWarningsAsErrors = false,
|
|
OutputAssembly = Path.Combine(Environment.CurrentDirectory, objectFilename),
|
|
CompilerOptions = string.Format("/target:library /lib:{0}", exDir)
|
|
};
|
|
|
|
var mlDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
|
|
|
foreach (var item in AppDomain.CurrentDomain.GetAssemblies())
|
|
{
|
|
compilerParameters.ReferencedAssemblies.Add(item.Location);
|
|
}
|
|
|
|
|
|
// compilerParameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
|
|
|
|
CompilerResults compilerResults =
|
|
new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } }).CompileAssemblyFromSource(compilerParameters,
|
|
new string[] { classCode }
|
|
);
|
|
|
|
dllAssembly = compilerResults.CompiledAssembly;
|
|
}
|
|
|
|
classType = dllAssembly.GetType("DictionaryToObjectConverterNamespace." + className);
|
|
classPredictionType = dllAssembly.GetType("DictionaryToObjectConverterNamespace." + className + "Prediction");
|
|
|
|
Type listType = typeof(List<>);
|
|
Type genericType = listType.MakeGenericType(classType);
|
|
|
|
var result = (IList)Activator.CreateInstance(genericType);
|
|
|
|
|
|
foreach (var inputData in data)
|
|
{
|
|
var outputData = (IDictionaryToObjectConverter)Activator.CreateInstance(classType);
|
|
result.Add(outputData);
|
|
|
|
foreach (var key in inputData.Keys)
|
|
{
|
|
outputData[key] = inputData[key];
|
|
}
|
|
}
|
|
|
|
schema = schemaBuilder.ToSchema();
|
|
|
|
return (IEnumerable<object>)result;
|
|
|
|
}
|
|
}
|
|
|
|
public partial class DictionaryToObjectConverterClass
|
|
{
|
|
public string ClassName { get; set; }
|
|
public string ToPredict { get; set; }
|
|
public Dictionary<string, Type> Definition { get; set; }
|
|
}
|
|
|
|
public interface IDictionaryToObjectConverter
|
|
{
|
|
object this[string propertyName] { get; set; }
|
|
|
|
void SetValue(string propertyName, object value);
|
|
|
|
object GetValue(string propertyName);
|
|
}
|
|
}
|
|
|
|
|