Last active
August 29, 2015 14:17
-
-
Save jmhdez/bbccc516d1ba4c53e457 to your computer and use it in GitHub Desktop.
Ejemplo de uso de numl para generar árboles de decisión mediante aprendizaje automático sobre un corpus de Princesas Disney
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Require instalar el paquete numl desde NuGet | |
using System; | |
using numl; | |
using numl.Model; | |
using numl.Supervised.DecisionTree; | |
namespace MachineLearning | |
{ | |
public enum HairColor | |
{ | |
Blonde, | |
Brown, | |
Red, | |
Black, | |
} | |
public class Princess | |
{ | |
public string Name { get; set; } | |
public string Country { get; set; } | |
public int Age { get; set; } | |
public HairColor HairColor { get; set; } | |
public bool Married { get; set; } | |
public bool FatherAlive { get; set; } | |
public bool MotherAlive { get; set; } | |
} | |
class Program | |
{ | |
private static readonly Princess[] PRINCESSES = | |
{ | |
new Princess | |
{ | |
Name = "Blancanieves", | |
Age = 14, | |
Country = "Alemania", | |
FatherAlive = false, | |
MotherAlive = false, | |
HairColor = HairColor.Black, | |
Married = true | |
}, | |
new Princess | |
{ | |
Name = "Cenicienta", | |
Age = 19, | |
Country = "Francia", | |
FatherAlive = false, | |
MotherAlive = false, | |
HairColor = HairColor.Blonde, | |
Married = true, | |
}, | |
new Princess | |
{ | |
Name = "Aurora", | |
Age = 16, | |
Country = "Francia", | |
FatherAlive = true, | |
MotherAlive = true, | |
HairColor = HairColor.Blonde, | |
Married = true, | |
}, | |
new Princess | |
{ | |
Name = "Ariel", | |
Age = 16, | |
Country = "Atlántida", | |
FatherAlive = true, | |
MotherAlive = false, | |
HairColor = HairColor.Red, | |
Married = true, | |
}, | |
new Princess | |
{ | |
Name = "Bella", | |
Age = 18, | |
Country = "Francia", | |
FatherAlive = true, | |
MotherAlive = false, | |
HairColor = HairColor.Brown, | |
Married = true, | |
}, | |
new Princess | |
{ | |
Name = "Jazmín", | |
Age = 16, | |
Country = "Arabia", | |
FatherAlive = true, | |
MotherAlive = false, | |
HairColor = HairColor.Black, | |
Married = true, | |
}, | |
new Princess | |
{ | |
Name = "Pocahontas", | |
Age = 18, | |
Country = "Estados Unidos", | |
FatherAlive = true, | |
MotherAlive = false, | |
HairColor = HairColor.Black, | |
Married = true, | |
}, | |
new Princess | |
{ | |
Name = "Mulán", | |
Age = 19, | |
Country = "China", | |
FatherAlive = true, | |
MotherAlive = true, | |
HairColor = HairColor.Black, | |
Married = true, | |
}, | |
new Princess | |
{ | |
Name = "Tiana", | |
Age = 19, | |
Country = "Maldonia", | |
FatherAlive = false, | |
MotherAlive = true, | |
HairColor = HairColor.Black, | |
Married = true, | |
}, | |
new Princess | |
{ | |
Name = "Rapunzel", | |
Age = 18, | |
Country = "Alemania", | |
FatherAlive = true, | |
MotherAlive = true, | |
HairColor = HairColor.Blonde, | |
Married = true, | |
}, | |
new Princess | |
{ | |
Name = "Mérida", | |
Age = 16, | |
Country = "Escocia", | |
FatherAlive = true, | |
MotherAlive = true, | |
HairColor = HairColor.Red, | |
Married = false, | |
}, | |
new Princess | |
{ | |
Name = "Anna", | |
Age = 18, | |
Country = "Noruega", | |
FatherAlive = false, | |
MotherAlive = false, | |
HairColor = HairColor.Blonde, | |
Married = true, | |
}, | |
new Princess | |
{ | |
Name = "Elsa", | |
Age = 21, | |
Country = "Noruega", | |
FatherAlive = false, | |
MotherAlive = false, | |
HairColor = HairColor.Blonde, | |
Married = false, | |
}, | |
}; | |
static void Main(string[] args) | |
{ | |
Console.Out.WriteLine("Prediciendo matrimonios..."); | |
PredictMarriage(); | |
Console.Out.WriteLine("Prediciendo muertes paternas..."); | |
PredictFatherDecease(); | |
Console.ReadKey(); | |
} | |
private static void PredictMarriage() | |
{ | |
// Creamos un descriptor para ver qué necesita una Princesa Disney para conseguir marido | |
var marriedDescriptor = Descriptor.For<Princess>() | |
.With(x => x.Age) | |
.WithString(property: x => x.Country, asEnum: true, splitType: StringSplitType.Word) | |
.With(x => x.FatherAlive) | |
.With(x => x.MotherAlive) | |
.With(x => x.HairColor) | |
.Learn(x => x.Married); | |
// Preparamos un generador de árboles de decisión... | |
var generator = new DecisionTreeGenerator(marriedDescriptor); | |
// ... que detecte cuando Married = true | |
generator.SetHint(true); | |
// Y lo construimos a partir de los ejemplos | |
var model = Learner.Learn(PRINCESSES, 0.8, 1000, generator); | |
// Veamos qué pinta tiene el árbol que hemos generado | |
Console.Out.WriteLine("Árbol de decisión para bodas reales:"); | |
Console.Out.WriteLine(model); | |
// Vamos a comprobar si una (hipotética) princesa Celia conseguiría casarse | |
var celia = new Princess | |
{ | |
Name = "Celia", | |
Age = 16, | |
Country = "Noruega", | |
FatherAlive = true, | |
MotherAlive = true, | |
HairColor = HairColor.Blonde, | |
}; | |
// Juguemos a los adivinos con Celia | |
var willGetMarried = model.Model.Predict(celia).Married; | |
Console.Out.WriteLine("¿Se casará Celia? {0}", willGetMarried ? "Sí" : "No"); | |
// Sí, se casará. Las princesas noruegas de menos de 19 años se casan | |
} | |
private static void PredictFatherDecease() | |
{ | |
// Creamos un descriptor para ver en qué condiciones muere el padre de una princesa | |
var orphanDescriptor = Descriptor.For<Princess>() | |
.With(x => x.Age) | |
.WithString(property: x => x.Country, asEnum: true, splitType: StringSplitType.Word) | |
.With(x => x.Married) | |
.With(x => x.MotherAlive) | |
.Learn(x => x.FatherAlive); | |
// Preparamos un generador de árboles de decisión... | |
var generator = new DecisionTreeGenerator(orphanDescriptor); | |
// ... que detecte cuando FatherAlive = true | |
generator.SetHint(false); | |
var model = Learner.Learn(PRINCESSES, 0.8, 1000, generator); | |
// Veamos qué pinta tiene el árbol que hemos generado | |
Console.Out.WriteLine("Árbol de decisión para muertes paternas:"); | |
Console.Out.WriteLine(model); | |
// ¿Estará vivo el padre de Rosa? | |
var rosa = new Princess | |
{ | |
Name = "Rosa", | |
Age = 23, | |
Country = "Francia", | |
MotherAlive = true, | |
HairColor = HairColor.Blonde, | |
Married = true, | |
}; | |
// Juguemos a los adivinos con Rosa | |
var isFatherDead = !model.Model.Predict(rosa).FatherAlive; | |
Console.Out.WriteLine("¿Ha muerto el padre de Rosa? {0}", isFatherDead ? "Sí" : "No"); | |
// Estará vivo. Los padres de princesas francesas cuya madre está viva suelen estar vivos | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tremendo ejemplo! Metía numl en la lista "awesome" https://github.com/quozd/awesome-dotnet#machine-learning
La guinda sería recopilar ejemplos reales del uso de numl, más potentes y de uso real, serviría de mucho para los paquetes como yo.
Offtopic- Otra cosa, con http://lmgtfy.com/ saldrían miles de referencias, pero cuál es su elección de única referencia de todas en la que indique cómo conectar VS 2012 o VS 2013 con github ? Es decir, empezar a crear proyectos con VS 2013 y tenerlos en github abiertos a la comunidad.
Gracias.