1
0
Files
TestMicrosoftML/testML/DictionaryToObjectConverter.cs

168 lines
4.4 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.Threading.Tasks;
namespace testML
{
public static class DictionaryToObjectConverter
{
public static IEnumerable<object> Convert(List<Dictionary<string, object>> data, string toPredict, out Type classType, out DataViewSchema schema)
{
var schemaBuilder = new DataViewSchema.Builder();
var definition = new Dictionary<string, Type>();
var sample = data.FirstOrDefault();
if (sample != null)
{
foreach (var key in sample.Keys)
{
//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();
if (key == toPredict)
{
keyType = typeof(float);
}
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 converter = new DictionaryToObjectConverterClass()
{
ClassName = "OBJ" + Guid.NewGuid().ToString("N").ToUpper(),
ToPredict = toPredict,
Definition = definition
};
var classCode = converter.TransformText();
string exDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory().Trim(Path.DirectorySeparatorChar);
CompilerParameters compilerParameters = new CompilerParameters
{
GenerateExecutable = false,
GenerateInMemory = true,
IncludeDebugInformation = true,
TreatWarningsAsErrors = false,
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 }
);
var dllAssembly = compilerResults.CompiledAssembly;
classType = dllAssembly.GetType("DictionaryToObjectConverterNamespace." + converter.ClassName);
Type listType = typeof(List<>);
Type genericType = listType.MakeGenericType(classType);
var result =(IList) Activator.CreateInstance(genericType) ;
Dictionary<string, float> translate = new Dictionary<string, float>();
translate.Add(string.Empty, 0);
foreach (var inputData in data)
{
if (inputData.ContainsKey(toPredict) && inputData[toPredict] != null)
{
if (!translate.ContainsKey(inputData[toPredict] as string))
{
var max = translate.Values.Max()+1;
translate.Add(inputData[toPredict] as string, max);
}
}
}
foreach (var inputData in data)
{
var outputData = (IDictionaryToObjectConverter)Activator.CreateInstance(classType);
result.Add(outputData);
foreach (var key in inputData.Keys)
{
if (key == toPredict)
{
outputData[key] = translate[inputData[key] as string ?? string.Empty];
}
else
{
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);
}
}