-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Agnostic data container proposal #15
Comments
I was wondering if data container are not well handeled in packages like https://github.com/queryverse/Queryverse.jl |
Currently Query.jl supports only in-memory data sources, so not JuliaDB |
Sorry mixed it up with https://github.com/queryverse/IterableTables.jl/blob/master/docs/src/integrationguide.md which does |
I've tried IterableTables a bit and it is much easier to get along with. |
Here is another challenge for agnostic data containers, which concerns categorical data. Some data containers do not handle factors well. In a DataFrame and other column-based containers, a column for a categorical feature can store metadata encoding all possible classes for the features, so that if I restrict to some subset of rows, I still know what all the possible values are, even if they do not occur in the restricted frame. If a model needs such data one-hot encoded, for example, the encoder can get all the information it needs just from, say, the training set, and later we can apply the same transformation to the test set. This means wrapping such models in the encoding transformation is not problematic. However, in JuliaDB for example, which is row-based, there is no such column meta data. One must see all the data before one can know how to one-hot encode a categorical. That's fine if we do our preprocessing "a priori" but precludes wrapping a model in an encoder because we only train on training data and the training data may not contain all classes seen in test. |
I simply think a "proper" data container (for data scientific modelling) needs to be type aware. I.e., it needs to provide a method by which the user can query what type they would expect at a position within - including whether it is a factor variable and if yes which levels it has. |
A problem with using Query.jl, Tables.jl or similar as our interface point to data is that these are designed to handle very general source types. In particular, they do not allow random access to rows. They just generate row iterators, meaning random access is slow. Since the dominant use-case is data we load into memory, this is not satisfactory. I see we have three options: (a) Write our own interface for each type we want to support (not too bad, as we mostly have DataFrames and JuiliaDB on our wish list) (b) Abandon our desire to support multiple containers; or (c) use IterableTables or similar to convert any datatype into our favourite kind (which we could just as well require the user to do, and revert to (b)). The other possibility is that there is a common random-access interface for in-memory data types out there, but I am not aware of one. |
Our agnostic data interface doesn't have to do much, but at minimum I think MLJ needs to be able to access arbitrary rows by index or splice (for, e.g., resampling) and request a subset of columns by name or index/splice. We should be able to extract the column names. It would be nice to be able change columns in-place (e.g., to standardise data) and to add columns (e.g., one-hot encode). Vertical and horizontal concatenation would also be nice. We probably don't need general joins or group-by. |
Regarding previous discussion regarding nominal features, the proposal is now the following: MLJ will require nominal features to have a nominal feature element type. Ie, each element knows all the possible levels the feature can take, as in R, and as in CategoricalArrays.jl. We could use |
Much agreed, the use of a categorical data type for type-aware indexing and queries is natural. I assume this is the most widely adopted (or only available) solution in Julia?
|
Yes, I think |
To clarify, |
I have lodged a feature request at Tables.jl for a row getindex method. |
After revisiting Tables.jl (and properly reading the docs :-) ) I have concluded that this package provides us with the most we can presently expect from a generic tabular interface. I had been flirting with Query/TableTraits in MLJBase for a while, but have now switched in an upcoming PR. The impact on MLJ will, for practical purposes, be nill. |
How about overloading the
getindex
andsetindex
methods for each container we want to support to give the different containers common functionality? We can do this without interfering with the existing index methods (or, worse, wrapping the containers in a commonstruct
) as follows:Then, for example,
df[Rows, 3:7]
returns rows 3-7 ofdf
whetherdf
is aDataFrame
, a JuliaDBTable
, aMatrix
or avector
.The text was updated successfully, but these errors were encountered: