Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RDatasetLoader.cxx
Go to the documentation of this file.
1#include "RDatasetLoader.hxx"
2
4
5RDatasetLoader::RDatasetLoader(const std::vector<ROOT::RDF::RNode> &rdfs, const float validationSplit,
6 const std::vector<std::string> &cols, const std::vector<std::size_t> &vecSizes,
7 const float vecPadding, bool shuffle, const std::size_t setSeed)
8 : fValidationSplit(validationSplit),
9 fVecSizes(vecSizes),
10 fVecPadding(vecPadding),
11 f_rdfs(rdfs),
12 fCols(cols),
13 fSetSeed(setSeed),
14 fShuffle(shuffle)
15{
16 fTensorOperators = std::make_unique<RFlat2DMatrixOperators>(fShuffle, fSetSeed);
17 fNumCols = fCols.size();
18 fSumVecSizes = std::accumulate(fVecSizes.begin(), fVecSizes.end(), 0);
19
21}
22
23//////////////////////////////////////////////////////////////////////////
24/// \brief Split an individual dataframe into a training and validation dataset
25/// \param[in] rdf Dataframe that will be split into training and validation
26/// \param[in] TrainingDataset Tensor for the training dataset
27/// \param[in] ValidationDataset Tensor for the validation dataset
29 RFlat2DMatrix &ValidationDataset)
30{
31 const bool NotFiltered = rdf.GetFilterNames().empty();
32
33 // size the buffer from the cluster metadata, Count() is only the fallback for sources without it
35 std::size_t NumEntries = 0;
36 if (NotFiltered) {
37 try {
38 for (const auto &cluster : ROOT::Internal::RDF::GetDatasetGlobalClusterBoundaries(rdf)) {
39 NumEntries += cluster.second - cluster.first;
40 }
41 } catch (const std::runtime_error &) {
42 // GetDatasetGlobalClusterBoundaries() throws when the RDataFrame has no cluster
43 // metadata to query (a source other than TTree/RNTuple or no data source at all).
44 // Those paths fall back to Count() below.
45 }
46 if (NumEntries == 0) {
47 NumEntries = static_cast<std::size_t>(*rdf.Count());
48 }
49 } else {
50 Entries = rdf.Take<ULong64_t>("rdfentry_");
51 NumEntries = Entries->size();
52 // add the last element in entries to not go out of range when filling chunks
53 Entries->push_back((*Entries)[NumEntries - 1] + 1);
54 }
55
56 // number of training and validation entries after the split
57 std::size_t NumValidationEntries = static_cast<std::size_t>(fValidationSplit * NumEntries);
58 std::size_t NumTrainingEntries = NumEntries - NumValidationEntries;
59
60 // reserve the dataset and let the values be appended to it
61 RFlat2DMatrix Dataset;
62 Dataset.fRVec.reserve(NumEntries * fNumDatasetCols);
63
64 if (NotFiltered) {
66 }
67
68 else {
69 for (std::size_t j = 0; j < NumEntries; j++) {
70 ROOT::Internal::RDF::ChangeBeginAndEndEntries(rdf, (*Entries)[j], (*Entries)[j + 1]);
72 }
73 }
74 Dataset.Resize(NumEntries, fNumDatasetCols);
75
76 // reset dataframe, only the filtered path changed the entry range
77 if (!NotFiltered) {
78 ROOT::Internal::RDF::ChangeBeginAndEndEntries(rdf, (*Entries)[0], (*Entries)[NumEntries]);
79 }
80
81 // copy out the validation tail, then shrink the (shuffled) buffer to the training rows and move it
82 RFlat2DMatrix ShuffledDataset;
83 RFlat2DMatrix &Source = fTensorOperators->ShuffleTensor(ShuffledDataset, Dataset);
84 fTensorOperators->SliceTensor(ValidationDataset, Source, {{NumTrainingEntries, NumEntries}, {0, fNumDatasetCols}});
85 Source.Resize(NumTrainingEntries, fNumDatasetCols);
86 TrainingDataset = std::move(Source);
87}
88
89//////////////////////////////////////////////////////////////////////////
90/// \brief Split the dataframes in a training and validation dataset
92{
95
96 for (auto &rdf : f_rdfs) {
97 RFlat2DMatrix TrainingDataset;
98 RFlat2DMatrix ValidationDataset;
99
100 SplitDataframe(rdf, TrainingDataset, ValidationDataset);
101
102 fNumTrainingEntries += TrainingDataset.GetRows();
103 fNumValidationEntries += ValidationDataset.GetRows();
104
105 fTrainingDatasets.push_back(std::move(TrainingDataset));
106 fValidationDatasets.push_back(std::move(ValidationDataset));
107 }
108}
109
110//////////////////////////////////////////////////////////////////////////
111/// \brief Concatenate the datasets to a dataset
113{
114 if (fTrainingDatasets.size() == 1) {
115 fTrainingDataset = std::move(fTrainingDatasets[0]);
117 } else {
120 }
121 fTrainingDatasets.clear();
122 fValidationDatasets.clear();
123}
124
125} // namespace ROOT::Experimental::Internal::ML
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Definition RtypesCore.h:85
void reserve(size_type N)
Definition RVec.hxx:606
void SplitDataframe(ROOT::RDF::RNode &rdf, RFlat2DMatrix &TrainingDataset, RFlat2DMatrix &ValidationDataset)
Split an individual dataframe into a training and validation dataset.
void SplitDatasets()
Split the dataframes in a training and validation dataset.
std::unique_ptr< RFlat2DMatrixOperators > fTensorOperators
void ConcatenateDatasets()
Concatenate the datasets to a dataset.
RDatasetLoader(const std::vector< ROOT::RDF::RNode > &rdfs, const float validationSplit, const std::vector< std::string > &cols, const std::vector< std::size_t > &vecSizes={}, const float vecPadding=0.0, bool shuffle=true, const std::size_t setSeed=0)
The public interface to the RDataFrame federation of classes.
std::vector< std::string > GetFilterNames()
Returns the names of the filters created.
RResultPtr< COLL > Take(std::string_view column="")
Return a collection of values of a column (lazy action, returns a std::vector by default).
RResultPtr< ULong64_t > Count()
Return the number of entries processed (lazy action).
Smart pointer for the return type of actions.
void LoadCustomValues(ROOT::RDF::RNode &node, const std::vector< std::string > &cols, const std::vector< std::size_t > &vecSizes, float vecPadding, ROOT::RVecF &dest)
std::vector< std::pair< std::uint64_t, std::uint64_t > > GetDatasetGlobalClusterBoundaries(const RNode &node)
Retrieve the cluster boundaries for each cluster in the dataset, across files, with a global offset.
void ChangeBeginAndEndEntries(const RNode &node, Long64_t begin, Long64_t end)
Wrapper around ROOT::RVec<float> representing a 2D matrix.
void Resize(std::size_t rows, std::size_t cols)