カスタム データストアの開発
このトピックでは、ファイルベースのデータ用のカスタム データストアを実装する方法を説明します。このフレームワークは、独自のカスタム データストア インターフェイスを記述する場合にのみ使用します。それ以外の場合で、イメージやスプレッドシートなどの標準ファイル形式を扱うときは、MATLAB® から既存のデータストアを使用します。詳細については、データストア入門を参照してください。
概要
独自のカスタム データストア インターフェイスを作成するには、カスタム データストア クラスおよびオブジェクトを使用します。次に、このカスタム データストアを使用して MATLAB にデータを読み込み、tall、mapreduce、Hadoop® などの MATLAB のビッグ データ機能を利用します。
独自のカスタム データストアを設計する場合は、1 つ以上の抽象クラスから継承し、必須のメソッドを実装します。必要となる具体的なクラスおよびメソッドは処理のニーズによって異なります。
| 処理のニーズ | クラス |
|---|---|
| MATLAB での逐次処理のためのデータストア |
逐次処理のためのデータストアの実装を参照してください。 |
| Parallel Computing Toolbox™ および MATLAB Parallel Server™ をサポートするデータストア |
並列処理のサポートの追加を参照してください。 |
Hadoop をサポートするデータストア |
Hadoop サポートの追加を参照してください。 |
ランダムな順序によるデータストアのサンプルのシャッフリングをサポートするデータストア |
シャッフリングのサポートの追加を参照してください。 |
|
(オプションで データ書き込みのサポートの追加を参照してください。 |
まず逐次処理のためのデータストアを実装してから、並列処理、Hadoop、シャッフリング、または書き込みのサポートを追加します。
逐次処理のためのデータストアの実装
MyDatastore という名前のカスタム データストアを実装するために、MyDatastore.m というスクリプトを作成します。スクリプトは MATLAB パス上にあり、かつ、適切なクラスから継承し、必須のメソッドを定義したコードを含んでいなければなりません。MATLAB での逐次処理用のデータストアを作成するためのコードは以下でなければなりません。
基底クラス
matlab.io.Datastoreから継承する。hasdata、read、reset、progressの各メソッドを定義する。データ処理およびデータ解析の必要性に基づき、追加のプロパティおよびメソッドを定義する。
サンプル実装として、以下の手順に従います。
| 手順 | 実装 |
|---|---|
基底クラス | classdef MyDatastore < matlab.io.Datastore properties (Access = private) CurrentFileIndex double FileSet matlab.io.datastore.DsFileSet end |
ファイル システムやオペレーティング システムが異なる可能性のある別のマシンまたはクラスターでシームレスに機能するデータストアを作成するために、このプロパティを追加します。 メソッドのセクションに、このプロパティを取得および設定するためのメソッドを追加します。 | % Property to support saving, loading, and processing of % datastore on different file system machines or clusters. % In addition, define the methods get.AlternateFileSystemRoots() % and set.AlternateFileSystemRoots() in the methods section. properties(Dependent) AlternateFileSystemRoots end |
カスタム データストアを作成する関数 | methods % begin methods section function myds = MyDatastore(location,altRoots) myds.FileSet = matlab.io.datastore.DsFileSet(location,... 'FileExtensions','.bin', ... 'FileSplitSize',8*1024); myds.CurrentFileIndex = 1; if nargin == 2 myds.AlternateFileSystemRoots = altRoots; end reset(myds); end |
| function tf = hasdata(myds) % Return true if more data is available. tf = hasfile(myds.FileSet); end |
このメソッドでは 独自ファイル形式を読み取るための関数の作成を参照してください。 | function [data,info] = read(myds) % Read data and information about the extracted data. if ~hasdata(myds) error(sprintf(['No more data to read.\nUse the reset ',... 'method to reset the datastore to the start of ' ,... 'the data. \nBefore calling the read method, ',... 'check if data is available to read ',... 'by using the hasdata method.'])) end fileInfoTbl = nextfile(myds.FileSet); data = MyFileReader(fileInfoTbl); info.Size = size(data); info.FileName = fileInfoTbl.FileName; info.Offset = fileInfoTbl.Offset; % Update CurrentFileIndex for tracking progress if fileInfoTbl.Offset + fileInfoTbl.SplitSize >= ... fileInfoTbl.FileSize myds.CurrentFileIndex = myds.CurrentFileIndex + 1 ; end end |
| function reset(myds) % Reset to the start of the data. reset(myds.FileSet); myds.CurrentFileIndex = 1; end |
| % Before defining these methods, add the AlternateFileSystemRoots % property in the properties section % Getter for AlternateFileSystemRoots property function altRoots = get.AlternateFileSystemRoots(myds) altRoots = myds.FileSet.AlternateFileSystemRoots; end % Setter for AlternateFileSystemRoots property function set.AlternateFileSystemRoots(myds,altRoots) try % The DsFileSet object manages the AlternateFileSystemRoots % for your datastore myds.FileSet.AlternateFileSystemRoots = altRoots; % Reset the datastore reset(myds); catch ME throw(ME); end end end |
| methods (Hidden = true)
function frac = progress(myds)
% Determine percentage of data read from datastore
if hasdata(myds)
frac = (myds.CurrentFileIndex-1)/...
myds.FileSet.NumFiles;
else
frac = 1;
end
end
end |
| methods (Access = protected)
% If you use the DsFileSet object as a property, then
% you must define the copyElement method. The copyElement
% method allows methods such as readall and preview to
% remain stateless
function dscopy = copyElement(ds)
dscopy = copyElement@matlab.mixin.Copyable(ds);
dscopy.FileSet = copy(ds.FileSet);
end
end |
| end |
独自ファイル形式を読み取るための関数の作成
カスタム データストアの read メソッドの実装には、MyFileReader という名前の関数を使用します。カスタム データまたは独自データを読み取るには、この関数を作成しなければなりません。DsFileReader オブジェクトとそのメソッドを使用して、この関数を作成します。たとえば、バイナリ ファイルを読み取る関数を作成します。
function data = MyFileReader(fileInfoTbl) % create a reader object using the FileName reader = matlab.io.datastore.DsFileReader(fileInfoTbl.FileName); % seek to the offset seek(reader,fileInfoTbl.Offset,'Origin','start-of-file'); % read fileInfoTbl.SplitSize amount of data data = read(reader,fileInfoTbl.SplitSize); end
並列処理のサポートの追加
Parallel Computing Toolbox および MATLAB Parallel Server で並列処理のサポートを追加するには、MyDatastore.m の実装コードを以下のように更新します。
追加のクラス
matlab.io.datastore.Partitionableから継承する。2 つの追加メソッド、
maxpartitionsおよびpartitionを定義する。
サンプル実装として、以下の手順に従います。
| 手順 | 実装 |
|---|---|
| classdef MyDatastore < matlab.io.Datastore & ... matlab.io.datastore.Partitionable . . . |
| methods
.
.
.
function subds = partition(myds,n,ii)
subds = copy(myds);
subds.FileSet = partition(myds.FileSet,n,ii);
reset(subds);
end
end
|
| methods (Access = protected)
function n = maxpartitions(myds)
n = maxpartitions(myds.FileSet);
end
end
|
| end |
Hadoop サポートの追加
Hadoop のサポートを追加するには、MyDatastore.m の実装コードを以下のように更新します。
追加のクラス
matlab.io.datastore.HadoopLocationBasedから継承する。2 つの追加メソッド
getLocationおよびinitializeDatastoreを定義する。
サンプル実装として、以下の手順に従います。
| 手順 | 実装 |
|---|---|
| classdef MyDatastore < matlab.io.Datastore & ... matlab.io.datastore.HadoopLocationBased . . . |
| methods (Hidden = true)
.
.
.
function initializeDatastore(myds,hadoopInfo)
import matlab.io.datastore.DsFileSet;
myds.FileSet = DsFileSet(hadoopInfo,...
'FileSplitSize',myds.FileSet.FileSplitSize);
reset(myds);
end
function loc = getLocation(myds)
loc = myds.FileSet;
end
% isfullfile method is optional
function tf = isfullfile(myds)
tf = isequal(myds.FileSet.FileSplitSize,'file');
end
end |
| end |
シャッフリングのサポートの追加
シャッフリングのサポートを追加するには、MyDatastore.m の実装コードを以下のように更新します。
追加のクラス
matlab.io.datastore.Shuffleableから継承する。追加のメソッド
shuffleを定義する。
サンプル実装として、以下の手順に従います。
| 手順 | 実装 |
|---|---|
| classdef MyDatastore < matlab.io.Datastore & ... matlab.io.datastore.Shuffleable . . . |
| methods
% previously defined methods
.
.
.
function dsNew = shuffle(ds)
% dsNew = shuffle(ds) shuffles the files and the
% corresponding labels in the datastore.
% Create a copy of datastore
dsNew = copy(ds);
dsNew.Datastore = copy(ds.Datastore);
fds = dsNew.Datastore;
% Shuffle files and corresponding labels
numObservations = dsNew.NumObservations;
idx = randperm(numObservations);
fds.Files = fds.Files(idx);
dsNew.Labels = dsNew.Labels(idx);
end
end |
| end |
データ書き込みのサポートの追加
データ書き込みのサポートを追加するには、MyDatastore.m の実装コードを以下の要件に従うように更新します。
追加のクラス
matlab.io.datastore.FileWritableから継承する。SupportedOutputFormatsプロパティおよびDefaultOutputFormatプロパティを初期化する。データストアがデータをカスタム形式に書き込む場合は
writeメソッドを実装する。データストアに
Filesプロパティがない場合はgetFilesメソッドを実装する。データストアに
Foldersプロパティがない場合はgetFoldersメソッドを実装する。出力する場所が string として検証される。データストアの検証がさらに必要な場合は
validateOutputLocationメソッドを実装しなければなりません。データストアが、ファイルごとに複数の読み取りを必要とするファイル用の場合は、
getCurrentFilenameメソッドおよびcurrentFileIndexComparatorメソッドを実装しなければならない。オプションで、別の
matlab.io.datastore.FoldersPropertyProviderクラスから継承して、Foldersプロパティ (およびwriteallのFolderLayoutの名前と値のペア) のサポートを追加する。これを行う場合、データストア コンストラクターでpopulateFoldersFromLocationメソッドを使用して、Foldersプロパティを入力できる。writeallの'UseParallel'オプションのサポートを追加するには、matlab.io.datastore.FileWritableとmatlab.io.datastore.Partitionableの両方からサブクラス化し、サブクラスに構文partition(ds,'Files',index)をサポートするpartitionメソッドを実装しなければならない。
matlab.io.datastore.FileWritable から継承するサンプルの実装については、次の手順に従います。
| 手順 | 実装 |
|---|---|
|
classdef MyDatastore < matlab.io.Datastore & ... matlab.io.datastore.FileWritable . . . |
|
properties (Constant)
SupportedOutputFormats = ...
[matlab.io.datastore.ImageDatastore.SupportedOutputFormats, "dcm"];
DefaultOutputFormat = "dcm";
end |
|
methods (Access = {?matlab.io.datastore.FileWritable, ...
?matlab.bigdata.internal.executor.FullfileDatastorePartitionStrategy})
function files = getFiles(ds)
files = {'data/folder/file1', 'data/folder/file2',...};
end
end
methods (Access = protected)
function folders = getFolders(ds)
folders = {'data/folder1/', 'data/folder2/',...};
end
end |
データストアがデータをカスタム形式に書き込む場合は、 |
methods(Access = protected)
function tf = write(myds, data, writeInfo, outFmt, varargin)
if outFmt == "dcm" % use custom write fcn for dcm format
dicomwrite(data, writeInfo.SuggestedOutputName, varargin{:});
else % callback into built-in for known formats
write@matlab.io.datastore.FileWritable(myds, data, ...
writeInfo, outFmt, varargin{:});
end
tf = true;
end
end |
|
end |
matlab.io.datastore.FileWritable と matlab.io.datastore.FoldersPropertyProvider の両方から継承する長いクラスの例については、DICOM データ用のカスタム データストアの開発を参照してください。
カスタム データストアの検証
これまで説明してきた指示に従うと、カスタム データストアの実装手順が完了します。このカスタム データストアを使用する前に、カスタム データストアのテストのガイドラインに示されているガイドラインを使用して検定してください。
参考
matlab.io.Datastore | matlab.io.datastore.Partitionable | matlab.io.datastore.HadoopLocationBased | matlab.io.datastore.Shuffleable | matlab.io.datastore.DsFileSet | matlab.io.datastore.DsFileReader | matlab.io.datastore.FoldersPropertyProvider | matlab.io.datastore.FileWritable