共用方式為


從檔案和其他來源載入資料

了解如何使用 API,將要處理和定型的資料載入 ML.NET。 資料原先是儲存在檔案或其他資料來源中,例如資料庫、JSON、XML 或記憶體內部集合。

如果您正在使用 Model Builder,請參閱 將定型資料載入 Model Builder

建立資料模型

ML.NET 可讓您透過類別定義資料模型。 例如,假設有下列的輸入資料:

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

建立資料模型以表示以下的程式碼片段:

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

使用資料行屬性標註資料模型

屬性可提供 ML.NET 更多關於資料模型和資料來源的資訊。

LoadColumn 屬性會指定您屬性的資料行索引。

重要

LoadColumn 只有在從檔案載入資料時才需要。

將資料行作為以下項目載入:

  • 個別資料行,像是 HousingData 類別中的 SizeCurrentPrices
  • 以類似 HousingData 類別中 HistoricalPrices 的向量形式,一次載入多個資料行。

若您擁有向量屬性,請將 VectorType 屬性套用到您資料模型中的屬性。 向量中的所有元素都必須是相同的型別。 將資料行保持分離可讓您更輕易且具備彈性地進行特徵工程,但針對大量的資料行,在每一個資料行上進行作業會影響定型速度。

ML.NET 會透過資料行名稱運作。 若您想要將資料行名稱變更為屬性名稱之外的名稱,請使用 ColumnName 屬性。 在建立記憶體內部物件時,您仍會使用屬性名稱建立物件。 但是,針對資料處理和建置機器學習模型,ML.NET 會使用 ColumnName 屬性中提供的值來覆寫及參考屬性。

從單一檔案載入資料

若要從檔案載入資料,請搭配要載入其資料的資料模型使用 LoadFromTextFile 方法。 因為 separatorChar 參數根據預設會以 Tab 鍵分隔,您可以視需要為您的資料檔案變更它。 若您的檔案擁有標頭,請將 hasHeader 參數設為 true 來忽略檔案中的第一行,並從第二行開始載入資料。

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

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

從多個檔案載入資料

您的資料儲存在多個檔案,只要資料結構描述相同,ML.NET 可讓您將資料載入會在相同目錄中的多個檔案或多個目錄。

從單一目錄中的檔案載入

當您所有的資料檔案都位於相同目錄時,請在 LoadFromTextFile 方法中使用萬用字元。

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

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

載入多個目錄中的檔案

若要從多個目錄載入資料,請使用 CreateTextLoader 方法來建立 TextLoader。 然後,請使用 TextLoader.Load 方法並指定個別檔案路徑 (無法使用萬用字元)。

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

從關聯式資料庫載入資料

ML.NET 支援從受 System.Data 支援的各種關聯式資料庫載入資料,這些資料庫包括 SQL Server、Azure SQL Database、Oracle、SQLite、PostgreSQL、Progress、IBM DB2 等等。

注意

若要使用 DatabaseLoader,請參考 System.Data.SqlClient NuGet 套件。

給定的資料庫具有名為 House 的表格和下列結構描述:

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

資料可由 HouseData 等類別建立模型:

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

然後在應用程式內建立 DatabaseLoader

MLContext mlContext = new MLContext();

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

定義連接字串,以及要在資料庫上執行的 SQL 命令,並建立 DatabaseSource 執行個體。 此範例會使用帶有檔案路徑的 LocalDB SQL Server 資料庫。 不過,DatabaseLoader 支援任何其他有效的連接字串,這些字串可用於內部部署和雲端資料庫。

重要

Microsoft建議您使用可用的最安全驗證流程。 如果您正在連接 Azure SQL,建議使用的驗證方法為 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);

不是 Real 型別的數值資料必須轉換成 Real。 此 Real 型別會表示為單精確度浮點數值或 Single,這是 ML.NET 演算法所預期的輸入型別。 在此範例中,資料庫中的 SizeNumBed 資料行都是整數。 使用 CAST 內建函式會將資料轉換成 Real。 因為 Price 屬性已經是型別 Real,所以會依原樣載入。

使用 Load 方法將資料載入 IDataView

IDataView data = loader.Load(dbSource);

載入映像

若要從目錄載入映像資料,請先建立包含映像路徑和標籤的模型。 ImagePath 是資料來源目錄中映像的絕對路徑。 Label 是實際映像檔案的類別或分類。

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

然後載入此映像:

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

若要從目錄載入記憶體內部原始映像,請建立模型以保存原始映像位元組陣列和標籤:

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

    }
}

從其他來源載入資料

除了載入在檔案中儲存的資料,ML.NET 支援從包含以下項目的來源載入資料:

  • 記憶體內集合
  • JSON/XML

使用串流來源時,ML.NET 預期輸入的形式為記憶體內部集合。 因此,當使用像是 JSON/XML 等來源時,請務必將資料格式化成記憶體內部集合。

假設有下列記憶體內部集合:

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

請使用 LoadFromEnumerable 方法將記憶體內部集合載入 IDataView

重要

LoadFromEnumerable 假設它載入的 IEnumerable 是安全執行緒。

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

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

下一步