從檔案和其他來源載入資料
了解如何使用 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
類別中的Size
和CurrentPrices
。 - 以類似
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 演算法所預期的輸入型別。 在此範例中,資料庫中的 Size
和 NumBed
資料行都是整數。 使用 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);