grydra 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/gr/core.rb +354 -2
  3. data/lib/gr/version.rb +1 -1
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e449d883a411813be922b8336a3e8044d33c36cbecc7590472cf98ba83d7bd24
4
- data.tar.gz: d95118b578b70a82f539153a203be2afb11be345fc5bf317d010ea476b43225c
3
+ metadata.gz: 6c7c8176630e8f46bc755437bf28829564123d4c7b2c352a789abc257bd625f2
4
+ data.tar.gz: c69e061a5b621989d15e7163878cd9302939a69043b4a4f228adbba41ba20563
5
5
  SHA512:
6
- metadata.gz: 83d5f6bad1790e03bd60cf59f061c4e1c3b23eef6dbd4e7a04d475b1262c9543a1cbea0188f6d84fde6de04e927142ef8f5d1f220784e12d7416ad002c06caab
7
- data.tar.gz: 64b5c314cb50f51cc0c01ac6763c2a643442be772b96acbeed26f0c5cb3b54248452c31f4549e06008aa070fc53a9ac07217834b6fd93a6dd3e3b8aa9b1f27ec
6
+ metadata.gz: 034f93c0e54bf6f2209b20efdcb4d0e0670cca1634808b3dab4b8563adb7ec82d071a0e0dea0939a7b00f6b8f3cdd66ee3a6f6b960920a0a8b8950195b1dbc8b
7
+ data.tar.gz: 807c70832d2d0abd31b402dd51b9b28031360ea1ae89cbba2c6b6f68ccc86fc13cd1a7b9acc3a997c6b1fd94e7af18e0e1906328363574681764f6b31f56356e
data/lib/gr/core.rb CHANGED
@@ -538,7 +538,7 @@ module GR
538
538
  {entrada: [[0.1, 0.2]], salida: [[0.3]]},
539
539
  {entrada: [[0.5, 0.6]], salida: [[0.7]]}
540
540
  ]
541
- red = GR::RedPrincipal.new(true) <-- (true) es para que impriam el umbral de error
541
+ red = GR::RedPrincipal.new(true) <-- (true) es para que imprima el umbral de error
542
542
  red.agregar_subred([2, 3, 1])
543
543
  red.agregar_subred([2, 2, 1])
544
544
  red.entrenar_subredes(datos, 0.01, 1000, paciencia: 5)
@@ -576,7 +576,7 @@ module GR
576
576
  {altura: 170, edad: 25, peso: 65},
577
577
  {altura: 160, edad: 30, peso: 60}
578
578
  ]
579
- red = GR::FacilRed.new(true) <-- (true) es para que impriam el umbral de error
579
+ red = GR::FacilRed.new(true) <-- (true) es para que imprima el umbral de error
580
580
  red.entrenar_hashes(datos_hash, [:altura, :edad], :peso, [[4, 1]], 0.05, 15000, :max)
581
581
  EX
582
582
  },
@@ -695,4 +695,356 @@ module GR
695
695
  end
696
696
  print "\e[0m"
697
697
  end
698
+
699
+ #Función para generar ejemplos de uso con la libreria
700
+ def self.generar_ejemplo(num_ejemplo, nombre_archivo = "ejemplo", extension = "rb", path = File.dirname(__FILE__))
701
+ case num_ejemplo
702
+ when 1
703
+ contenido = <<-RUBY
704
+ require 'grydra'
705
+
706
+
707
+ # Datos de entrenamiento
708
+ datos_entrenamiento = [
709
+ { nombre: "Empresa 1", numero_empleados: 5, es_nuevo: false, sitio: true, etiqueta: 0 },
710
+ { nombre: "Empresa 2", numero_empleados: 4, es_nuevo: true, sitio: false, etiqueta: 0 },
711
+ { nombre: "Empresa 3", numero_empleados: 4, es_nuevo: false, sitio: false, etiqueta: 1 },
712
+ { nombre: "Empresa 4", numero_empleados: 20, es_nuevo: false, sitio: false, etiqueta: 1 },
713
+ { nombre: "Empresa 5", numero_empleados: 60, es_nuevo: false, sitio: false, etiqueta: 1 },
714
+ { nombre: "Empresa 6", numero_empleados: 90, es_nuevo: false, sitio: false, etiqueta: 0 },
715
+ { nombre: "Empresa 7", numero_empleados: 33, es_nuevo: true, sitio: false, etiqueta: 0 },
716
+ { nombre: "Empresa 8", numero_empleados: 33, es_nuevo: false, sitio: true, etiqueta: 0 },
717
+ { nombre: "Empresa 9", numero_empleados: 15, es_nuevo: false, sitio: false, etiqueta: 1 },
718
+ { nombre: "Empresa 10", numero_empleados: 40, es_nuevo: false, sitio: true, etiqueta: 0 },
719
+ { nombre: "Empresa 11", numero_empleados: 3, es_nuevo: false, sitio: false, etiqueta: 0 },
720
+ { nombre: "Empresa 12", numero_empleados: 66, es_nuevo: false, sitio: true, etiqueta: 0 },
721
+ { nombre: "Empresa 13", numero_empleados: 15, es_nuevo: true, sitio: false, etiqueta: 0 },
722
+ { nombre: "Empresa 13", numero_empleados: 10, es_nuevo: false, sitio: false, etiqueta: 1 },
723
+ { nombre: "Empresa 13", numero_empleados: 33, es_nuevo: false, sitio: false, etiqueta: 1 },
724
+ { nombre: "Empresa 13", numero_empleados: 8, es_nuevo: false, sitio: false, etiqueta: 1 },
725
+ ]
726
+
727
+ # Creamos el modelo
728
+ modelo = GR::FacilRed.new(true) # true para que imprima el error cada 1000 épocas
729
+
730
+ # Entrenamos directamente usando datos tipo hash
731
+ modelo.entrenar_hashes(
732
+ datos_entrenamiento,
733
+ [:numero_empleados, :es_nuevo, :sitio], # claves a usar como entrada
734
+ :etiqueta, # clave de salida
735
+ [[3, 4, 1]], # estructura de subred: 3 entradas → capa oculta de 4 → 1 salida
736
+ 0.05, # tasa de aprendizaje
737
+ 12000 # épocas
738
+ )
739
+
740
+
741
+ # Guardamos el modelo entrenado
742
+ GR.guardar_modelo(modelo, "modelo_empresas")
743
+
744
+ puts "Entrenamiento completado y modelo guardado exitosamente." #Mensaje de depuración para comprobar la ejecución adecuada
745
+ RUBY
746
+ when 2
747
+ contenido = <<-RUBY
748
+ require 'grydra'
749
+ modelo = nil
750
+ modelo = GR.cargar_modelo("modelo_empresas")
751
+
752
+ # Nuevos datos de empresas a evaluar
753
+ nuevos_datos = [
754
+ { nombre: "Nueva Empresa A", numero_empleados: 12, es_nuevo: true, sitio: true },
755
+ { nombre: "Nueva Empresa B", numero_empleados: 50, es_nuevo: false, sitio: false },
756
+ { nombre: "Nueva Empresa C", numero_empleados: 7, es_nuevo: false, sitio: false },
757
+ { nombre: "Nueva Empresa D", numero_empleados: 22, es_nuevo: true, sitio: true }
758
+ ]
759
+
760
+ # Hacemos predicciones
761
+ predicciones = modelo.predecir_hashes(nuevos_datos, [:numero_empleados, :es_nuevo, :sitio])
762
+
763
+ # Mostrar resultados
764
+ nuevos_datos.each_with_index do |empresa, i|
765
+ prediccion = predicciones[i].first.round(3)
766
+ puts "Empresa: \#{empresa[:nombre]} → Predicción: \#{prediccion} (\#{prediccion >= 0.5 ? 'Etiqueta 1 (Sí)' : 'Etiqueta 0 (No)'})"
767
+ end
768
+ RUBY
769
+
770
+ when 3
771
+ contenido = <<-RUBY
772
+ require 'grydra'
773
+
774
+ # Crear red principal
775
+ red = GR::RedPrincipal.new #Sin el true, simplemente no se imprimen las epocas
776
+
777
+ # Agregar una subred con estructura [2 entradas, 2 ocultas, 1 salida]
778
+ red.agregar_subred([2, 3, 1], [:tanh, :tanh])
779
+ red.agregar_subred([2, 4, 1], [:sigmoid, :sigmoid])
780
+
781
+ # Datos XOR
782
+ entradas = [
783
+ [0, 0],
784
+ [0, 1],
785
+ [1, 0],
786
+ [1, 1]
787
+ ]
788
+
789
+ salidas = [
790
+ [0],
791
+ [1],
792
+ [1],
793
+ [0]
794
+ ]
795
+
796
+
797
+ # Entrenamiento
798
+ epocas = 6000
799
+ tasa_aprendizaje = 0.9
800
+
801
+ red.entrenar_subredes(
802
+ [
803
+ {entrada: entradas, salida: salidas},
804
+ {entrada: entradas, salida: salidas},
805
+ ],
806
+ tasa_aprendizaje,
807
+ epocas,
808
+ batch_size: 1, #Número de datos con los que va a entrenar al mismo tiempo
809
+ paciencia: 100, #Si los resultados no mejoran en (n cantidad) de epocas, entonces pasa
810
+ decay: 0.995 #Número por el cual multiplica
811
+ )
812
+
813
+ # Evaluación
814
+ puts "\\nEvaluación XOR:"
815
+ entradas.each do |entrada|
816
+ salida = red.combinar_resultados(entrada)
817
+ puts "Entrada: \#{entrada} => Salida: \#{salida.map { |v| v.round(3) }}" #>0.5 en este caso seria 1
818
+ end
819
+ RUBY
820
+ when 4
821
+ contenido = <<-RUBY
822
+ require 'grydra'
823
+
824
+ # Datos originales (temperatura Celsius y Fahrenheit)
825
+ datos_in = [[0], [10], [20], [30], [40], [50], [-10], [-20], [100], [-30], [-5], [-40]]
826
+ datos_ou = [[32], [50], [68], [86], [104], [122], [14], [-4], [212], [-22], [23], [-40]]
827
+
828
+ # Encontrar valores máximos para normalizar (método :max)
829
+ max_in = GR.calcular_maximos(datos_in, :max) # {0 => valor}
830
+ max_ou = GR.calcular_maximos(datos_ou, :max) # {0 => valor}
831
+
832
+ # Normalizar datos
833
+ datos_in_no = GR.normalizar_varios(datos_in, max_in, :max)
834
+ datos_ou_no = GR.normalizar_varios(datos_ou, max_ou, :max)
835
+
836
+ # Crear red principal
837
+ red_principal = GR::RedPrincipal.new
838
+
839
+ # Agregar subredes
840
+ red_principal.agregar_subred([1, 4, 1], [:sigmoid, :tanh])
841
+ red_principal.agregar_subred([1, 3, 1], [:relu, :tanh])
842
+ red_principal.agregar_subred([1, 2, 1], [:tanh, :tanh])
843
+
844
+ puts "Entrenando subredes..."
845
+ red_principal.entrenar_subredes(
846
+ [
847
+ { entrada: datos_in_no, salida: datos_ou_no },
848
+ { entrada: datos_in_no, salida: datos_ou_no },
849
+ { entrada: datos_in_no, salida: datos_ou_no }
850
+ ],
851
+ 0.2, # tasa aprendizaje
852
+ 25000, # épocas
853
+ batch_size: 5,
854
+ paciencia: 500,
855
+ decay: 0.995
856
+ )
857
+
858
+ puts "\\nIngrese los grados Celsius separados por espacio:"
859
+ print "<< "
860
+ entrada_usuario = gets.chomp.split.map(&:to_f)
861
+
862
+ # Normalizar entradas
863
+ entrada_usuario_no = entrada_usuario.map { |e| [e] }
864
+ entrada_usuario_no = GR.normalizar_varios(entrada_usuario_no, max_in, :max)
865
+
866
+ puts "\\nResultados combinados:"
867
+ entrada_usuario_no.each_with_index do |entrada_norm, i|
868
+ prediccion_norm = red_principal.combinar_resultados(entrada_norm)
869
+ prediccion = [prediccion_norm[0] * max_ou[0]]
870
+ puts "\#{entrada_usuario[i]} °C : \#{prediccion[0].round(2)} °F"
871
+ end
872
+ RUBY
873
+ when 5
874
+ contenido = <<-RUBY
875
+ require 'grydra'
876
+ =begin
877
+ NOTA IMPORTANTE:
878
+ Si se usa la normalización con zscore, debemos ser mas minusiosos y lo recomendable
879
+ es bajar y subir constantmente la tasa de aprendizaje, pues con zscore una vez llegando
880
+ a los resultados esperados se mantendra por ese margen. La tasa se puede bajar y subir
881
+ tanto como uno quiera, ejemplo:
882
+ 0.003, 0.3, 0.9, 0.2, 0.223, 0.00008
883
+ =end
884
+ # Crear instancia de la clase FacilRed
885
+ red = GR::FacilRed.new(true) # true para imprimir las épocas y errores
886
+
887
+ # Datos originales (temperatura Celsius y Fahrenheit)
888
+ datos_in = [[0], [10], [20], [30], [40], [50], [-10], [-20], [100], [-30], [-5], [-40]]
889
+ datos_out = [[32], [50], [68], [86], [104], [122], [14], [-4], [212], [-22], [23], [-40]]
890
+
891
+ # Definir estructuras de subredes (capas ocultas)
892
+ estructuras = [
893
+ [2, 4, 1], # capa oculta con 4 neuronas, salida 1
894
+ [1, 3, 1], # otra subred, 3 neuronas capa oculta
895
+ [2, 7, 1] # y otra más pequeña
896
+ ]
897
+
898
+ puts "Entrenando red..."
899
+ red.entrenar_numericos(datos_in, datos_out, estructuras, 0.5, 30000, :zscore)
900
+ #red.entrenar_numericos(datos_in, datos_out, estructuras, 0.5, 30000, :max)
901
+
902
+ puts "\nIngrese los grados Celsius separados por espacio:"
903
+ print "<< "
904
+ entrada_usuario = gets.chomp.split.map(&:to_f).map { |v| [v] }
905
+
906
+ predicciones = red.predecir_numericos(entrada_usuario, :zscore)
907
+ #predicciones = red.predecir_numericos(entrada_usuario, :max)
908
+
909
+ puts "\\nResultados:"
910
+ entrada_usuario.each_with_index do |entrada, i|
911
+ f = predicciones[i][0]
912
+ puts "\#{entrada[0]} °C : \#{f.round(2)} °F"
913
+ end
914
+ RUBY
915
+ when 6
916
+ contenido = <<-RUBY
917
+ require 'grydra'
918
+
919
+ # Crear datos de entrada y salida
920
+ datos_entrada = [
921
+ [170, 25],
922
+ [160, 30],
923
+ [180, 22],
924
+ [150, 28],
925
+ [175, 24]
926
+ ]
927
+
928
+ # Peso correspondiente a cada persona (kg)
929
+ datos_salida = [
930
+ [65],
931
+ [60],
932
+ [75],
933
+ [55],
934
+ [70]
935
+ ]
936
+
937
+ # Definir estructuras de las subredes
938
+ # Cada subred tiene: 2 entradas → 3 neuronas ocultas → 1 salida
939
+ estructuras = [
940
+ [3, 1],
941
+ [4, 1]
942
+ ]
943
+
944
+ # Crear red usando la interfaz fácil
945
+ red = GR::FacilRed.new(true) # true para que imprima error por época
946
+
947
+ # Entrenar la red
948
+ red.entrenar_numericos(
949
+ datos_entrada,
950
+ datos_salida,
951
+ estructuras,
952
+ 0.05, # tasa de aprendizaje
953
+ 15000, # épocas
954
+ :max # tipo de normalización
955
+ )
956
+
957
+ # Predecir para un nuevo individuo
958
+ nuevos_datos = [[172, 26]]
959
+
960
+ predicciones = red.predecir_numericos(nuevos_datos, :max)
961
+
962
+ puts "\\nResultado:"
963
+ puts "Altura: \#{nuevos_datos[0][0]}, Edad: \#{nuevos_datos[0][1]} ⇒ Peso estimado: \#{predicciones[0][0].round(2)} kg"
964
+ RUBY
965
+ when 7
966
+ contenido = <<-RUBY
967
+ require 'grydra'
968
+
969
+ # Datos de entrenamiento: [altura (cm), edad (años)]
970
+ datos_entrada = [
971
+ [170, 25],
972
+ [160, 30],
973
+ [180, 22],
974
+ [175, 28],
975
+ [165, 35],
976
+ [155, 40],
977
+ [185, 20]
978
+ ]
979
+
980
+ # Peso real en kg
981
+ datos_salida = [
982
+ [65],
983
+ [60],
984
+ [75],
985
+ [70],
986
+ [62],
987
+ [58],
988
+ [80]
989
+ ]
990
+
991
+ # Estructuras para las subredes: capas ocultas y salida
992
+ estructuras = [
993
+ [4, 1],
994
+ [3, 1],
995
+ [6, 1],
996
+ [2, 1]
997
+ ]
998
+
999
+ # Crear red Fácil
1000
+ red = GR::FacilRed.new # true para ver el progreso de entrenamiento
1001
+
1002
+ # Vamos a asignar activación 'sigmoid' en la última capa para limitar la salida entre 0 y 1
1003
+ # Ajustamos internamente en el método agregar_subred
1004
+
1005
+ estructuras.each do |estructura|
1006
+ # Definimos activaciones: ocultas con :tanh, salida con :sigmoid
1007
+ activaciones = Array.new(estructura.size - 1, :tanh) + [:sigmoid]
1008
+ red.red.agregar_subred([datos_entrada.first.size, *estructura], activaciones)
1009
+ end
1010
+
1011
+ # Normalización :max (fácil de desnormalizar)
1012
+ red.entrenar_numericos(datos_entrada, datos_salida, estructuras, 0.01, 10000, :max)
1013
+
1014
+ # Nueva muestra para predecir: altura=172 cm, edad=26 años
1015
+ nuevos_datos = [[172, 26]]
1016
+
1017
+ # Hacemos predicción (normalizada internamente)
1018
+ predicciones = red.predecir_numericos(nuevos_datos, :max)
1019
+
1020
+ # Las predicciones ya están desnormalizadas por FacilRed, solo redondeamos
1021
+ puts "Predicción peso (kg) para altura \#{nuevos_datos[0][0]} cm y edad \#{nuevos_datos[0][1]} años:"
1022
+ print predicciones.map { |p| p[0].round(2) }
1023
+ GR.guardar_modelo(red, "peso_promedio")
1024
+ RUBY
1025
+ when 8
1026
+ contenido = <<-RUBY
1027
+ # predecir.rb
1028
+ require 'grydra'
1029
+
1030
+ # Cargar el modelo previamente guardado
1031
+ modelo = GR.cargar_modelo("peso_promedio")
1032
+
1033
+ # Datos de entrada para predecir: altura=172 cm, edad=26 años
1034
+ nuevos_datos = [[172, 26]]
1035
+
1036
+ # Normalización que usaste (puede ser :max o :zscore, según entrenaste)
1037
+ normalizacion = :max
1038
+
1039
+ # Realizar predicción
1040
+ predicciones = modelo.predecir_numericos(nuevos_datos, normalizacion)
1041
+
1042
+ puts "Predicción peso (kg) para altura \#{nuevos_datos[0][0]} cm y edad \#{nuevos_datos[0][1]} años:"
1043
+ puts predicciones.map { |p| p[0].round(2) }
1044
+ RUBY
1045
+ end
1046
+ File.write("#{nombre_archivo}.#{extension}", contenido)
1047
+ puts "Ejemplo generado y guardado en \e[33m#{path}/#{nombre_archivo}\e[0m"
1048
+ end
698
1049
  end
1050
+
data/lib/gr/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Gr
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grydra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Razo