Compartilhar via


Carregar dados de arquivos e outras fontes

Saiba como carregar dados no ML.NET para processamento e treinamento usando a API. Originalmente, os dados são armazenados em arquivos ou outras fontes de dados, como bancos de dados, JSON, XML ou coleções na memória.

Se você estiver usando o Model Builder, confira Carregar dados de treinamento no Model Builder.

Criar o modelo de dados

O ML.NET permite que você defina modelos de dados por meio de classes. Por exemplo, considerando os seguintes dados de entrada:

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

Crie um modelo de dados que represente o snippet a seguir:

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; }
}

Anotar o modelo de dados com atributos de coluna

Atributos dão ao ML.NET mais informações sobre o modelo de dados e a fonte de dados.

O atributo LoadColumn especifica os índices de colunas de suas propriedades.

Importante

LoadColumn é necessário apenas ao carregar dados de um arquivo.

Carregar colunas como:

  • Colunas individuais, como Size e CurrentPrices na classe HousingData.
  • Várias colunas por vez na forma de um vetor, como HistoricalPrices na classe HousingData.

Se você tiver uma propriedade de vetor, aplique o atributo VectorType à propriedade em seu modelo de dados. Todos os elementos no vetor devem ser do mesmo tipo. Manter as colunas separadas permite a facilidade e a flexibilidade da engenharia de recursos, mas, para um grande número de colunas, a operação nas colunas individuais causa um impacto na velocidade de treinamento.

O ML.NET opera por meio de nomes de coluna. Se você quiser alterar o nome de uma coluna para algo diferente do nome de propriedade, use o atributo ColumnName. Ao criar objetos na memória, você ainda cria objetos usando o nome da propriedade. No entanto, para processar e criar modelos de machine learning, o ML.NET substitui e faz referência à propriedade com o valor fornecido no atributo ColumnName.

Carregar dados de um único arquivo

Para carregar dados de um arquivo, use o método LoadFromTextFile com o modelo de dados para os dados a serem carregados. Uma vez que o parâmetro separatorChar é delimitado por tabulação por padrão, altere-o para seu arquivo de dados conforme necessário. Se o arquivo tiver um cabeçalho, defina o parâmetro hasHeader como true para ignorar a primeira linha no arquivo e começar a carregar dados da segunda linha.

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

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

Carregar dados de vários arquivos

Caso seus dados sejam armazenados em vários arquivos, desde que o esquema de dados seja o mesmo, o ML.NET permitirá que você carregue dados de vários arquivos que estejam no mesmo diretório ou em vários diretórios.

Carregar de arquivos em um único diretório

Quando todos os seus arquivos de dados estão no mesmo diretório, use caracteres curinga no método LoadFromTextFile.

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

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

Carregar de arquivos em vários diretórios

Para carregar dados de vários diretórios, use o método CreateTextLoader para criar um TextLoader. Em seguida, use o método TextLoader.Load e especifique os caminhos de arquivo individual (caracteres curinga não podem ser usados).

//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");

Carregar dados de um banco de dados relacional

O ML.NET dá suporte ao carregamento de dados de uma variedade de bancos de dados relacionais compatíveis com System.Data, como o SQL Server, o Banco de Dados SQL do Azure, o Oracle, o SQLite, o PostgreSQL, o Progress, o IBM DB2 e muito mais.

Observação

Para usar DatabaseLoader, faça referência ao pacote NuGet System.Data.SqlClient.

Dado um banco de dados com uma tabela nomeada House e o seguinte esquema:

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])
);

Os dados podem ser modelados por uma classe como HouseData:

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

Em seguida, no aplicativo, crie um DatabaseLoader.

MLContext mlContext = new MLContext();

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

Defina a cadeia de conexão, bem como o comando SQL a ser executado no banco de dados, e crie uma instância DatabaseSource. Este exemplo usa um banco de dados SQL Server LocalDB com um caminho de arquivo. No entanto, o DatabaseLoader dá suporte a qualquer outra cadeia de conexão válida para bancos de dados locais e na nuvem.

Importante

A Microsoft recomenda usar o fluxo de autenticação mais seguro disponível. Se você estiver se conectando ao SQL do Azure, as Identidades gerenciadas para recursos do Azure é o método de autenticação recomendado.

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);

Dados numéricos que não são do tipo Real devem ser convertidos em Real. O tipo Real é representado como um valor de ponto flutuante de precisão única ou como Single, o tipo de entrada esperado por algoritmos do ML.NET. Neste exemplo, as colunas Size e NumBed são inteiros no banco de dados. Usando a função interna CAST, eles são convertidos em Real. Como a propriedade Price já é do tipo Real, ela é carregada no estado em que se encontra.

Use o método Load para carregar os dados em um IDataView.

IDataView data = loader.Load(dbSource);

Carregar imagens

Para carregar dados de imagem de um diretório, primeiro crie um modelo que inclua o caminho da imagem e um rótulo. ImagePath é o caminho absoluto da imagem no diretório da fonte de dados. Label é a classe ou categoria do arquivo da imagem 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
        };
    }
}

Em seguida, carregue a imagem:

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

Para carregar imagens brutas na memória a partir do diretório, crie um modelo para manter a matriz de bytes de imagem bruta e o rótulo:

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
        };

    }
}

Carregar dados de outras fontes

Além de carregar os dados armazenados em arquivos, o ML.NET dá suporte ao carregamento de dados de várias fontes que incluem:

  • Coleções na memória
  • JSON/XML

Ao trabalhar com fontes de streaming, o ML.NET espera que a entrada esteja na forma de uma coleção em memória. Portanto, ao trabalhar com fontes, como JSON/XML, formate os dados em uma coleção em memória.

Dada a coleção em memória a seguir:

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
    }
};

Carregue a coleção em memória em um IDataView com o método LoadFromEnumerable:

Importante

O LoadFromEnumerable pressupõe que o IEnumerable carregado é thread-safe.

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

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

Próximas etapas