¿Cómo entrenar un clasificador de bosque aleatorio con un gran conjunto de datos para evitar errores de memoria en Python?

Resuelto youtube asked hace 10 meses • 0 respuestas

Tengo un conjunto de datos de 30 millones de filas. Tengo dos columnas: una que contiene una etiqueta 1 o 0 y la otra columna tiene una lista de 1280 funciones para cada fila (181 GB en total). Todo lo que quiero hacer es conectar este conjunto de datos a un algoritmo de bosque aleatorio, pero la memoria se agota y falla (he intentado usar una memoria de 400 GB, pero aún falla).

Después de cargar el conjunto de datos, tuve que manipularlo un poco ya que está en el formato de flecha de Huggingface: https://huggingface.co/docs/datasets/en/about_arrow (sospecho que esto está consumiendo mucha RAM).

Soy consciente de que podría reducir un poco la dimensionalidad de mi conjunto de datos, pero ¿debo realizar algún cambio en mi código para reducir el uso de RAM?

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, roc_auc_score, roc_curve, auc
from datasets import load_dataset, Dataset

# Load dataset
df = Dataset.from_file("data.arrow")
df = pd.DataFrame(df)
X = df['embeddings'].to_numpy() # Convert Series to NumPy array
X = np.array(X.tolist()) # Convert list of arrays to a 2D NumPy array
X = X.reshape(X.shape[0], -1) # Flatten the 3D array into a 2D array
y = df['labels']

# Split the data into training and testing sets (80% train, 20% test)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Initialize the random forest classifier
rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)

# Train the classifier
rf_classifier.fit(X_train, y_train)

# Make predictions on the test set
y_pred = rf_classifier.predict(X_test)

# Evaluate the classifier

# Calculate accuracy
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

# Calculate AUC score
auc_score = roc_auc_score(y_test, y_pred)
print("AUC Score:", auc_score)

with open("metrics.txt", "w") as f:
    f.write("Accuracy: " + str(accuracy) + "\n")
    f.write("AUC Score: " + str(auc_score))
    
# Make predictions on the test set
y_pred_proba = rf_classifier.predict_proba(X_test)[:, 1]

# Calculate ROC curve
fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba)

# Plot ROC curve
plt.figure()
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)' % auc(fpr, tpr))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic (ROC) Curve')
plt.legend(loc="lower right")

# Save ROC curve plot to an image file
plt.savefig('roc_curve.png')

# Close plot to free memory
youtube avatar Feb 15 '24 23:02 youtube
Aceptado

Algunas ideas:

conjunto de modelos

Entrene N modelos (debe elegir N, dependiendo del uso de RAM), cada uno en solo una parte separada de los datos del tren.

Luego haga una fusión de modelos, use predict_proba(x)el método para cada modelo para hacer una inferencia y calcular predicciones promedio.

Esto puede tener mejor/peor/misma precisión que el modelo único; si N no es muy grande, no debería tener un gran impacto.

Tenedor de scikit aprender

Fork scikit aprende y sustituye cada bucle sobre xlos datos del tren de entrada con un bucle personalizado que carga los datos desde el disco en lugar de la RAM.

Este es un enfoque largo o difícil, y no estoy seguro de qué problemas enfrentará en el camino. En términos de dificultad, lo peor sería simplemente escribir RF desde cero.

Otras ideas

  • El uso de RAM se puede reducir disminuyendo max_ Depth, n_estimators, max_features, etc. Tenga en cuenta que estos afectarán la precisión de su modelo (¡tal vez de manera positiva! Pero para saber esto tendría que comparar resultados...)
  • ¿Convertir datos a float32 ( data.astype(np.float32)), o tal vez incluso a int16 si se escalan y transforman correctamente?
  • eliminar duplicados o cerrar duplicados. Es poco probable con tantas funciones, pero tal vez le resulte útil. Si hay muestras que están muy cerca entre sí (la métrica de distancia la dejo a usted), calcule la media de esas muestras y reemplácelas con esta media. También da esta muestra.sample_weight = number_of_averaged_samples
  • elimine características de baja importancia : entrene un modelo en una parte aleatoria del conjunto de datos y observe el modelo feature_importances. Luego, ignórelos mientras carga el conjunto de datos la próxima vez.
dankal444 avatar Feb 15 '2024 22:02 dankal444