Dela via


Läsa in data från filer och andra källor

Lär dig hur du läser in data i ML.NET för bearbetning och träning med hjälp av API:et. Data lagras ursprungligen i filer eller andra datakällor som databaser, JSON, XML eller minnesinterna samlingar.

Om du använder Model Builder läser du Läsa in träningsdata i Model Builder.

Skapa datamodellen

ML.NET kan du definiera datamodeller via klasser. Till exempel med hjälp av följande indata:

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

Skapa en datamodell som representerar följande kodfragment:

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

Kommentera datamodellen med kolumnattribut

Attribut ger ML.NET mer information om datamodellen och datakällan.

Attributet LoadColumn anger dina egenskapers kolumnindex.

Viktigt!

LoadColumn krävs endast vid inläsning av data från en fil.

Läs in kolumner som:

  • Enskilda kolumner, som Size och CurrentPrices i HousingData klassen.
  • Flera kolumner i taget i form av en vektor, till exempel HistoricalPrices i HousingData klassen.

Om du har en vektoregenskap tillämpar VectorType du attributet på egenskapen i datamodellen. Alla element i vektorn måste vara av samma typ. Att hålla kolumnerna åtskilda möjliggör enkel och flexibel funktionsutveckling, men för ett stort antal kolumner påverkar driften av de enskilda kolumnerna träningshastigheten.

ML.NET fungerar via kolumnnamn. Om du vill ändra namnet på en kolumn till något annat än egenskapsnamnet använder du attributet ColumnName . När du skapar minnesinterna objekt skapar du fortfarande objekt med egenskapsnamnet. Men för databearbetning och skapande av maskininlärningsmodeller ML.NET åsidosättningar och refererar till egenskapen med värdet som anges i ColumnName attributet.

Läsa in data från en enda fil

Om du vill läsa in data från en fil använder du LoadFromTextFile metoden med datamodellen för att läsa in data. Eftersom separatorChar parametern är tab-avgränsad som standard ändrar du den för din datafil efter behov. Om filen har en rubrik anger du parametern hasHeader till true för att ignorera den första raden i filen och börjar läsa in data från den andra raden.

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

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

Läsa in data från flera filer

Om dina data lagras i flera filer, så länge dataschemat är detsamma, kan du ML.NET läsa in data från flera filer som antingen finns i samma katalog eller flera kataloger.

Läsa in från filer i en enda katalog

När alla dina datafiler finns i samma katalog använder du jokertecken i LoadFromTextFile -metoden.

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

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

Läsa in från filer i flera kataloger

Om du vill läsa in data från flera kataloger använder du CreateTextLoader metoden för att skapa en TextLoader. TextLoader.Load Använd sedan metoden och ange de enskilda filsökvägarna (jokertecken kan inte användas).

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

Läsa in data från en relationsdatabas

ML.NET stöder inläsning av data från en mängd olika relationsdatabaser som stöds av System.Data som SQL Server, Azure SQL Database, Oracle, SQLite, PostgreSQL, Progress, IBM DB2 och många fler.

Kommentar

Om du vill använda DatabaseLoaderrefererar du till NuGet-paketet System.Data.SqlClient .

Givet en databas med en tabell med namnet House och följande schema:

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

Data kan modelleras av en klass som HouseData:

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

I ditt program skapar du sedan en DatabaseLoader.

MLContext mlContext = new MLContext();

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

Definiera din anslutningssträng samt SQL-kommandot som ska köras på databasen och skapa en DatabaseSource instans. Det här exemplet använder en LocalDB SQL Server-databas med en filsökväg. DatabaseLoader stöder dock alla andra giltiga anslutningssträng för databaser lokalt och i molnet.

Viktigt!

Microsoft rekommenderar att du använder det säkraste tillgängliga autentiseringsflödet. Om du ansluter till Azure SQL är hanterade identiteter för Azure-resurser den rekommenderade autentiseringsmetoden.

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

Numeriska data som inte är av typen Real måste konverteras till Real. Typen Real representeras som ett flyttal med enkel precision eller Single, den indatatyp som förväntas av ML.NET algoritmer. I det här exemplet är kolumnerna Size och NumBed heltalen i databasen. Med den CAST inbyggda funktionen konverteras den till Real. Eftersom egenskapen Price redan är av typen Realläses den in som den är.

Load Använd metoden för att läsa in data till en IDataView.

IDataView data = loader.Load(dbSource);

Läsa in bilder

Om du vill läsa in bilddata från en katalog skapar du först en modell som innehåller bildsökvägen och en etikett. ImagePath är den absoluta sökvägen till avbildningen i datakällans katalog. Label är klassen eller kategorin för den faktiska bildfilen.

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

Läs sedan in avbildningen:

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

Om du vill läsa in minnesinterna råa avbildningar från katalogen skapar du en modell för att lagra den råa bytematrisen för avbildningen och etiketten:

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

    }
}

Läsa in data från andra källor

Förutom att läsa in data som lagras i filer stöder ML.NET inläsning av data från källor som omfattar:

  • Minnesinterna samlingar
  • JSON/XML

När du arbetar med strömningskällor förväntar sig ML.NET att indata ska vara i form av en minnesintern samling. När du arbetar med källor som JSON/XML bör du därför formatera data till en minnesintern samling.

Med tanke på följande minnesintern samling:

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

Läs in den minnesinterna samlingen till en IDataView med LoadFromEnumerable -metoden:

Viktigt!

LoadFromEnumerable förutsätter att den som IEnumerable läses in från är trådsäker.

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

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

Nästa steg