JuliaStats / MultivariateStats.jl

A Julia package for multivariate statistics and data analysis (e.g. dimension reduction)
Other
379 stars 86 forks source link

Inferred `outdim` for ICA sometimes fails but without an informative explanation #224

Open ablaom opened 10 months ago

ablaom commented 10 months ago

The following works fine if outdim=0 is replaced with outdim=3. A more informative error message would be helpful, unless a better inference of outdim is more appropriate.

Sorry this is through the MLJ interface.

using MLJBase, MLJModels

ICA = @load ICA pkg=MultivariateStats

times = range(0, 8, length=2000)

sine_wave = sin.(2*times)
square_wave = sign.(sin.(3*times))
sawtooth_wave = map(t -> mod(2t, 2) - 1, times)
signals = hcat(sine_wave, square_wave, sawtooth_wave)
noisy_signals = signals + 0.2*randn(size(signals))

mixing_matrix = [ 1 1 1; 0.5 2 1; 1.5 1 2]
X = MLJ.table(noisy_signals*mixing_matrix)

model = ICA(outdim = 0, tol=0.1)
mach = machine(model, X) |> fit!

ERROR: MethodError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
Stacktrace:
  [1] mapreduce_empty
    @ ./reduce.jl:372
  [2] reduce_empty(op::Base.MappingRF{typeof(identity), typeof(max)}, ::Type{Float64})
    @ Base ./reduce.jl:361
  [3] reduce_empty_iter
    @ ./reduce.jl:384 [inlined]
  [4] mapreduce_empty_iter(f::Function, op::Function, itr::Vector{Float64}, ItrEltype::Base.HasEltype)                                                                             
    @ Base ./reduce.jl:380
  [5] _mapreduce(f::typeof(identity), op::typeof(max), ::IndexLinear, A::Vector{Float64})
    @ Base ./reduce.jl:432
  [6] _mapreduce_dim
    @ ./reducedim.jl:365 [inlined]
  [7] mapreduce
    @ ./reducedim.jl:357 [inlined]
  [8] _maximum
    @ ./reducedim.jl:1015 [inlined]
  [9] _maximum
    @ ./reducedim.jl:1014 [inlined]
 [10] maximum
    @ ./reducedim.jl:1010 [inlined]
 [11] fastica!(W::Matrix{Float64}, X::Matrix{Float64}, fun::MultivariateStats.Tanh{Float64}, maxiter::Int64, tol::Float64)                                                             
    @ MultivariateStats ~/.julia/packages/MultivariateStats/F3eLE/src/ica.jl:171
 [12] fit(::Type{…}, X::LinearAlgebra.Adjoint{…}, k::Int64; alg::Symbol, fun::MultivariateStats.Tanh{…}, do_whiten::Bool, maxiter::Int64, tol::Float64, mean::Nothing, winit::Matrix{…})
    @ MultivariateStats ~/.julia/packages/MultivariateStats/F3eLE/src/ica.jl:250
 [13] fit(model::MLJMultivariateStatsInterface.ICA, verbosity::Int64, X::Tables.MatrixTable{Matrix{Float64}})                                                                          
    @ MLJMultivariateStatsInterface ~/.julia/packages/MLJMultivariateStatsInterface/VOkse/src/models/decomposition_models.jl:123
 [14] fit_only!(mach::Machine{…}; rows::Nothing, verbosity::Int64, force::Bool, composite::Nothing)                                                                                    
    @ MLJBase ~/.julia/packages/MLJBase/fEiP2/src/machines.jl:680
 [15] fit_only!
    @ MLJBase ~/.julia/packages/MLJBase/fEiP2/src/machines.jl:606 [inlined]
 [16] #fit!#63
    @ MLJBase ~/.julia/packages/MLJBase/fEiP2/src/machines.jl:777 [inlined]
 [17] fit!
    @ MLJBase ~/.julia/packages/MLJBase/fEiP2/src/machines.jl:774 [inlined]
 [18] |>(x::Machine{MLJMultivariateStatsInterface.ICA, true}, f::typeof(fit!))
    @ Base ./operators.jl:917
 [19] top-level scope
    @ REPL[206]:1
Some type information was truncated. Use `show(err)` to see complete types.