diciembre 21, 2025
16 min de lectura

Preguntas para Entrevistas de Data Scientist Senior: Guía Completa

interview
career-advice
job-search
Preguntas para Entrevistas de Data Scientist Senior: Guía Completa
Milad Bonakdar

Milad Bonakdar

Autor

Domina conceptos avanzados de ciencia de datos con preguntas esenciales para entrevistas que cubren algoritmos avanzados de ML, aprendizaje profundo, implementación de modelos, ingeniería de características, pruebas A/B y big data para data scientists senior.


Introducción

Se espera que los científicos de datos senior diseñen arquitecturas de soluciones de aprendizaje automático de extremo a extremo, optimicen el rendimiento del modelo, implementen modelos en producción y comuniquen información a las partes interesadas. Este rol exige una profunda experiencia en algoritmos avanzados, ingeniería de características, implementación de modelos y la capacidad de resolver problemas empresariales complejos con datos.

Esta guía completa cubre las preguntas esenciales de la entrevista para científicos de datos senior, que abarcan el aprendizaje automático avanzado, el aprendizaje profundo, la ingeniería de características, la implementación de modelos, las pruebas A/B y las tecnologías de big data. Cada pregunta incluye respuestas detalladas, evaluación de rareza y calificaciones de dificultad.


Aprendizaje automático avanzado (6 preguntas)

1. Explique el equilibrio entre sesgo y varianza.

Respuesta: El equilibrio entre sesgo y varianza describe la relación entre la complejidad del modelo y el error de predicción.

  • Sesgo: Error derivado de simplificar en exceso las suposiciones (ajuste insuficiente)
  • Varianza: Error derivado de la sensibilidad a las fluctuaciones de los datos de entrenamiento (sobreajuste)
  • Equilibrio: Disminuir el sesgo aumenta la varianza y viceversa
  • Objetivo: Encontrar el equilibrio óptimo que minimice el error total
Loading diagram...
import numpy as np
from sklearn.model_selection import learning_curve
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt

# Generar datos
X = np.random.rand(100, 1) * 10
y = 2 * X + 3 + np.random.randn(100, 1) * 2

# Modelo de alto sesgo (max_depth=1)
high_bias = DecisionTreeRegressor(max_depth=1)

# Modelo de alta varianza (max_depth=20)
high_variance = DecisionTreeRegressor(max_depth=20)

# Modelo óptimo (max_depth=3)
optimal = DecisionTreeRegressor(max_depth=3)

# Las curvas de aprendizaje muestran el equilibrio entre sesgo y varianza
train_sizes, train_scores, val_scores = learning_curve(
    optimal, X, y.ravel(), cv=5, train_sizes=np.linspace(0.1, 1.0, 10)
)

print(f"Puntuación de entrenamiento: {train_scores.mean():.2f}")
print(f"Puntuación de validación: {val_scores.mean():.2f}")

Rareza: Muy común Dificultad: Difícil


2. ¿Qué es la regularización y explique la regularización L1 frente a L2?

Respuesta: La regularización añade un término de penalización a la función de pérdida para evitar el sobreajuste.

  • L1 (Lazo):
    • Penalización: Suma de los valores absolutos de los coeficientes
    • Efecto: Modelos dispersos (algunos coeficientes se convierten exactamente en 0)
    • Uso: Selección de características
  • L2 (Ridge):
    • Penalización: Suma de los coeficientes al cuadrado
    • Efecto: Reduce los coeficientes hacia 0 (pero no exactamente 0)
    • Uso: Cuando todas las características son potencialmente relevantes
  • Elastic Net: Combina L1 y L2
from sklearn.linear_model import Lasso, Ridge, ElasticNet
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
import numpy as np

# Generar datos con muchas características
X, y = make_regression(n_samples=100, n_features=20, n_informative=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

# Regularización L1 (Lazo)
lasso = Lasso(alpha=1.0)
lasso.fit(X_train, y_train)
print(f"Coeficientes de Lazo: {np.sum(lasso.coef_ != 0)} no cero de {len(lasso.coef_)}")

# Regularización L2 (Ridge)
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)
print(f"Coeficientes de Ridge: {np.sum(ridge.coef_ != 0)} no cero de {len(ridge.coef_)}")

# Elastic Net (L1 + L2)
elastic = ElasticNet(alpha=1.0, l1_ratio=0.5)
elastic.fit(X_train, y_train)

print(f"\nPuntuación de Lazo: {lasso.score(X_test, y_test):.3f}")
print(f"Puntuación de Ridge: {ridge.score(X_test, y_test):.3f}")
print(f"Puntuación de Elastic Net: {elastic.score(X_test, y_test):.3f}")

Rareza: Muy común Dificultad: Media


3. Explique los métodos de conjunto: Bagging vs Boosting.

Respuesta: Los métodos de conjunto combinan múltiples modelos para mejorar el rendimiento.

  • Bagging (Bootstrap Aggregating):
    • Entrenar modelos en paralelo en subconjuntos aleatorios
    • Reduce la varianza
    • Ejemplo: Bosque aleatorio
  • Boosting:
    • Entrenar modelos secuencialmente, cada uno corrigiendo errores anteriores
    • Reduce el sesgo
    • Ejemplos: AdaBoost, Gradient Boosting, XGBoost
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split, cross_val_score

# Cargar datos
data = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
    data.data, data.target, test_size=0.3, random_state=42
)

# Bagging - Bosque aleatorio
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
rf_score = rf.score(X_test, y_test)

# Boosting - Gradient Boosting
gb = GradientBoostingClassifier(n_estimators=100, random_state=42)
gb.fit(X_train, y_train)
gb_score = gb.score(X_test, y_test)

print(f"Precisión de Bosque Aleatorio (Bagging): {rf_score:.3f}")
print(f"Precisión de Gradient Boosting: {gb_score:.3f}")

# Validación cruzada
rf_cv = cross_val_score(rf, data.data, data.target, cv=5)
gb_cv = cross_val_score(gb, data.data, data.target, cv=5)

print(f"\nPuntuaciones de CV de RF: {rf_cv.mean():.3f} (+/- {rf_cv.std():.3f})")
print(f"Puntuaciones de CV de GB: {gb_cv.mean():.3f} (+/- {gb_cv.std():.3f})")

Rareza: Muy común Dificultad: Difícil


4. ¿Qué es la validación cruzada y por qué k-fold es mejor que la división de entrenamiento-prueba?

Respuesta: La validación cruzada evalúa el rendimiento del modelo de forma más robusta que una única división de entrenamiento-prueba.

  • K-Fold CV:
    • Divide los datos en k pliegues
    • Entrena k veces, cada vez utilizando un pliegue diferente como validación
    • Promedia los resultados
  • Beneficios:
    • Estimación del rendimiento más fiable
    • Utiliza todos los datos tanto para el entrenamiento como para la validación
    • Reduce la varianza en la estimación del rendimiento
  • Variaciones: K-Fold estratificado, Leave-One-Out, División de series temporales
from sklearn.model_selection import cross_val_score, KFold, StratifiedKFold
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris

data = load_iris()
X, y = data.data, data.target

model = LogisticRegression(max_iter=200)

# K-Fold estándar
kfold = KFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=kfold)
print(f"Puntuaciones de CV de K-Fold: {scores}")
print(f"Media: {scores.mean():.3f} (+/- {scores.std():.3f})")

# K-Fold estratificado (conserva la distribución de clases)
stratified_kfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
stratified_scores = cross_val_score(model, X, y, cv=stratified_kfold)
print(f"\nPuntuaciones de K-Fold estratificado: {stratified_scores}")
print(f"Media: {stratified_scores.mean():.3f} (+/- {stratified_scores.std():.3f})")

# Validación cruzada personalizada
from sklearn.model_selection import cross_validate

cv_results = cross_validate(
    model, X, y, cv=5,
    scoring=['accuracy', 'precision_macro', 'recall_macro'],
    return_train_score=True
)

print(f"\nPrecisión de la prueba: {cv_results['test_accuracy'].mean():.3f}")
print(f"Precisión de la prueba: {cv_results['test_precision_macro'].mean():.3f}")
print(f"Recuperación de la prueba: {cv_results['test_recall_macro'].mean():.3f}")

Rareza: Muy común Dificultad: Media


5. Explique las técnicas de reducción de la dimensionalidad (PCA, t-SNE).

Respuesta: La reducción de la dimensionalidad reduce el número de características preservando la información.

  • PCA (Análisis de componentes principales):
    • Transformación lineal
    • Encuentra direcciones de máxima varianza
    • Preserva la estructura global
    • Rápido, interpretable
  • t-SNE (t-Distributed Stochastic Neighbor Embedding):
    • Transformación no lineal
    • Preserva la estructura local
    • Bueno para la visualización
    • Más lento, no para la extracción de características
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt

# Cargar datos de alta dimensión
digits = load_digits()
X, y = digits.data, digits.target

print(f"Forma original: {X.shape}")

# PCA - reducir a 2 dimensiones
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
print(f"Forma de PCA: {X_pca.shape}")
print(f"Relación de varianza explicada: {pca.explained_variance_ratio_}")
print(f"Varianza total explicada: {pca.explained_variance_ratio_.sum():.3f}")

# t-SNE - reducir a 2 dimensiones
tsne = TSNE(n_components=2, random_state=42)
X_tsne = tsne.fit_transform(X)
print(f"Forma de t-SNE: {X_tsne.shape}")

# PCA para la extracción de características (mantener el 95% de la varianza)
pca_95 = PCA(n_components=0.95)
X_reduced = pca_95.fit_transform(X)
print(f"\nComponentes para el 95% de la varianza: {pca_95.n_components_}")
print(f"Forma reducida: {X_reduced.shape}")

Rareza: Común Dificultad: Difícil


6. ¿Qué es la curva ROC y el AUC? ¿Cuándo la usaría?

Respuesta: La curva ROC (Receiver Operating Characteristic) representa la tasa de verdaderos positivos frente a la tasa de falsos positivos en varios umbrales.

  • AUC (Área bajo la curva): Métrica única que resume la ROC
    • AUC = 1.0: Clasificador perfecto
    • AUC = 0.5: Clasificador aleatorio
    • AUC < 0.5: Peor que aleatorio
  • Casos de uso:
    • Comparación de modelos
    • Conjuntos de datos desequilibrados
    • Cuando necesita elegir el umbral
from sklearn.metrics import roc_curve, roc_auc_score, auc
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
import matplotlib.pyplot as plt

# Cargar datos
data = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
    data.data, data.target, test_size=0.3, random_state=42
)

# Entrenar modelo
model = LogisticRegression(max_iter=10000)
model.fit(X_train, y_train)

# Obtener predicciones de probabilidad
y_pred_proba = model.predict_proba(X_test)[:, 1]

# Calcular la curva ROC
fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba)
roc_auc = auc(fpr, tpr)

print(f"AUC: {roc_auc:.3f}")

# Alternativa: cálculo directo del AUC
auc_score = roc_auc_score(y_test, y_pred_proba)
print(f"AUC (directo): {auc_score:.3f}")

# Encontrar el umbral óptimo (estadístico J de Youden)
optimal_idx = np.argmax(tpr - fpr)
optimal_threshold = thresholds[optimal_idx]
print(f"Umbral óptimo: {optimal_threshold:.3f}")

Rareza: Muy común Dificultad: Media


Ingeniería de características (4 preguntas)

7. ¿Qué técnicas utiliza para la ingeniería de características?

Respuesta: La ingeniería de características crea nuevas características a partir de los datos existentes para mejorar el rendimiento del modelo.

  • Técnicas:
    • Codificación: Codificación one-hot, de etiqueta, de destino
    • Escalado: StandardScaler, MinMaxScaler
    • Agrupación: Discretizar variables continuas
    • Características polinómicas: Términos de interacción
    • Específico del dominio: Características de fecha, características de texto
    • Agregaciones: Estadísticas de grupo
from sklearn.preprocessing import StandardScaler, OneHotEncoder, PolynomialFeatures
import pandas as pd
import numpy as np

# Datos de muestra
df = pd.DataFrame({
    'age': [25, 30, 35, 40, 45],
    'salary': [50000, 60000, 75000, 80000, 90000],
    'department': ['IT', 'HR', 'IT', 'Finance', 'HR'],
    'date': pd.date_range('2023-01-01', periods=5)
})

# Codificación one-hot
df_encoded = pd.get_dummies(df, columns=['department'], prefix='dept')

# Escalado
scaler = StandardScaler()
df_encoded[['age_scaled', 'salary_scaled']] = scaler.fit_transform(
    df_encoded[['age', 'salary']]
)

# Agrupación
df_encoded['age_group'] = pd.cut(df['age'], bins=[0, 30, 40, 100], labels=['young', 'mid', 'senior'])

# Características de fecha
df_encoded['year'] = df['date'].dt.year
df_encoded['month'] = df['date'].dt.month
df_encoded['day_of_week'] = df['date'].dt.dayofweek

# Características polinómicas
poly = PolynomialFeatures(degree=2, include_bias=False)
poly_features = poly.fit_transform(df[['age', 'salary']])

# Características de interacción
df_encoded['age_salary_interaction'] = df['age'] * df['salary']

print(df_encoded.head())

Rareza: Muy común Dificultad: Media


8. ¿Cómo maneja los conjuntos de datos desequilibrados?

Respuesta: Los conjuntos de datos desequilibrados tienen distribuciones de clase desiguales, lo que puede sesgar los modelos.

  • Técnicas:
    • Remuestreo:
      • Sobre muestreo de la clase minoritaria (SMOTE)
      • Submuestreo de la clase mayoritaria
    • Ponderaciones de clase: Penalizar la clasificación errónea de la clase minoritaria
    • Métodos de conjunto: Bosque aleatorio equilibrado
    • Evaluación: Utilice precisión, recuperación, F1, no solo precisión
    • Detección de anomalías: Tratar la minoría como una anomalía
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler

# Crear un conjunto de datos desequilibrado
X, y = make_classification(
    n_samples=1000, n_features=20, n_informative=15,
    n_classes=2, weights=[0.9, 0.1], random_state=42
)

print(f"Distribución de clases: {np.bincount(y)}")

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 1. Sin manejar el desequilibrio
model_baseline = LogisticRegression()
model_baseline.fit(X_train, y_train)
y_pred_baseline = model_baseline.predict(X_test)
print("\nLínea de base (sin manejo):")
print(classification_report(y_test, y_pred_baseline))

# 2. SMOTE (sobremuestreo sintético de minorías)
smote = SMOTE(random_state=42)
X_train_smote, y_train_smote = smote.fit_resample(X_train, y_train)
print(f"\nDespués de SMOTE: {np.bincount(y_train_smote)}")

model_smote = LogisticRegression()
model_smote.fit(X_train_smote, y_train_smote)
y_pred_smote = model_smote.predict(X_test)
print("\nCon SMOTE:")
print(classification_report(y_test, y_pred_smote))

# 3. Ponderaciones de clase
model_weighted = LogisticRegression(class_weight='balanced')
model_weighted.fit(X_train, y_train)
y_pred_weighted = model_weighted.predict(X_test)
print("\nCon ponderaciones de clase:")
print(classification_report(y_test, y_pred_weighted))

Rareza: Muy común Dificultad: Media


9. Explique las técnicas de selección de características.

Respuesta: La selección de características identifica las características más relevantes para el modelado.

  • Métodos:
    • Métodos de filtro: Pruebas estadísticas (correlación, chi-cuadrado)
    • Métodos de envoltura: Eliminación recursiva de características (RFE)
    • Métodos integrados: Lazo, importancia de características basada en árboles
    • Reducción de la dimensionalidad: PCA (diferente de la selección)
from sklearn.feature_selection import SelectKBest, chi2, RFE, SelectFromModel
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import MinMaxScaler

# Cargar datos
data = load_breast_cancer()
X, y = data.data, data.target

# 1. Método de filtro - SelectKBest con chi-cuadrado
X_scaled = MinMaxScaler().fit_transform(X)
selector_chi2 = SelectKBest(chi2, k=10)
X_chi2 = selector_chi2.fit_transform(X_scaled, y)
print(f"Características originales: {X.shape[1]}")
print(f"Características seleccionadas (chi2): {X_chi2.shape[1]}")

# 2. Método de envoltura - Eliminación recursiva de características
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rfe = RFE(estimator=rf, n_features_to_select=10)
X_rfe = rfe.fit_transform(X, y)
print(f"Características seleccionadas (RFE): {X_rfe.shape[1]}")
print(f"Clasificación de características: {rfe.ranking_}")

# 3. Método integrado - Importancia de características basada en árboles
rf.fit(X, y)
importances = rf.feature_importances_
indices = np.argsort(importances)[::-1]

print("\nLas 10 características principales por importancia:")
for i in range(10):
    print(f"{i+1}. {data.feature_names[indices[i]]}: {importances[indices[i]]:.4f}")

# SelectFromModel
selector_model = SelectFromModel(rf, threshold='median', prefit=True)
X_selected = selector_model.transform(X)
print(f"\nCaracterísticas seleccionadas (importancia): {X_selected.shape[1]}")

Rareza: Común Dificultad: Media


10. ¿Cómo maneja las variables categóricas con alta cardinalidad?

Respuesta: Las variables categóricas de alta cardinalidad tienen muchos valores únicos.

  • Técnicas:
    • Codificación de destino: Reemplazar con la media de destino
    • Codificación de frecuencia: Reemplazar con la frecuencia
    • Incrustación: Aprender representaciones densas (redes neuronales)
    • Agrupación: Combinar categorías raras en "Otro"
    • Hashing: Hash a un número fijo de depósitos
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

# Datos de muestra con alta cardinalidad
df = pd.DataFrame({
    'city': np.random.choice([f'City_{i}' for i in range(100)], 1000),
    'target': np.random.randint(0, 2, 1000)
})

print(f"Ciudades únicas: {df['city'].nunique()}")

# 1. Codificación de destino
target_means = df.groupby('city')['target'].mean()
df['city_target_encoded'] = df['city'].map(target_means)

# 2. Codificación de frecuencia
freq = df['city'].value_counts()
df['city_frequency'] = df['city'].map(freq)

# 3. Agrupar categorías raras
freq_threshold = 10
rare_cities = freq[freq < freq_threshold].index
df['city_grouped'] = df['city'].apply(lambda x: 'Other' if x in rare_cities else x)

print(f"\nDespués de la agrupación: {df['city_grouped'].nunique()} valores únicos")

# 4. Codificación hash (usando la librería category_encoders)
# from category_encoders import HashingEncoder
# encoder = HashingEncoder(cols=['city'], n_components=10)
# df_hashed = encoder.fit_transform(df)

print(df[['city', 'city_target_encoded', 'city_frequency', 'city_grouped']].head())

Rareza: Común Dificultad: Difícil


Implementación y producción de modelos (4 preguntas)

11. ¿Cómo implementa un modelo de aprendizaje automático en producción?

Respuesta: La implementación de modelos hace que los modelos estén disponibles para su uso en el mundo real.

  • Pasos:
    1. Serialización del modelo: Guardar el modelo (pickle, joblib, ONNX)
    2. Desarrollo de API: Crear API REST (Flask, FastAPI)
    3. Contenedorización: Docker para la consistencia
    4. Implementación: Plataformas en la nube (AWS, GCP, Azure)
    5. Monitoreo: Seguimiento del rendimiento, deriva
    6. CI/CD: Pruebas e implementación automatizadas
# 1. Entrenar y guardar el modelo
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
import joblib

# Entrenar modelo
data = load_iris()
model = RandomForestClassifier()
model.fit(data.data, data.target)

# Guardar modelo
joblib.dump(model, 'model.joblib')

# 2. Crear API con FastAPI
from fastapi import FastAPI
import numpy as np

app = FastAPI()

# Cargar modelo
model = joblib.load('model.joblib')

@app.post("/predict")
def predict(features: list):
    # Convertir a matriz numpy
    X = np.array(features).reshape(1, -1)
    prediction = model.predict(X)
    probability = model.predict_proba(X)
    
    return {
        "prediction": int(prediction[0]),
        "probability": probability[0].tolist()
    }

# 3. Dockerfile
"""
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
"""

# 4. Uso
# curl -X POST "http://localhost:8000/predict" \
#      -H "Content-Type: application/json" \
#      -d '{"features": [5.1, 3.5, 1.4, 0.2]}'

Rareza: Muy común Dificultad: Difícil


12. ¿Qué es el monitoreo de modelos y por qué es importante?

Respuesta: El monitoreo de modelos rastrea el rendimiento del modelo en producción.

  • Qué monitorear:
    • Métricas de rendimiento: Precisión, precisión, recuperación
    • Deriva de datos: Cambios en la distribución de entrada
    • Deriva de conceptos: Cambios en la relación de destino
    • Métricas del sistema: Latencia, rendimiento, errores
  • Acciones:
    • Alertas cuando el rendimiento se degrada
    • Volver a entrenar con nuevos datos
    • Pruebas A/B de nuevos modelos
import numpy as np
from scipy import stats

# Simular datos de producción
training_data = np.random.normal(0, 1, 1000)
production_data = np.random.normal(0.5, 1.2, 1000)  # Derivado

# Detectar la deriva de datos utilizando la prueba de Kolmogorov-Smirnov
statistic, p_value = stats.ks_2samp(training_data, production_data)

print(f"Estadístico KS: {statistic:.4f}")
print(f"Valor P: {p_value:.4f}")

if p_value < 0.05:
    print("¡Deriva de datos detectada! Considere volver a entrenar el modelo.")
else:
    print("No se detectó ninguna deriva significativa.")

# Monitorear el rendimiento del modelo
class ModelMonitor:
    def __init__(self, model):
        self.model = model
        self.predictions = []
        self.actuals = []
        
    def log_prediction(self, X, y_pred, y_true=None):
        self.predictions.append(y_pred)
        if y_true is not None:
            self.actuals.append(y_true)
    
    def get_accuracy(self):
        if len(self.actuals) == 0:
            return None
        return np.mean(np.array(self.predictions) == np.array(self.actuals))
    
    def check_drift(self, new_data, reference_data):
        statistic, p_value = stats.ks_2samp(new_data, reference_data)
        return p_value < 0.05

# Uso
monitor = ModelMonitor(model)
# monitor.log_prediction(X, y_pred, y_true)
# accuracy = monitor.get_accuracy()

Rareza: Común Dificultad: Media


13. Explique las pruebas A/B en el contexto del aprendizaje automático.

Respuesta: Las pruebas A/B comparan dos versiones (control vs tratamiento) para determinar cuál funciona mejor.

  • Proceso:
    1. Dividir el tráfico aleatoriamente
    2. Servir diferentes modelos a cada grupo
    3. Recopilar métricas
    4. Prueba estadística para determinar el ganador
  • Métricas: Tasa de conversión, ingresos, participación
  • Pruebas estadísticas: Prueba t, chi-cuadrado, métodos bayesianos
import numpy as np
from scipy import stats

# Simular los resultados de las pruebas A/B
# Grupo de control (Modelo A)
control_conversions = 520
control_visitors = 10000

# Grupo de tratamiento (Modelo B)
treatment_conversions = 580
treatment_visitors = 10000

# Calcular las tasas de conversión
control_rate = control_conversions / control_visitors
treatment_rate = treatment_conversions / treatment_visitors

print(f"Tasa de conversión de control: {control_rate:.4f}")
print(f"Tasa de conversión de tratamiento: {treatment_rate:.4f}")
print(f"Elevación: {((treatment_rate - control_rate) / control_rate * 100):.2f}%")

# Prueba de significación estadística (prueba z de dos proporciones)
pooled_rate = (control_conversions + treatment_conversions) / (control_visitors + treatment_visitors)
se = np.sqrt(pooled_rate * (1 - pooled_rate) * (1/control_visitors + 1/treatment_visitors))
z_score = (treatment_rate - control_rate) / se
p_value = 2 * (1 - stats.norm.cdf(abs(z_score)))

print(f"\nPuntuación Z: {z_score:.4f}")
print(f"Valor P: {p_value:.4f}")

if p_value < 0.05:
    print("¡El resultado es estadísticamente significativo!")
    if treatment_rate > control_rate:
        print("El tratamiento (Modelo B) es mejor.")
    else:
        print("El control (Modelo A) es mejor.")
else:
    print("No hay diferencia estadísticamente significativa.")

# Cálculo del tamaño de la muestra
from statsmodels.stats.power import zt_ind_solve_power

required_sample = zt_ind_solve_power(
    effect_size=0.02,  # Efecto mínimo detectable
    alpha=0.05,
    power=0.8,
    alternative='two-sided'
)
print(f"\nTamaño de muestra requerido por grupo: {int(required_sample)}")

Rareza: Común Dificultad: Difícil


14. ¿Qué es MLOps y por qué es importante?

Respuesta: MLOps (Machine Learning Operations) aplica los principios de DevOps a los sistemas de ML.

  • Componentes:
    • Control de versiones: Código, datos, modelos
    • Pruebas automatizadas: Pruebas unitarias, de integración, de modelos
    • Canalizaciones de CI/CD: Implementación automatizada
    • Monitoreo: Rendimiento, detección de deriva
    • Reproducibilidad: Seguimiento de experimentos
  • Herramientas: MLflow, Kubeflow, DVC, Weights & Biases
# Ejemplo: MLflow para el seguimiento de experimentos
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# Cargar datos
data = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
    data.data, data.target, test_size=0.3, random_state=42
)

# Iniciar la ejecución de MLflow
with mlflow.start_run():
    # Registrar parámetros
    n_estimators = 100
    max_depth = 5
    mlflow.log_param("n_estimators", n_estimators)
    mlflow.log_param("max_depth", max_depth)
    
    # Entrenar modelo
    model = RandomForestClassifier(
        n_estimators=n_estimators,
        max_depth=max_depth,
        random_state=42
    )
    model.fit(X_train, y_train)
    
    # Evaluar
    y_pred = model.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    
    # Registrar métricas
    mlflow.log_metric("accuracy", accuracy)
    
    # Registrar modelo
    mlflow.sklearn.log_model(model,
Newsletter subscription

Consejos de carrera semanales que realmente funcionan

Recibe las últimas ideas directamente en tu bandeja de entrada

Tu Próxima Entrevista Está a Solo un Currículum de Distancia

Crea un currículum profesional y optimizado en minutos. No se necesitan habilidades de diseño, solo resultados comprobados.

Crea mi currículum

Compartir esta publicación

Haz que tus 6 Segundos Cuenten

Los reclutadores escanean currículums durante un promedio de solo 6 a 7 segundos. Nuestras plantillas probadas están diseñadas para captar la atención al instante y mantenerlos leyendo.