Code Monkey home page Code Monkey logo

scikit-criteria's Introduction

Scikit-Criteria

image

Multiple-criteria decision analysis

QuatroPe Gihub Actions CI Documentation Status PyPI PyPI - Downloads Conda Forge Conda License Python 3.9+

Scikit-Criteria is a collection of Multiple-criteria decision analysis (MCDA) methods integrated into scientific python stack. Is Open source and commercially usable.

Help & discussion mailing list

Our Google Groups mailing list is here.

You can contact me at: [email protected] (if you have a support question, try the mailing list first)

Support

This project is completely free of charge and open source. If you find it useful in your work or simply want to support us, you can buy us a coffee:

"Buy Me A Coffee"

Code Repository & Issues

https://github.com/quatrope/scikit-criteria

License

Scikit-Criteria is under The 3-Clause BSD License

This license allows unlimited redistribution for any purpose as long as its copyright notices and the license's disclaimers of warranty are maintained.

Citation

If you are using Scikit-Criteria in your research, please cite:

If you use scikit-criteria in a scientific publication, we would appreciate citations to the following paper:

Cabral, Juan B., Nadia Ayelen Luczywo, and José Luis Zanazzi 2016 Scikit-Criteria: Colección de Métodos de Análisis Multi-Criterio Integrado Al Stack Científico de Python. In XLV Jornadas Argentinas de Informática E Investigación Operativa (45JAIIO)-XIV Simposio Argentino de Investigación Operativa (SIO) (Buenos Aires, 2016) Pp. 59-66. http://45jaiio.sadio.org.ar/sites/default/files/Sio-23.pdf.

Bibtex entry:

   @inproceedings{scikit-criteria,
        author={
            Juan B Cabral and Nadia Ayelen Luczywo and Jos\'{e} Luis Zanazzi},
        title={
            Scikit-Criteria: Colecci\'{o}n de m\'{e}todos de an\'{a}lisis
            multi-criterio integrado al stack cient\'{i}fico de {P}ython},
        booktitle = {
            XLV Jornadas Argentinas de Inform{\'a}tica
            e Investigaci{\'o}n Operativa (45JAIIO)-
            XIV Simposio Argentino de Investigaci\'{o}n Operativa (SIO)
            (Buenos Aires, 2016)},
        year={2016},
        pages = {59--66},
        url={http://45jaiio.sadio.org.ar/sites/default/files/Sio-23.pdf}
    }

Full Publication: http://sedici.unlp.edu.ar/handle/10915/58577

scikit-criteria's People

Contributors

audrynyonata avatar hadim avatar leliel12 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

scikit-criteria's Issues

General doubt

I am sorry, I'm new with this topic, but does this repository helps for ranking objects like a news feed?

Issue with dataset

I found a case in which nor TOPSIS nor WeightedSum would work... Here is the full code:

from skcriteria import Data, MIN, MAX
from skcriteria.madm import closeness, simple
import pandas as pd
from pandas.compat import StringIO

txt='''    SINNOUVEAU  PERTETOTAL  CHANGGARAN  SOCLOCATIO  SINISAMEDI  NOMASCONDU  SINIREPET
0            0           0           0           0           0           1          0
1            0           0           0           0           0           1          0
2            0           0           0           0           0           1          0
3            0           0           0           0           0           1          0
4            1           0           0           0           0           1          0
5            0           0           0           0           0           1          0
6            0           0           0           0           0           1          0
7            0           0           0           0           1           0          0
8            0           0           0           0           0           1          0
9            0           0           0           0           1           0          0'''
DF = pd.read_csv(StringIO(txt), sep="\s+")
strategy = [max, max, max, max, max, max, max]
weights = [1, 1, 3, 1, 1, 1, 1]
data = Data(DF.values, strategy, weights = weights, anames=DF.index.values, cnames=DF.columns)
dm = simple.WeightedSum()
decide = dm.decide(data)
print(decide)

In case of a simple dataset it works, but I tried everything with this dataframe, the rank should start from the row number 4 but in this case the rank is just an incrementation...

The only workaround I found was to add a row with only 1 values, then decide, then remove it...

SIMUS

Hello,

I am trying to use the SIMUS model, let'say I have a matrix dm

import skcriteria as skc

dm = skc.mkdm(
    matrix=[
        [7, 5, 35],
        [5, 4, 26],
        [5, 6, 28],
        [3, 4, 36],
        [1, 7, 30],
        [5, 8, 30],
    ],
    objectives=[max, max, min],
    alternatives=["PE", "JN", "AA", "FX", "MM", "FN"],
    criteria=["ROE", "CAP", "RI"],
)

dm

How I can use SIMUS?

I have tried:


from skcriteria.madm import simus
import numpy as np

#alt1
simus = simus.simus(np.array(dm), objectives=[max, max, min])
#alt2
simus = simus.simus(dm, objectives=[max, max, min])
#alt3
simus = simus.simus(dm)

They all providing an error.

thank you very much

Data cleaning

Data cleaning

  • It is understandable that some data sets have invalid values.
  • The most common invalid values are NaN, inf, and -inf but there may be cases where some finite values are invalid (debts < 0 for example).
  • It would be useful to have some kind of functionality that allows removing these invalid values.
  • values or replace them with some useful value with some heuristic.

Latest version on Pypi not compatible with setuptools

setuptools recently mandated checking for newlines: pypa/setuptools@a4b7cae

We're observing errors while installing skcriteria with setuptools:

``
10:08:12 cwd: /tmp/pip-install-6vgy8g_3/scikit-criteria_a188aa38d71246558652ef0768f8ca3b/
10:08:12 Complete output (29 lines):
10:08:12 Warning: 'classifiers' should be a list, got type 'tuple'
10:08:12 running egg_info
10:08:12 creating /tmp/pip-pip-egg-info-v0lih8ua/scikit_criteria.egg-info
10:08:12 writing /tmp/pip-pip-egg-info-v0lih8ua/scikit_criteria.egg-info/PKG-INFO
10:08:12 Traceback (most recent call last):
10:08:12 File "", line 1, in
10:08:12 File "/tmp/pip-install-6vgy8g_3/scikit-criteria_a188aa38d71246558652ef0768f8ca3b/setup.py", line 115, in
10:08:12 do_setup()
10:08:12 File "/tmp/pip-install-6vgy8g_3/scikit-criteria_a188aa38d71246558652ef0768f8ca3b/setup.py", line 103, in do_setup
10:08:12 install_requires=REQUIREMENTS,
10:08:12 File "/var/lib/jenkins/workspace/pummel_PR-148-5IDUTEJ55KBJ2X3SZN5AW6R3R7KENFHATMRIO6JRRCA2QV3Y7OFA/.nox/linter/lib/python3.7/site-packages/setuptools/init.py", line 153, in setup
10:08:12 return distutils.core.setup(**attrs)
10:08:12 File "/usr/lib/python3.7/distutils/core.py", line 148, in setup
10:08:12 dist.run_commands()
10:08:12 File "/usr/lib/python3.7/distutils/dist.py", line 966, in run_commands
10:08:12 self.run_command(cmd)
10:08:12 File "/usr/lib/python3.7/distutils/dist.py", line 985, in run_command
10:08:12 cmd_obj.run()
10:08:12 File "/var/lib/jenkins/workspace/pummel_PR-148-5IDUTEJ55KBJ2X3SZN5AW6R3R7KENFHATMRIO6JRRCA2QV3Y7OFA/.nox/linter/lib/python3.7/site-packages/setuptools/command/egg_info.py", line 292, in run
10:08:12 writer(self, ep.name, os.path.join(self.egg_info, ep.name))
10:08:12 File "/var/lib/jenkins/workspace/pummel_PR-148-5IDUTEJ55KBJ2X3SZN5AW6R3R7KENFHATMRIO6JRRCA2QV3Y7OFA/.nox/linter/lib/python3.7/site-packages/setuptools/command/egg_info.py", line 656, in write_pkg_info
10:08:12 metadata.write_pkg_info(cmd.egg_info)
10:08:12 File "/usr/lib/python3.7/distutils/dist.py", line 1117, in write_pkg_info
10:08:12 self.write_pkg_file(pkg_info)
10:08:12 File "/var/lib/jenkins/workspace/pummel_PR-148-5IDUTEJ55KBJ2X3SZN5AW6R3R7KENFHATMRIO6JRRCA2QV3Y7OFA/.nox/linter/lib/python3.7/site-packages/setuptools/dist.py", line 167, in write_pkg_file
10:08:12 write_field('Summary', single_line(self.get_description()))
10:08:12 File "/var/lib/jenkins/workspace/pummel_PR-148-5IDUTEJ55KBJ2X3SZN5AW6R3R7KENFHATMRIO6JRRCA2QV3Y7OFA/.nox/linter/lib/python3.7/site-packages/setuptools/dist.py", line 151, in single_line
10:08:12 raise ValueError('Newlines are not allowed')
10:08:12 ValueError: Newlines are not allowed```

It seems the latest release on Pypi 0.2.11 has this issue

>>> import skcriteria
>>> skcriteria.DOC
'Scikit-Criteria is a collections of algorithms, methods and\ntechniques for multiple-criteria decision analysis.\n\n'
>>> skcriteria.VERSION
'0.2.11'

whereas the current master does not:

techniques for multiple-criteria decision analysis."""

Did not understand documentation

On the Conceptual Overview page, the following like was confusing:

The criteria vector must be a 1D array-like whit the same number of elements than columns has the alternative mattrix (mtx) where every component represent the optimal sense of every criteria.

Can you please re-explain?

Reimplement ScikitCriteria with an internal framework

The idea is to design an entire framework to only define:

  • Hiper-parameters
  • Attributes
  • Input data for the decide() method
  • Output data for the decide() method
  • Remove the normalizers from the methods.
  • Make all the methods chaineables in something like
matrix_normalizer -> weight_normalizer -> decisor

Dominance

It is reasonable to implement an automatic dominance detection system.

Assuming that we have a matrix

image

We can see that the FX alternative is worse than all the others.

It is reasonable to have a transformer of the type

>>> import skcriteria as skc
>>> from skcriteria.preprocessing import dominance

>>> dm = skc.mkdm(
...     matrix=[[7, 5, 35], 
...             [5, 4, 26], 
...             [5, 6, 28], 
...             [3, 4, 36],
...             [1, 7, 30],
...             [5, 8, 30]],
...     objectives=[max, max, min],
...     weights=[2, 4, 1],
...     alternatives=["PE", "JN", "AA", "FX", "MM", "FN"],
...     criteria=["ROE", "CAP", "RI"]
...  )

>>> trans = dominance.RemoveDominated()
>>> dmt = trans.transform(dm)

This must result in the matrix

>>> dmt
   ROE[▲ 2.0] CAP[▲ 4.0] RI[▼ 1.0]
PE          7          5        35
JN          5          4        26
AA          5          6        28
MM          1          7        30
FN          5          8        30
[5 Alternatives x 3 Criteria]

Bibliography

Satisfation Analysis

Let us assume that we have the matrix

>>> dm = skc.mkdm(
...     matrix=[[7, 5, 35],
...             [5, 4, 26],
...             [5, 6, 28],
...             [1, 7, 30],
...             [5, 8, 30]],
...     objectives=[max, max, min],
...     weights=[2, 4, 1],
...     alternatives=["PE", "JN", "AA", "MM", "FN"],
...     criteria=["ROE", "CAP", "RI"]
...   )
>>> dm
   ROE[▲ 2.0] CAP[▲ 4.0] RI[▼ 1.0]
PE          7          5        35
JN          5          4        26
AA          5          6        28
MM          1          7        30
FN          5          8        30
[5 Alternatives x 3 Criteria]

On the other hand, let us assume that only alternatives that ROE > 2% will be accepted.

So MM must be deleted

>>> from skcriteria.preprocessing import filters

>>> trans = filters.FilterGT(ROE=1)
>>> trans.transform(dm)
   ROE[▲ 2.0] CAP[▲ 4.0] RI[▼ 1.0]
PE          7          5        35
JN          5          4        26
AA          5          6        28
FN          5          8        30
[4 Alternatives x 3 Criteria]

so the transformer trans will remove any alternative that the criteria ROE are GT (greater than/>=) than 1.

If the user provides a decision matrix without a criteria ROE a ValueError must be raised.

Finally, the total number of filter must be 7:

  1. FilterLE: Filter an alternative if a value of any criteria is <= than a threshold.
  2. FilterLT: Filter an alternative if a value of any criteria is < than a threshold.
  3. FilterGE: Filter an alternative if a value of any criteria is >= than a threshold.
  4. FilterGT: Filter an alternative if a value of any criteria is > than a threshold.
  5. FilterEQ: Filter an alternative if a value of any criteria is == than a threshold.
  6. FilterNE: Filter an alternative if a value of any criteria is != than a threshold.
  7. Filter: Filter an alternative if a value of any criteria is returned false when a filter function is called.

Notes

All the filters accept criteria names as hyperparameters and their threshold. For example

FilterGT(CRITERIA_NAME=THRESHOLD)

The only exception is the Filter class that accepts a callable instead of a threshold. For example, if you want to only accept values of RI between 10, 20:

Filter(ROE=lambda v: v > 10 and v < 20)

Extract TOPSIS rankings?

I am trying to use the topsis ranking function rank = dm.decide(TOPSISdata)and it makes a nice output but it doesnt yield anything useful beyond this, I want to store the output of the rank as an array or ultimately a dataframe but it's not seemingly possible.

We tried to use dm.solve(TOPSISdata) but it does not put it in the right order

Any thoughts?

website down?

When navigating to: http://scikit-criteria.org/ the page cannot be loaded. Is this expected? Can we get a version going even if it the a zip of the public folder in uploaded to this repo.

pulp module missing solvers

Tried installing scikit-criteria on Debian 10 using pip install scikit-criteria and everything works just perfect until I try to import SIMUS class using from skcriteria.madm.simus import SIMUS

I get an attribution error: AttributeError: module 'pulp' has no attribute 'solvers'
I am running Python 3.8 and I have tried.

The developers of pulp noticed the problem and advised as follows: See https://github.com/coin-or/pulp/issues/286

  1. They use a correct but not standard reference (pulp.solvers.SOME_SOLVER) when it should have been pulp.SOME_SOLVER.
  2. We have now changed the files format, so the absolute reference should be pulp.apis.SOME_SOLVE. Nevertheless, pulp.SOME_SOLVER still works and should be encouraged.

As a fix, you could try opening an issue in their github so they take out the "solvers" part and leave it with pulp.SOME_SOLVER.

Could you please fix this?

Internal Model creation framework

The authors have prototyped in different projects frameworks for the creation of models with hyperparameters Garpar, GalaxyChop; All of them built on Attrs.

La idea es definir los modelos de una forma mas semantica como

from model_framework as mfk

class Model(mfk.ModelABC):
    x = mfk.hparam(default="foo")
    kwargs = mfk.hparam_kwargs()

    prop = mfk.mproperty()

Esto puede ser usado de la forma

>>> m = Model(x=2, z=1)
>>> m
Model(x=2, kwargs={"z": 1})
>>> m.prop
None

Where:

  • ModelABC has as their metaclass abc.ABCMeta. Its also support to define abstractmethods.
  • hparam is a shortcut to attr.ib(init=True) and alwas has a default.
  • hparam_kwargs adds the variable keyword argument to the class initialization and is always init=True and can't have a default.
  • mproperty is a model property and always have an init=False

Tutorial: Weights

Implement a tutorial on how to use the different methods for calculating weights

Descriptive statistics

It would be interesting to be able to access descriptive statistics per view by pandas.Dataframe.

Currently only dm.describe() and are implemented, it would be more reasonable to move all statistics to a new accessor
stats.

Te proposed statistics are

  • dm.stats.corr()
  • dm.stats.cov()
  • dm.stats.describe()
  • dm.stats.kurtosis()
  • dm.stats.mad()
  • dm.stats.max()
  • dm.stats.mean()
  • dm.stats.median()
  • dm.stats.min()
  • dm.stats.pct_change()
  • dm.stats.quantile()
  • dm.stats.sem()
  • dm.stats.skew()
  • dm.stats.std()
  • dm.stats.var()

finally call dm.describe() must be deprecated

Add mnorm and wnorm keyword to all mcda method.

  • Add mnorm and wnorm keyword for every mcda function method with a default value.
  • Also need provide a default value for this parameter

Example

from skcriteria import norm

def method(mtx, criteria, weights=None, mnorm=norm.vector, wnorm=norm.sum...):
     nmtx = mnorm(mtx)
     nweights = wnorm(weights) if weights is not None else 1
     ...

Failing tests on win-64

There are failing tests on windows:

               INFO   FAILED tests/agg/test_moora.py::test_ReferencePointMOORA_kracka2010ranking - ... 
               INFO   FAILED tests/agg/test_moora.py::test_FullMultiplicativeForm_kracka2010ranking
               INFO   FAILED tests/agg/test_moora.py::test_FullMultiplicativeForm_only_minimize - a... 
               INFO   FAILED tests/agg/test_moora.py::test_FullMultiplicativeForm_only_maximize - a...
               INFO   FAILED tests/agg/test_moora.py::test_MultiMOORA_kracka2010ranking - assert False
               INFO   FAILED tests/agg/test_similarity.py::test_TOPSIS - assert False
               INFO   FAILED tests/agg/test_similarity.py::test_TOPSIS_tzeng2011multiple - assert F...
               INFO   FAILED tests/agg/test_simple.py::test_WeightedSumModel - assert False
               INFO   FAILED tests/agg/test_simple.py::test_WeightedSumModel_kracka2010ranking - as...
               INFO   FAILED tests/agg/test_simple.py::test_WeightedProductModel - assert False
               INFO   FAILED tests/agg/test_simple.py::test_WeightedProductModel_enwiki_1015567716
               INFO   FAILED tests/agg/test_simus.py::test_SIMUS_munier24metodo - assert False
               INFO   FAILED tests/core/test_dominance.py::test_DecisionMatrixDominanceAccessor_compare

These are failing due to following line

assert result.values_equals(expected)

This is because result and expected, which are of type DecisionMatrix and RankResult respectively, rely on pandas.DataFrame which is known to default to int32 values on windows as opposed to int64 when dealing with integer values. This issue is also discussed here.

Can you please fix the tests so that the dtype is enforced on DecisionMatrix?

PulpSolverError

I am following the SIMUS solvers and three of them are unavailable
git+https://github.com/leliel12/scikit-criteria.git@1ca7667e08e79d551f8241278c939f604800d81b

dm = SIMUS(solver='glpk')
PulpSolverError: PuLP: cannot execute glpsol


dm = SIMUS(solver='gurobi')
PulpSolverError: GUROBI: Not Available


dm = SIMUS(solver='cplex')
PulpSolverError: PuLP: cannot execute cplex

register normalizers

create a functionality to call normalizers by their name

from skcriteria import norm
assert norm.normalize("vector", [10, 20, 70]) == norm.vector([10, 20, 70])

What is `b`?

SIMUS

At first it is one column call Right side value
image

Later on it is b and then you put it in b argument
image

Questions

  1. What is Right side value?
  2. What is b?
  3. Can set b equal to list of None?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.