unifying the ecosystem around observations-as-row convention
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 20/100
Direzione di ricerca
Inizia facendo un inventario degli entry point di MultivariateStats che attualmente richiedono input trasposto, incluso l’esempio PCA nella documentazione, e confronta le loro convenzioni con le funzioni di Statistics come cov e cor. Definisci l’ambito della migrazione attorno a una parola chiave dims esplicita e determina quali API devono cambiare prima che le osservazioni come righe diventino il comportamento predefinito.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
In statistical analysis, e.g. with DataFrames.jl, it is a convention that columns equal variables, rows equal observations. The same is true for the entire R analytical ecosystem (statistics + machine learning) + the entire Python analytical ecosystem (stats + machine learning) + matlab. I believe it is also the case in most cases in the rest of the Julia ecosystem. For DataFrames this is the only obvious choice, as the same observation (row) can contain multiple types; and given that different columns can have different types, observations-are-rows is the only feasible way. Not true for Matrixes, which are the same type in both directions, so in principle columns can be interpreted as observations for Matrices.
In some parts of the Julia ecosystem that are built only for Matrix{<:Number}, that is actually done - the convention is flipped. This is true for the kmeans algorithm in Clustering (https://github.com/JuliaStats/Clustering.jl/issues/79), and for NearestNeighbours. It also used to be the case for standardize in StatsBase and for Distances, but a deprecation has just been added requiring an explicit dims argument (e.g. https://github.com/JuliaStats/StatsBase.jl/pull/490/files), which is the first step towards remedying this. And, it is also the case here in MultivariateStats - e.g. you'll need to transpose the data if you get them from a DataFrame, in order to do a PCA on them.
On the other hand, the stdlib Statistics (e.g. functions cov and cor), StatsModels, GLM, MixedModels, Plots, the MLJ machine learning library, and Turing all use the more widely accepted standard of observations-as-rows.
I think we should standardize on using the same convention across the ecosystem, and preferably the same standard as everyone else. The main arguments against has been 1) that Machine-learning often uses columns-as-observations, and 2) that because Julia is column-major, analyses of all variables for an observation should be faster.
Ad 1), I'd like to question that assertion - most machine-learning frameworks I know of uses rows-are-observations (or indeed DataFrames). A notable exception appears to be Flux, which looks like it is columns-are-observations, AFAICS.
Ad 2) I have some other concerns:
- Column-major is an implementation detail, that shouldn't define the API. Especially as the fastest implementation will differ depending on what type of analysis you're using, but a mixture of rows or columns as observations is a really dangerous footgun for introducing bugs.
- Often rows-as-observations is likely to be fastest, as many analyses focus on each variable individually.
- If most users get their data from DataFrames anyway, like in the very example used for PCA in the docs for MultivariateStats, the user is likely to transpose, and the algorithm will work on a lazy adjoint - losing the entire value of column-major memory layout. So most users will only experience the inconvenience but not harvest the performance benefits. Instead, with observations-as-rows, algorithms can be optimised for that; and in cases where they can't be, superusers that want max performance can make their object with observations-as-columns, then lazy transpose before passing in; if I'm not much mistaken these users would then still reap the performance gains.
I believe an added advantage is to improve the JuliaStats ecosystem combatability with Tables. The approach I'd suggest would be to require a dims keyword across all functions for at least 1 julia minor version, then flip the default, to make all code calling these functions deprecate noisily.
cc @nalimilan @andreasnoack @ararslan @tsela
- Lingua principale
- Julia
- Stelle
- 387
- Fork
- 83
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di JuliaStats/MultivariateStats.jl
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
tagbot-manual
Difficoltà 2/5 1-3 ore Idoneità per principianti 35/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 35/100
JuliaStats/MultivariateStats.jl#238 · 1 commento ·
-
Return a result even when MetricMDS does not convergeForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
JuliaStats/MultivariateStats.jl#233 · 1 commento ·
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 30/100
Tutte le issue di JuliaStats/MultivariateStats.jl
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
oscar-system/GAP.jl#1455 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
JuliaAI/MLJTransforms.jl#85 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
SciML/OrdinaryDiffEq.jl#4875 ·
I maintainer di solito rispondono entro 4 giorni
-
documentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
SciML/NonlinearSolve.jl#1372 ·
I maintainer di solito rispondono entro 1 giorno