¿Por qué considerar Go para ML en absoluto?
Python es un gran lenguaje para la creación de prototipos y la investigación, pero tiene sus limitaciones:
Productividad: Python es lento, especialmente sin bibliotecas optimizadas
Paralelismo: GIL (Global Interpreter Lock) complica la multihilo
Despliegue: empaquetar aplicaciones Python con dependencias es una tarea difícil
Tipificación: la tipificación dinámica puede provocar errores en la producción
Go resuelve muchos de estos problemas:
Lenguaje compilado de alto rendimiento
Soporte integrado para la competitividad a través de la rutina
Un archivo binario sin dependencias
Tipificación estática
¿Qué se puede hacer en Go en el área de ML?
1. Inferencia (aplicación de modelos listos para usar)
El escenario más popular es el uso de modelos ya entrenados. Entrenas el modelo en Python y luego lo usas en producción en Go.
Ejemplo con ONNX Runtime:
package main
import (
"fmt"
onnxruntime "github.com/yalue/onnxruntime_go"
)
func main() {
// Cargando el modelo entrenado en PyTorch/TensorFlow
session, err := onnxruntime.NewSession[float32](
"model.onnx",
[]string{"input"},
[]string{"output"},
nil,
)
if err != nil {
panic(err)
}
defer session.Destroy()
// Preparando datos de entrada
input := []float32{1.0, 2.0, 3.0, 4.0}
// Hacemos una predicción
output, err := session.Run([][]float32{input})
if err != nil {
panic(err)
}
fmt.Println("Prediction:", output[0])
}2. Algoritmos clásicos de ML
Muchas tareas no requieren redes neuronales. Regresión lineal, árboles de decisión, k-means: todo esto se puede implementar en Go.
Biblioteca GoLearn:
package main
import (
"fmt"
"github.com/sjwhitworth/golearn/base"
"github.com/sjwhitworth/golearn/evaluation"
"github.com/sjwhitworth/golearn/knn"
)
func main() {
// Cargando datos
rawData, err := base.ParseCSVToInstances("data.csv", true)
if err != nil {
panic(err)
}
// Creación de un clasificador KNN
cls := knn.NewKnnClassifier("euclidean", "linear", 2)
// Dividimos en train/test
trainData, testData := base.InstancesTrainTestSplit(rawData, 0.7)
// Formación
cls.Fit(trainData)
// Comprobamos la precisión
predictions, err := cls.Predict(testData)
if err != nil {
panic(err)
}
confusionMat, err := evaluation.GetConfusionMatrix(testData, predictions)
if err != nil {
panic(err)
}
fmt.Println(evaluation.GetAccuracy(confusionMat))
}3. Procesamiento de datos e ingeniería de características
Go es ideal para pipelines ETL y procesamiento de grandes volúmenes de datos.
package main
import (
"encoding/csv"
"os"
"strconv"
"sync"
)
type DataPoint struct {
Feature1 float64
Feature2 float64
Label int
}
func processData(filename string) ([]DataPoint, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
reader := csv.NewReader(file)
records, err := reader.ReadAll()
if err != nil {
return nil, err
}
// Procesamiento paralelo a través de núcleos
var wg sync.WaitGroup
results := make([]DataPoint, len(records)-1)
for i, record := range records[1:] {
wg.Add(1)
go func(idx int, rec []string) {
defer wg.Done()
f1, _ := strconv.ParseFloat(rec[0], 64)
f2, _ := strconv.ParseFloat(rec[1], 64)
label, _ := strconv.Atoi(rec[2])
// Normalización u otras transformaciones
results[idx] = DataPoint{
Feature1: (f1 - 50) / 10,
Feature2: (f2 - 100) / 20,
Label: label,
}
}(i, record)
}
wg.Wait()
return results, nil
}4. Microservicios para ML
Go es ideal para crear API que sirven modelos de ML:
package main
import (
"encoding/json"
"net/http"
"log"
)
type PredictionRequest struct {
Features []float64 `json:"features"`
}
type PredictionResponse struct {
Prediction float64 `json:"prediction"`
Confidence float64 `json:"confidence"`
}
func predictHandler(w http.ResponseWriter, r *http.Request) {
var req PredictionRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Aquí llamamos a tu modelo
prediction := runModel(req.Features)
response := PredictionResponse{
Prediction: prediction,
Confidence: 0.95,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func runModel(features []float64) float64 {
// Tu lógica de inferencia
return 42.0
}
func main() {
http.HandleFunc("/predict", predictHandler)
log.Println("Server starting on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Bibliotecas Go populares para ML
Gorgonia — biblioteca para construir redes neuronales, similar a PyTorch
GoLearn - algoritmos clásicos de ML
Gonum — cálculos numéricos (análogos a NumPy)
ONNX Runtime Go — lanzamiento de modelos ONNX
TensorFlow Go — Enlaces Go para TensorFlow
¿Cuándo usar Go y cuándo Python?
Utiliza Go cuando:
Se necesita un alto rendimiento en producción
La facilidad de implementación es importante (un binario)
Trabaja con cargas competitivas
Utiliza modelos listos para usar (inferencia)
Construye microservicios de ML
Quédate con Python cuando:
Realiza investigaciones y experimentos
Entrenar redes neuronales complejas
Necesito una amplia selección de bibliotecas
Trabaja con un equipo de científicos de datos
La opción más práctica:
Python para el entrenamiento de modelos, experimentos, ciencia de datos
Go para entorno de producción, API, procesamiento de datos
Este enfoque aprovecha los puntos fuertes de cada idioma.
Ejemplo práctico: sistema de recomendaciones.
package main
import (
"math"
"sort"
)
type Item struct {
ID int
Features []float64
}
type Recommendation struct {
ItemID int
Score float64
}
// Similitud de cosinuso func cosineSimilarity(a, b []float64) float64 {
var dotProduct, normA, normB float64
for i := range a {
dotProduct += a[i] * b[i]
normA += a[i] * a[i]
normB += b[i] * b[i]
}
return dotProduct / (math.Sqrt(normA) * math.Sqrt(normB))
}
// Obtenemos recomendacionesfunc getRecommendations(userPrefs []float64, items []Item, topN int) []Recommendation {
recommendations := make([]Recommendation, len(items))
for i, item := range items {
recommendations[i] = Recommendation{
ItemID: item.ID,
Score: cosineSimilarity(userPrefs, item.Features),
}
}
// Ordenar por puntuación
sort.Slice(recommendations, func(i, j int) bool {
return recommendations[i].Score > recommendations[j].Score
})
return recommendations[:topN]
}
func main() {
userPrefs := []float64{0.8, 0.3, 0.9}
items := []Item{
{ID: 1, Features: []float64{0.9, 0.2, 0.8}},
{ID: 2, Features: []float64{0.1, 0.9, 0.2}},
{ID: 3, Features: []float64{0.7, 0.4, 0.9}},
}
recs := getRecommendations(userPrefs, items, 2)
// Mostrará las 2 mejores recomendaciones
}Conclusión
Go puede usarse para construir sistemas de aprendizaje automático, especialmente en un entorno de producción. Sí, Python sigue siendo el estándar para entrenar modelos complejos, pero para la inferencia, el procesamiento de datos y la creación de servicios de alto rendimiento, Go es una excelente opción.
La elección de la herramienta siempre depende de la tarea. No es necesario renunciar a Python por completo, pero tampoco hay que ignorar las capacidades de Go en el campo del aprendizaje automático.
Esto y mucho más se puede estudiar en Codice — analizar todo en detalle y consolidarlo con la práctica con tareas reales. Ofrecemos cursos estructurados en Python, Go, JavaScript y otros lenguajes con un enfoque en la aplicación práctica.
Y si necesitas apoyo y quieres discutir el código con personas de ideas afines, ya tenemos más de 2000 desarrolladores activos en Canal de Telegram, ¡donde siempre te ayudarán, aconsejarán y apoyarán en el camino del aprendizaje de la programación!
🚀 Únete a la comunidad de desarrolladores en Codice!
