ForzaRS
ForzaRS

Reputation: 97

Defining Conflicting Modules in Julia

I am new to Julia (used with MATLAB). I am taking some datasets, cleaning it and encoding categorical variable using tools that are available in ScikitLearn then running XGBoost of the clean data.

However, I cannot make a prediction using by trained XGBoost model because both ScitkitLearn and XGBoost have a function named predict. Refer to the error message below:

WARNING: both ScikitLearn and XGBoost export "predict"; uses of it in module Main must be qualified ERROR: LoadError: UndefVarError: predict not defined

The problem is that I can not define the predict function for XGBoost as XGBoost.predict because this does not work and it seems to be the only solution that I know of.

Further, I cannot find or understand how I can load only specific modules from ScikitLearn without loading the predict function. e.g, the format import MLDataUtils.splitobs works for most packages but ScikitLearn.preprocessing does not work.

Upvotes: 3

Views: 543

Answers (1)

fredrikekre
fredrikekre

Reputation: 10984

Here is a MWE of your problem (two modules exporting the same name):

module A
    export f
    f() = println("f from A")
end
module B
    export f
    f() = println("f from B")
end

Now, consider the situation where you using both A and B and try to call f:

julia> using .A, .B

julia> f()
WARNING: both B and A export "f"; uses of it in module Main must be qualified
ERROR: UndefVarError: f not defined

The reason this fails is that Julia does not know what you mean with f; is it A.f or B.f? You can solve this problem by explicitly disambiguating the any call to f:

julia> using .A, .B

julia> A.f()
f from A

julia> B.f()
f from B

If you want to be able to call one of the functions by name alone (f) then you (the user) have to choose what f should point to. You can do this by explicitly defining that as part of the import statement:

julia> using .A, .B

julia> using .B: f # explicitly choosing f to be B.f

julia> f() # no error
f from B

julia> A.f()
f from A

julia> B.f()
f from B

Another alternative is to just explicitly define your own name f in your namespace:

julia> using .A, .B

julia> const f = B.f # defining a new name in this namespace pointing to B.f
f (generic function with 1 method)

julia> f() # no error
f from B

julia> A.f()
f from A

julia> B.f()
f from B

Upvotes: 3

Related Questions