ファイルとその他のソースからデータを読み込む
API を利用し、処理とトレーニング用のデータを ML.NET に読み込む方法について説明します。 データは、最初はファイルや、データベース、JSON、XML、メモリ内コレクションなどの他のデータ ソースに格納されます。
モデル ビルダーを使用している場合、「モデル ビルダーにトレーニング データを読み込む」を参照してください。
データ モデルの作成
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
は、ファイルからデータを読み込む場合にのみ必要です。
列は次のように読み込みます。
Size
クラスのCurrentPrices
やHousingData
のように個々の列。HistoricalPrices
クラスのHousingData
のようにベクター形式で一度に複数の列。
ベクター プロパティがある場合は、データ モデルのプロパティに VectorType
属性を適用します。 ベクターの要素はすべて同じ型である必要があります。 列を分割したままにすると、特徴エンジニアリングが容易になり、柔軟性が向上しますが、列数が多い場合、個々の列を操作するとトレーニング速度に影響します。
ML.NET は列名を介して動作します。 列の名前をプロパティ名以外に変更する場合は、ColumnName
属性を使用します。 メモリ内オブジェクトを作成するときも、プロパティ名を使ってオブジェクトを作成します。 ただし、データ処理と機械学習モデルの構築の場合、ML.NET では ColumnName
属性に指定された値でプロパティがオーバーライドされ、参照されます。
1 つのファイルからデータを読み込む
ファイルからデータを読み込むには、読み込むデータのデータ モデルと共に LoadFromTextFile
メソッドを使用します。 separatorChar
パラメーターは既定でタブ区切りなので、必要に応じてデータ ファイルに合わせて変更します。 ファイルにヘッダーがある場合は、ファイルの最初の行を無視して 2 行目からデータの読み込みを開始するように、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 では、同じディレクトリまたは複数のディレクトリ内にある複数のファイルからデータを読み込むことができます。
1 つのディレクトリ内のファイルから読み込む
すべてのデータ ファイルが同じディレクトリ内にある場合は、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 では、sql Server、Azure SQL Database、Oracle、SQLite、PostgreSQL、Progress、IBM DB2 など、System.Data
でサポートされているさまざまなリレーショナル データベースからのデータの読み込みがサポートされています。
Note
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 リソースの管理 ID が推奨される認証方法です。
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
型は、単精度浮動小数点値または ML.NET アルゴリズムによって求められる入力型の Single
として表されます。 このサンプルでは、Size
列と NumBed
列はどちらも、データベース内では整数です。 CAST
組み込み関数を使用すると、Real
に変換されます。 Price
プロパティは既に Real
型であるため、as-is読み込まれます。
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
}
};
IDataView
メソッドを使用してメモリ内コレクションを LoadFromEnumerable
に読み込みます。
重要
LoadFromEnumerable
では、この読み込み元の IEnumerable
がスレッドセーフであると想定されています。
// Create MLContext
MLContext mlContext = new MLContext();
//Load Data
IDataView data = mlContext.Data.LoadFromEnumerable<HousingData>(inMemoryCollection);
次の手順
- データを消去するか、消去以外の処理を行う方法については、「モデル構築用のデータを準備する」を参照してください。
- モデルを構築する用意ができたら、「モデルのトレーニングと評価」を参照してください。
.NET