Compartir vía


Tutorial: Análisis de opiniones de comentarios de sitios web con clasificación binaria en ML.NET

En este tutorial se muestra cómo crear una aplicación de consola de .NET que clasifica las opiniones de los comentarios del sitio web y realiza la acción adecuada. El clasificador de sentimiento binario usa C# en Visual Studio 2022.

En este tutorial, aprenderá a:

  • Creación de una aplicación de consola
  • Preparación de datos
  • Carga de los datos
  • Compilación y entrenamiento del modelo
  • Evaluación del modelo
  • Uso del modelo para realizar una predicción
  • Ver los resultados

Puede encontrar el código fuente de este tutorial en el repositorio dotnet/samples .

Prerrequisitos

Creación de una aplicación de consola

  1. Cree una aplicación de consola de C# denominada "SentimentAnalysis". Haga clic en el botón Siguiente .

  2. Elija .NET 8 como marco de trabajo que se va a usar. Haga clic en el botón Crear.

  3. Cree un directorio denominado Data en el proyecto para guardar los archivos del conjunto de datos.

  4. Instale el paquete NuGet de Microsoft.ML:

    Nota:

    En este ejemplo se usa la versión estable más reciente de los paquetes NuGet mencionados a menos que se indique lo contrario.

    En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Administrar paquetes NuGet. Elija "nuget.org" como origen del paquete y, a continuación, seleccione la pestaña Examinar . Busque Microsoft.ML, seleccione el paquete que desee y, a continuación, seleccione Instalar. Continúe con la instalación aceptando los términos de licencia del paquete que elija.

Preparar los datos

Nota:

Los conjuntos de datos de este tutorial proceden de "De grupo a etiquetas individuales mediante características profundas", Kotzias et. al,. KDD 2015 y hospedado en el Repositorio de Machine Learning de UCI: Dua, D. y Karra Taniskidou, E. (2017). Repositorio de Machine Learning de UCI [http://archive.ics.uci.edu/ml]. Irvine, CA: Universidad de California, Facultad de Ciencias de la Computación y de la Información

  1. Descargue el archivo ZIP del conjunto de datos UCI Sentiment Labeled Sentences y descomprima.

  2. Copie el yelp_labelled.txt archivo en el directorio Data que creó.

  3. En el Explorador de soluciones, haga clic con el botón derecho en el yelp_labelled.txt archivo y seleccione Propiedades. En Avanzado, cambie el valor de Copiar al directorio de salida a Copiar si es más reciente.

Creación de clases y definición de rutas de acceso

  1. Agregue las siguientes directivas adicionales using a la parte superior del archivo Program.cs :

    using Microsoft.ML;
    using Microsoft.ML.Data;
    using SentimentAnalysis;
    using static Microsoft.ML.DataOperationsCatalog;
    
  2. Agregue el código siguiente a la línea situada debajo de las using directivas para crear un campo que contenga la ruta de acceso del archivo del conjunto de datos descargado recientemente:

    string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "yelp_labelled.txt");
    
  3. A continuación, cree clases para los datos de entrada y las predicciones. Agregue una nueva clase al proyecto:

    • En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Agregar>nuevo elemento.

    • En el cuadro de diálogo Agregar nuevo elemento , seleccione Clase y cambie el campo Nombre a SentimentData.cs. A continuación, seleccione Agregar.

  4. El archivo SentimentData.cs se abre en el editor de código. Agregue la siguiente using directiva a la parte superior de SentimentData.cs:

    using Microsoft.ML.Data;
    
  5. Quite la definición de clase existente y agregue el código siguiente, que tiene dos clases SentimentData y SentimentPrediction, al archivo SentimentData.cs :

    public class SentimentData
    {
        [LoadColumn(0)]
        public string? SentimentText;
    
        [LoadColumn(1), ColumnName("Label")]
        public bool Sentiment;
    }
    
    public class SentimentPrediction : SentimentData
    {
    
        [ColumnName("PredictedLabel")]
        public bool Prediction { get; set; }
    
        public float Probability { get; set; }
    
        public float Score { get; set; }
    }
    

Cómo se prepararon los datos

La clase de conjunto de datos de entrada, SentimentData, tiene un string valor para los comentarios del usuario () y un SentimentText valor (boolSentiment) de 1 (positivo) o 0 (negativo) para la opinión. Ambos campos tienen atributos LoadColumn adjuntos, que describen el orden del archivo de datos de cada campo. Además, la Sentiment propiedad tiene un atributo ColumnName para designarlo como campo Label . El siguiente archivo de ejemplo no tiene una fila de encabezado y tiene este aspecto:

SentimentText Sentimiento (etiqueta)
Las camareras eran un poco lentas en el servicio. 0
La corteza no es buena. 0
Uau... Amaba este lugar. 1
El servicio era muy rápido. 1

SentimentPrediction es la clase de predicción que se usa después del entrenamiento del modelo. Hereda de SentimentData para que la entrada SentimentText se pueda mostrar junto con la predicción de salida. El Prediction valor booleano es el que predice el modelo cuando se proporciona con la nueva entrada SentimentText.

La clase SentimentPrediction de salida contiene otras dos propiedades calculadas por el modelo: - Score la puntuación sin procesar calculada por el modelo y Probability - la puntuación calibrada para la probabilidad de que el texto tenga una opinión positiva.

Para este tutorial, la propiedad más importante es Prediction.

Carga de los datos

Los datos de ML.NET se representan como una interfaz IDataView. IDataView es una manera flexible y eficaz de describir datos tabulares (numéricos y texto). Los datos se pueden cargar desde un archivo de texto o en tiempo real (por ejemplo, archivos de base de datos SQL o de registro) en un IDataView objeto .

La clase MLContext es un punto de partida para todas las operaciones de ML.NET. Inicializar mlContext crea un nuevo entorno de ML.NET que se puede compartir entre los objetos de flujo de trabajo de creación de modelos. Es similar, conceptualmente, a DBContext en Entity Framework.

Prepare la aplicación y, a continuación, cargue los datos:

  1. Reemplace la Console.WriteLine("Hello World!") línea por el código siguiente para declarar e inicializar la variable mlContext:

    MLContext mlContext = new MLContext();
    
  2. Agregue lo siguiente como la siguiente línea de código:

    TrainTestData splitDataView = LoadData(mlContext);
    
  3. Cree un LoadData() método en la parte inferior del Program.cs archivo con el código siguiente:

    TrainTestData LoadData(MLContext mlContext)
    {
    
    }
    

    El LoadData() método ejecuta las siguientes tareas:

    • Carga los datos.
    • Divide el conjunto de datos cargado en conjuntos de datos de entrenamiento y prueba.
    • Devuelve los conjuntos de datos de entrenamiento y prueba divididos.
  4. Agregue el código siguiente como primera línea del LoadData() método :

    IDataView dataView = mlContext.Data.LoadFromTextFile<SentimentData>(_dataPath, hasHeader: false);
    

    El método LoadFromTextFile() define el esquema de datos y lee en el archivo. Toma las variables de ruta de acceso de datos y devuelve un IDataView.

Dividir el conjunto de datos para el entrenamiento y las pruebas del modelo

Al preparar un modelo, se usa parte del conjunto de datos para entrenarlo y parte del conjunto de datos para probar la precisión del modelo.

  1. Para dividir los datos cargados en los conjuntos de datos necesarios, agregue el código siguiente como la línea siguiente en el LoadData() método :

    TrainTestData splitDataView = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2);
    

    El código anterior usa el método TrainTestSplit() para dividir el conjunto de datos cargado en conjuntos de datos de entrenamiento y prueba y devolverlos en la DataOperationsCatalog.TrainTestData clase . Especifique el porcentaje de datos del conjunto de pruebas con el testFractionparámetro . El valor predeterminado es 10%, en este caso se usan 20% para evaluar más datos.

  2. Devuelve al splitDataView final del LoadData() método :

    return splitDataView;
    

Compilación y entrenamiento del modelo

  1. Agregue la siguiente llamada al BuildAndTrainModelmétodo debajo de la llamada al LoadData método :

    ITransformer model = BuildAndTrainModel(mlContext, splitDataView.TrainSet);
    

    El BuildAndTrainModel() método ejecuta las siguientes tareas:

    • Extrae y transforma los datos.
    • Entrena el modelo.
    • Predice opiniones basadas en los datos de prueba.
    • Devuelve el modelo.
  2. Cree el BuildAndTrainModel() método , debajo del LoadData() método , con el código siguiente:

    ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet)
    {
    
    }
    

Extracción y transformación de los datos

  1. Llame FeaturizeText a como la siguiente línea de código:

    var estimator = mlContext.Transforms.Text.FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(SentimentData.SentimentText))
    

    El FeaturizeText() método del código anterior convierte la columna de texto (SentimentText) en una columna de tipo Features de clave numérica usada por el algoritmo de aprendizaje automático y la agrega como una nueva columna de conjunto de datos:

    SentimentText Sentimiento Características
    Las camareras eran un poco lentas en el servicio. 0 [0.76, 0.65, 0.44, …]
    La corteza no es buena. 0 [0.98, 0.43, 0.54, …]
    Uau... Amaba este lugar. 1 [0.35, 0.73, 0.46, …]
    El servicio era muy rápido. 1 [0.39, 0, 0.75, …]

Adición de un algoritmo de aprendizaje

Esta aplicación usa un algoritmo de clasificación que clasifica elementos o filas de datos. La aplicación clasifica los comentarios del sitio web como positivos o negativos, por lo que usa la tarea de clasificación binaria.

Anexe la tarea de aprendizaje automático a las definiciones de transformación de datos agregando lo siguiente como la siguiente línea de código en BuildAndTrainModel():

.Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: "Label", featureColumnName: "Features"));

SdcaLogisticRegressionBinaryTrainer es el algoritmo de entrenamiento de clasificación. Esto se anexa a estimator y acepta las características SentimentText (Features) y los Label parámetros de entrada para aprender de los datos históricos.

Entrenamiento del modelo

Ajuste el modelo a los splitTrainSet datos y devuelva el modelo entrenado agregando lo siguiente como la siguiente línea de código en el BuildAndTrainModel() método :

Console.WriteLine("=============== Create and Train the Model ===============");
var model = estimator.Fit(splitTrainSet);
Console.WriteLine("=============== End of training ===============");
Console.WriteLine();

El método Fit() entrena el modelo mediante la transformación del conjunto de datos y la aplicación del entrenamiento.

Devolver el modelo entrenado para utilizarse en la evaluación

Devuelve el modelo al final del BuildAndTrainModel() método :

return model;

Evaluación del modelo

Una vez entrenado el modelo, use los datos de prueba para validar el rendimiento del modelo.

  1. Cree el Evaluate() método , justo después BuildAndTrainModel()de , con el código siguiente:

    void Evaluate(MLContext mlContext, ITransformer model, IDataView splitTestSet)
    {
    
    }
    

    El Evaluate() método ejecuta las siguientes tareas:

    • Carga el conjunto de datos de prueba.
    • Crea el evaluador BinaryClassification.
    • Evalúa el modelo y crea métricas.
    • Muestra las métricas.
  2. Agregue una llamada al nuevo método debajo de la BuildAndTrainModel llamada al método mediante el código siguiente:

    Evaluate(mlContext, model, splitDataView.TestSet);
    
  3. Transforme los splitTestSet datos agregando el código siguiente a Evaluate():

    Console.WriteLine("=============== Evaluating Model accuracy with Test data===============");
    IDataView predictions = model.Transform(splitTestSet);
    

    El código anterior usa el método Transform() para realizar predicciones para varias filas de entrada proporcionadas de un conjunto de datos de prueba.

  4. Evalúe el modelo agregando lo siguiente como la siguiente línea de código en el Evaluate() método :

    CalibratedBinaryClassificationMetrics metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label");
    

Una vez que tenga el conjunto de predicciones (predictions), el método Evaluate() evalúa el modelo, que compara los valores previstos con el real Labels en el conjunto de datos de prueba y devuelve un objeto CalibratedBinaryClassificationMetrics sobre cómo funciona el modelo.

Visualización de las métricas para la validación del modelo

Use el código siguiente para mostrar las métricas:

Console.WriteLine();
Console.WriteLine("Model quality metrics evaluation");
Console.WriteLine("--------------------------------");
Console.WriteLine($"Accuracy: {metrics.Accuracy:P2}");
Console.WriteLine($"Auc: {metrics.AreaUnderRocCurve:P2}");
Console.WriteLine($"F1Score: {metrics.F1Score:P2}");
Console.WriteLine("=============== End of model evaluation ===============");
  • La Accuracy métrica obtiene la precisión de un modelo, que es la proporción de predicciones correctas en el conjunto de pruebas.

  • La AreaUnderRocCurve métrica indica la confianza que el modelo está clasificando correctamente las clases positivas y negativas. Quiere AreaUnderRocCurve que esté lo más cerca posible de uno.

  • La F1Score métrica obtiene la puntuación F1 del modelo, que es una medida de equilibrio entre precisión y recuperación. Quiere F1Score que esté lo más cerca posible de uno.

Predicción del resultado de los datos de prueba

  1. Cree el UseModelWithSingleItem() método , justo después del Evaluate() método , con el código siguiente:

    void UseModelWithSingleItem(MLContext mlContext, ITransformer model)
    {
    
    }
    

    El UseModelWithSingleItem() método ejecuta las siguientes tareas:

    • Crea un único comentario de los datos de prueba.
    • Predice opiniones basadas en los datos de prueba.
    • Combina datos de prueba y predicciones para los informes.
    • Muestra los resultados previstos.
  2. Agregue una llamada al nuevo método justo debajo de la Evaluate() llamada al método mediante el código siguiente:

    UseModelWithSingleItem(mlContext, model);
    
  3. Agregue el código siguiente para crear como primera línea en el UseModelWithSingleItem() método :

    PredictionEngine<SentimentData, SentimentPrediction> predictionFunction = mlContext.Model.CreatePredictionEngine<SentimentData, SentimentPrediction>(model);
    

    PredictionEngine es una API útil, que permite realizar una predicción en una sola instancia de datos. PredictionEngine no es seguro para subprocesos. Es aceptable usarlo en entornos de un solo hilo o en prototipos. Para mejorar el rendimiento y la seguridad de los subprocesos en entornos de producción, use el servicio PredictionEnginePool, que crea una ObjectPool de objetos PredictionEngine para el uso en toda su aplicación. Consulte esta guía sobre cómo usar PredictionEnginePool en una API web de ASP.NET Core.

    Nota:

    PredictionEnginePool la extensión de servicio está actualmente en versión preliminar.

  4. Agregue un comentario para probar la predicción del modelo entrenado en el UseModelWithSingleItem() método mediante la creación de una instancia de SentimentData:

    SentimentData sampleStatement = new SentimentData
    {
        SentimentText = "This was a very bad steak"
    };
    
  5. Pase los datos del comentario de prueba al PredictionEngine añadiendo lo siguiente como líneas de código siguientes en el método UseModelWithSingleItem():

    var resultPrediction = predictionFunction.Predict(sampleStatement);
    

    La función Predict() realiza una predicción en una sola fila de datos.

  6. Muestra SentimentText y la predicción de opiniones correspondiente con el código siguiente:

    Console.WriteLine();
    Console.WriteLine("=============== Prediction Test of model with a single sample and test dataset ===============");
    
    Console.WriteLine();
    Console.WriteLine($"Sentiment: {resultPrediction.SentimentText} | Prediction: {(Convert.ToBoolean(resultPrediction.Prediction) ? "Positive" : "Negative")} | Probability: {resultPrediction.Probability} ");
    
    Console.WriteLine("=============== End of Predictions ===============");
    Console.WriteLine();
    

Uso del modelo para la predicción

Implementación y predicción de elementos por lotes

  1. Cree el UseModelWithBatchItems() método , justo después del UseModelWithSingleItem() método , con el código siguiente:

    void UseModelWithBatchItems(MLContext mlContext, ITransformer model)
    {
    
    }
    

    El UseModelWithBatchItems() método ejecuta las siguientes tareas:

    • Crea datos de prueba por lotes.
    • Predice opiniones basadas en los datos de prueba.
    • Combina datos de prueba y predicciones para los informes.
    • Muestra los resultados previstos.
  2. Agregue una llamada al nuevo método justo debajo de la UseModelWithSingleItem() llamada al método mediante el código siguiente:

    UseModelWithBatchItems(mlContext, model);
    
  3. Agregue algunos comentarios para probar las predicciones del modelo entrenado en el UseModelWithBatchItems() método :

    IEnumerable<SentimentData> sentiments = new[]
    {
        new SentimentData
        {
            SentimentText = "This was a horrible meal"
        },
        new SentimentData
        {
            SentimentText = "I love this spaghetti."
        }
    };
    

Predicción de opiniones de comentarios

Use el modelo para predecir la opinión de datos de comentarios mediante el método Transform():

IDataView batchComments = mlContext.Data.LoadFromEnumerable(sentiments);

IDataView predictions = model.Transform(batchComments);

// Use model to predict whether comment data is Positive (1) or Negative (0).
IEnumerable<SentimentPrediction> predictedResults = mlContext.Data.CreateEnumerable<SentimentPrediction>(predictions, reuseRowObject: false);

Combinar y mostrar las predicciones

Cree un encabezado para las predicciones mediante el código siguiente:

Console.WriteLine();

Console.WriteLine("=============== Prediction Test of loaded model with multiple samples ===============");

Dado que SentimentPrediction se hereda de SentimentData, el Transform() método se SentimentText rellena con los campos previstos. A medida que el proceso de ML.NET procesa, cada componente agrega columnas y esto facilita la visualización de los resultados:

foreach (SentimentPrediction prediction  in predictedResults)
{
    Console.WriteLine($"Sentiment: {prediction.SentimentText} | Prediction: {(Convert.ToBoolean(prediction.Prediction) ? "Positive" : "Negative")} | Probability: {prediction.Probability} ");
}
Console.WriteLine("=============== End of predictions ===============");

Results

Los resultados deben ser similares a los siguientes. Durante el procesamiento, se muestran los mensajes. Es posible que vea advertencias o mensajes de procesamiento. Estos se han quitado de los siguientes resultados para mayor claridad.

Model quality metrics evaluation
--------------------------------
Accuracy: 83.96%
Auc: 90.51%
F1Score: 84.04%

=============== End of model evaluation ===============

=============== Prediction Test of model with a single sample and test dataset ===============

Sentiment: This was a very bad steak | Prediction: Negative | Probability: 0.1027377
=============== End of Predictions ===============

=============== Prediction Test of loaded model with a multiple samples ===============

Sentiment: This was a horrible meal | Prediction: Negative | Probability: 0.1369192
Sentiment: I love this spaghetti. | Prediction: Positive | Probability: 0.9960636
=============== End of predictions ===============

=============== End of process ===============
Press any key to continue . . .

¡Felicidades! Ahora ha creado exitosamente un modelo de aprendizaje automático para clasificar y predecir el sentimiento de los mensajes.

La creación de modelos correctos es un proceso iterativo. Este modelo tiene una calidad inferior inicial, ya que el tutorial usa conjuntos de datos pequeños para proporcionar entrenamiento rápido del modelo. Si no está satisfecho con la calidad del modelo, puede intentar mejorarlo proporcionando conjuntos de datos de entrenamiento más grandes o eligiendo algoritmos de entrenamiento diferentes con distintos hiperparámetres para cada algoritmo.

Puede encontrar el código fuente de este tutorial en el repositorio dotnet/samples .

Pasos siguientes

En este tutorial, ha aprendido a:

  • Creación de una aplicación de consola
  • Preparación de datos
  • Carga de los datos
  • Compilación y entrenamiento del modelo
  • Evaluación del modelo
  • Uso del modelo para realizar una predicción
  • Ver los resultados

Avance al siguiente tutorial para obtener más información