Skip to content
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

Add option to use JMcDM functions in ADRIA site selection #348

Merged
merged 35 commits into from
May 24, 2023

Conversation

Rosejoycrocker
Copy link
Collaborator

Adds option to use either native ADRIA mcda aggregation functions or one of 18 available methods from the JMcDM package. Also adds function retrieve_ranks to allow transitioning between JMcDM methods and ADRIA methods while running ADRIA.

Closes #242

@Rosejoycrocker Rosejoycrocker added the enhancement New feature or request label May 17, 2023
@Rosejoycrocker
Copy link
Collaborator Author

Note: I have also reverted the wave_stress criteria normalisation back to min-max as the max normalisation was giving such a small range of values, everything was getting filtered out during testing. This is just a placeholder for whatever we decide to do with this.

Copy link
Collaborator

@ConnectedSystems ConnectedSystems left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Rose, much tidier well done.

This is a partial review, will continue on tomorrow.

- `weights` : importance weights for each criteria.
- `mcda_func` : function/[function bool] array to use for mcda, specified as an element from method.
- `site_ids` : array of site ids still remaining after filtering.
- `scores` : set of scores derived from applying an mcda ranking method.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Orphaned arguments in argument list?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which one?

Copy link
Collaborator

@ConnectedSystems ConnectedSystems May 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please read the argument list and then compare with the function signatures given at the top, and the function signature that is implemented.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List of functions in docstring still doesn't match implementations?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rosejoycrocker I guess you did update them but they're still incorrect.

Corrected, and changed rev_val to maximize as the latter is more intuitive.

src/sites/dMCDA.jl Outdated Show resolved Hide resolved
src/sites/dMCDA.jl Show resolved Hide resolved
src/sites/dMCDA.jl Outdated Show resolved Hide resolved
src/sites/dMCDA.jl Outdated Show resolved Hide resolved
end
function retrieve_ranks(S::Matrix, scores::Vector, rev_val::Bool, site_ids::Vector)

s_order = Union{Float64,Int64}[Int.(site_ids) scores 1:size(S, 1)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use concrete types where possible please: Int ->Int64

And you can consolidate this line with Line 243 to avoid reallocations.

using JMcDM
using ADRIA: order_ranking, adria_vikor, adria_topsis

global method = [
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Globals are bad! Mark this a const for the module please.

Also, isn't there a way of getting a list of available methods from JMcDM?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The list of available methods wasn't working for me when I tried previously. I just tried again and it's working now, so I'll add it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, sorry I remember now why I used the global (which I can replace with a constant), it's because I needed to add something which indicates whether the method gives best sites as the highest score or lowest score (I add a Boolean next to the method) and I wasn't sure how to do this without manually looking at the docs for the method and working it out. I'll have a look again and see if there is something which indicates but otherwise not sure how to replace.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So looks like the results struture also has a "best index" field, so I can add somethng which checks whether the best index is equal to the max or min score and order the sites accordingly :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think the reason the list of JMcDM functions wasn't working for me before is it uses the subtypes() function (in subtypes(MCDMMethod)) which is automatically loaded in interactive mode but doesn't seem to be loaded when running ADRIA. Due to this it throws an error saying it can't find the subtypes() function. Is it ok to include the InteractiveUtils module in dMCDA or is this not a good idea? If so, is there a way to just load one function from the module?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, I've also tried methods(mcda_func)[1] to extract the method but because it's a general method and the mcda function requires a JMcDM.MCDMMethod type it errors.

Copy link
Collaborator

@ConnectedSystems ConnectedSystems May 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/open-AIMS/ADRIA.jl/blob/ea5762f5b1f050a1f031ef9a538acb3741237329/src/sites/dMCDA.jl#L222C10-L229

That's what you want.

Note that the Promethee method errors because the constructor for it expects additional arguments.
There may be others like it.

Not sure what you want to do with these methods.

Also note the docstring for retrieve_ranks is now out of date.

ERROR: MethodError: no method matching JMcDM.PROMETHEE.PrometheeMethod()

Closest candidates are:
  JMcDM.PROMETHEE.PrometheeMethod(::Vector{<:Function}, ::Vector{Float64}, ::Vector{Float64})
   @ JMcDM C:\Users\takuy\.julia\packages\JMcDM\Oo88a\src\promethee.jl:22                                                                                                                                                                                                                 |  ETA: 0:00:04        
  JMcDM.PROMETHEE.PrometheeMethod(::Vector{Function}, ::Vector{Union{Nothing, Float64}}, ::Vector{Union{Nothing, Float64}})
   @ JMcDM C:\Users\takuy\.julia\packages\JMcDM\Oo88a\src\promethee.jl:13
  JMcDM.PROMETHEE.PrometheeMethod(::Any, ::Any, ::Any)
   @ JMcDM C:\Users\takuy\.julia\packages\JMcDM\Oo88a\src\promethee.jl:13

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah man, brackets is all it needed :( ...
Promethee should be in the list of excluded methods because of this- it's more complicated because you get 2 scores are output and based on these you decide whether to have a single or multiple "best choice". I'll add it to the list. The others which I've added should be the only methods which are exceptions, I looked through all th docs to catch any which have non-standard outputs.

I'll update the docstring.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did say to call the constructor...

#348 (comment)

Copy link
Collaborator Author

@Rosejoycrocker Rosejoycrocker May 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't realise that's what you meant by your example, I thought you were just referring to the datatype of the inputs because you referred to multiple dispatch

@Rosejoycrocker
Copy link
Collaborator Author

Hey @ConnectedSystems I think I've resolved your requested changes now. Let me know if there is anything else. I haven't changed S to be a NamedDims+AxisKeys array because this was a planned change for when replacing mcda_vars which I will do in another PR

@ConnectedSystems
Copy link
Collaborator

Thanks, will have a look this afternoon

order_ranking,
adria_vikor,
adria_topsis,
setdiff(jmcdm_methods, jmcdm_ignore)...
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI @Rosejoycrocker thought of a cleaner way to ignore unwanted methods.

- `weights` : importance weights for each criteria.
- `mcda_func` : function/[function bool] array to use for mcda, specified as an element from method.
- `site_ids` : array of site ids still remaining after filtering.
- `scores` : set of scores derived from applying an mcda ranking method.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List of functions in docstring still doesn't match implementations?

Q .= 1.0 .- Q # Invert rankings so higher values = higher rank

return Q
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to add an empty line at the very end to stop the linter from complaining

(I'll explain why leaving an empty line at the end is a common convention in programming later).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, missed this when copying and pasting

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List of functions in docstring still doesn't match implementations?

I thought I did this in commit e5ea28 , called "Change order of doc input values to match order"... maybe it got overwritten when merged with Main?

@@ -3,6 +3,10 @@
using StatsBase
using Distances
using Combinatorics
using JMcDM
using InteractiveUtils: subtypes
using ADRIA: order_ranking, adria_vikor, adria_topsis
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick question - was the adria_ prefix necessary?

Looks a bit tacky in the sense that none of the other methods have the prefix.
At first glance it doesn't seem like vikor or topsis would have resulted in a clash with JMcDM functions, so wondering if we can save the extra keypresses.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally didn't have the prefix but JMcDM seems to have wrapping functions for the vikor and topsis methods so instead of mcda(A,weights, method()) you can do vikor(A,weights) etc... so I had to have something different

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. I still think it looks a bit clunky but leave it as is. It'll be removed in the future if you contribute changes to JMcDM anyway.

Copy link
Collaborator

@ConnectedSystems ConnectedSystems left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR Rose!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consider using JMcDM
2 participants