Comparteix a través de


Carga de datos de archivos y otros orígenes

Obtenga información sobre cómo cargar datos en ML.NET para el procesamiento y el entrenamiento mediante la API. Los datos originalmente se almacenan en archivos u otros orígenes de datos, como colecciones en memoria, JSON, XML o bases de datos.

Si utiliza el generador de modelos, vea Carga de datos de entrenamiento en el Generador de modelos.

Crear el modelo de datos

ML.NET permite definir los modelos de datos mediante clases. Por ejemplo, dado los siguientes datos de entrada:

Size (Sq. ft.), HistoricalPrice1 ($), HistoricalPrice2 ($), HistoricalPrice3 ($), Current Price ($)
700, 100000, 3000000, 250000, 500000
1000, 600000, 400000, 650000, 700000

Cree un modelo de datos que represente el siguiente fragmento de código:

public class HousingData
{
    [LoadColumn(0)]
    public float Size { get; set; }

    [LoadColumn(1, 3)]
    [VectorType(3)]
    public float[] HistoricalPrices { get; set; }

    [LoadColumn(4)]
    [ColumnName("Label")]
    public float CurrentPrice { get; set; }
}

Anotación del modelo de datos con atributos de columna

Los atributos proporcionan a ML.NET más información sobre el modelo de datos y el origen de datos.

El atributo LoadColumn especifica los índices de columna de las propiedades.

Importante

LoadColumn solo es necesario cuando se cargan datos desde un archivo.

Cargar columnas como:

  • Columnas individuales, como Size y CurrentPrices en la clase HousingData.
  • Varias columnas a la vez en forma de vector, como HistoricalPrices en la clase HousingData.

Si tiene una propiedad de vector, aplique el atributo VectorType a la propiedad en el modelo de datos. Todos los elementos del vector deben ser del mismo tipo. Mantener separadas las columnas permite facilitar y flexibilidad en la ingeniería de características, pero para un gran número de columnas, el funcionamiento de las columnas individuales provoca un impacto en la velocidad de entrenamiento.

ML.NET funciona a través de nombres de columna. Si desea cambiar el nombre de una columna a otro nombre que no sea el de la propiedad, utilice el atributo ColumnName. Al crear objetos en memoria, debe crear todavía objetos mediante el nombre de la propiedad. Sin embargo, para el procesamiento de datos y la compilación de modelos de aprendizaje automático, ML.NET invalida la propiedad y hace referencia a esta con el valor proporcionado en el atributo ColumnName.

Carga de datos desde un archivo único

Para cargar datos desde un archivo, use el método LoadFromTextFile con el modelo de datos para que se carguen los datos. Puesto que el parámetro separatorChar está delimitado por tabulaciones de forma predeterminada, cámbielo para el archivo de datos según sea necesario. Si el archivo tiene un encabezado, establezca el parámetro hasHeader en true para omitir la primera línea en el archivo y comenzar a cargar datos de la segunda línea.

//Create MLContext
MLContext mlContext = new MLContext();

//Load Data
IDataView data = mlContext.Data.LoadFromTextFile<HousingData>("my-data-file.csv", separatorChar: ',', hasHeader: true);

Carga de datos de varios archivos

En caso de que los datos se almacenen en varios archivos, siempre y cuando el esquema de datos sea el mismo, ML.NET permite cargar datos desde varios archivos que están en el mismo directorio o en varios directorios.

Carga de archivos en un único directorio

Cuando todos los archivos de datos se encuentran en el mismo directorio, utilice caracteres comodín en el método LoadFromTextFile.

//Create MLContext
MLContext mlContext = new MLContext();

//Load Data File
IDataView data = mlContext.Data.LoadFromTextFile<HousingData>("Data/*", separatorChar: ',', hasHeader: true);

Carga de archivos en varios directorios

Para cargar datos desde varios directorios, utilice el método CreateTextLoader para crear un TextLoader. A continuación, utilice el método TextLoader.Load y especifique las rutas de acceso de archivo individuales (no se pueden usar caracteres comodín).

//Create MLContext
MLContext mlContext = new MLContext();

// Create TextLoader
TextLoader textLoader = mlContext.Data.CreateTextLoader<HousingData>(separatorChar: ',', hasHeader: true);

// Load Data
IDataView data = textLoader.Load("DataFolder/SubFolder1/1.txt", "DataFolder/SubFolder2/1.txt");

Cargar datos desde una base de datos relacional

ML.NET admite la carga de datos desde una variedad de bases de datos relacionales admitidas por System.Data, entre las que se incluyen SQL Server, Azure SQL Database, Oracle, SQLite, PostgreSQL, Progress, IBM DB2 y muchas más.

Nota

Para usar DatabaseLoader, haga referencia al paquete NuGet System.Data.SqlClient.

Dada una base de datos con una tabla denominada House y el esquema siguiente:

CREATE TABLE [House] (
    [HouseId] INT NOT NULL IDENTITY,
    [Size] INT NOT NULL,
    [NumBed] INT NOT NULL,
    [Price] REAL NOT NULL
    CONSTRAINT [PK_House] PRIMARY KEY ([HouseId])
);

Los datos se pueden modelar mediante una clase como HouseData:

public class HouseData
{
    public float Size { get; set; }
    public float NumBed { get; set; }
    public float Price { get; set; }
}

Después, dentro de la aplicación, cree un DatabaseLoader.

MLContext mlContext = new MLContext();

DatabaseLoader loader = mlContext.Data.CreateDatabaseLoader<HouseData>();

Defina la cadena de conexión, así como el comando SQL que se va a ejecutar en la base de datos y cree una instancia DatabaseSource. En este ejemplo se utiliza una base de datos de SQL Server LocalDB con una ruta de acceso de archivo. Pero DatabaseLoader admite cualquier otra cadena de conexión válida para bases de datos locales y en la nube.

Importante

Microsoft recomienda usar el flujo de autenticación más seguro disponible. Si se conecta a Azure SQL, el método de autenticación recomendado es Identidades administradas para recursos de Azure.

string connectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=<YOUR-DB-FILEPATH>;Database=<YOUR-DB-NAME>;Integrated Security=True;Connect Timeout=30";

string sqlCommand = "SELECT CAST(Size as REAL) as Size, CAST(NumBed as REAL) as NumBed, Price FROM House";

DatabaseSource dbSource = new DatabaseSource(SqlClientFactory.Instance, connectionString, sqlCommand);

Los datos numéricos que no son de tipo Real se deben convertir en Real. El tipo Real se representa como un valor de punto flotante de precisión sencilla o Single, el tipo de entrada que esperan los algoritmos de ML.NET. En este ejemplo, las columnas Size y NumBed son enteros en la base de datos. Con la función integrada CAST, se convierte en Real. Dado que la propiedad Price ya es de tipo Real, se carga tal como está.

Use el método Load para cargar los datos en IDataView.

IDataView data = loader.Load(dbSource);

Cargar imágenes

Para cargar datos de imagen desde un directorio, cree primero un modelo que incluya la ruta de acceso de la imagen y una etiqueta. ImagePath es la ruta de acceso absoluta de la imagen en el directorio del origen de datos. Label es la clase o categoría del archivo de imagen real.

public class ImageData
{
    [LoadColumn(0)]
    public string ImagePath;

    [LoadColumn(1)]
    public string Label;
}

public static IEnumerable<ImageData> LoadImagesFromDirectory(string folder,
            bool useFolderNameAsLabel = true)
{
    string[] files = Directory.GetFiles(folder, "*", searchOption: SearchOption.AllDirectories);

    foreach (string file in files)
    {
        if (Path.GetExtension(file) != ".jpg")
            continue;

        string label = Path.GetFileName(file);

        if (useFolderNameAsLabel)
            label = Directory.GetParent(file).Name;
        else
        {
            for (int index = 0; index < label.Length; index++)
            {
                if (!char.IsLetter(label[index]))
                {
                    label = label.Substring(0, index);
                    break;
                }
            }
        }

        yield return new ImageData()
        {
            ImagePath = file,
            Label = label
        };
    }
}

A continuación, cargue la imagen:

IEnumerable<ImageData> images = LoadImagesFromDirectory(
                folder: "your-image-directory-path",
                useFolderNameAsLabel: true
                );

Para cargar imágenes sin procesar en memoria desde el directorio, cree un modelo para contener la matriz de bytes de imagen sin formato y la etiqueta:

public class InMemoryImageData
{
    [LoadColumn(0)]
    public byte[] Image;

    [LoadColumn(1)]
    public string Label;
}

static IEnumerable<InMemoryImageData> LoadInMemoryImagesFromDirectory(
    string folder,
    bool useFolderNameAsLabel = true
    )
{
    string[] files = Directory.GetFiles(folder, "*",
        searchOption: SearchOption.AllDirectories);
    foreach (string file in files)
    {
        if (Path.GetExtension(file) != ".jpg")
            continue;

        string label = Path.GetFileName(file);
        if (useFolderNameAsLabel)
            label = Directory.GetParent(file).Name;
        else
        {
            for (int index = 0; index < label.Length; index++)
            {
                if (!char.IsLetter(label[index]))
                {
                    label = label.Substring(0, index);
                    break;
                }
            }
        }

        yield return new InMemoryImageData()
        {
            Image = File.ReadAllBytes(file),
            Label = label
        };

    }
}

Carga de datos desde otros orígenes

Además de cargar datos almacenados en archivos, ML.NET admite la carga de datos de orígenes que incluyen:

  • Colecciones en memoria
  • JSON/XML

Al trabajar con orígenes de streaming, ML.NET espera que la entrada esté en forma de una colección en memoria. Por lo tanto, cuando se trabaja con orígenes como JSON o XML, asegúrese de dar a los datos el formato de una colección en memoria.

Dada la siguiente colección en memoria:

HousingData[] inMemoryCollection = new HousingData[]
{
    new HousingData
    {
        Size =700f,
        HistoricalPrices = new float[]
        {
            100000f, 3000000f, 250000f
        },
        CurrentPrice = 500000f
    },
    new HousingData
    {
        Size =1000f,
        HistoricalPrices = new float[]
        {
            600000f, 400000f, 650000f
        },
        CurrentPrice=700000f
    }
};

Cargue la colección en memoria en un IDataView con el método LoadFromEnumerable:

Importante

LoadFromEnumerable supone que IEnumerable de donde se carga es seguro para subprocesos.

// Create MLContext
MLContext mlContext = new MLContext();

//Load Data
IDataView data = mlContext.Data.LoadFromEnumerable<HousingData>(inMemoryCollection);

Pasos siguientes