Skip to main content

Library for Multi-criteria Decision Aid Methods

Project description

scikit-mcda

It is a python library made to provide multi-criteria decision aid for developers and operacional researchers.

Scikit-mcda provides an easy way to apply several popular decision-making methods. It can be used as part of your development or for analytical experiments using notebooks like Jupyter, colab or kaggle. The package is available on the Pypi allowing installation by pip install scikit-mcda command.

Some methods available:

DMUU

  • laplace, hurwicz, maximax, maximin, minimax-regret ...

MCDA

  • Weighted Sum Model (WSM), Weighted Product Model (WPM) , Weighted Aggregated Sum Product Assessment (WASPAS), Technique for Order Preference by Similarity to an Ideal Solution (TOPSIS), Preference Ranking Organization METHod for Enrichment of Evaluations (PROMETHEE II), ELimination Et Choix Traduisant la REalité (ELECTRE I), Višekriterijumska Optimizacija I Kompromisno Rješenje (VIKOR) ...

Definition of criteria weights

  • Manually, Entropy, Ranking Methods, Analytic Hierarchy Process (AHP) ...

Nomalization

  • Linear MinMax, Linear Max, Linear Sum, Vector, Enhanced Accuracy and Logarithmic.

Scikit-mcda is free to use for personal, commercial and academic projects, always respecting the terms of the Apache 2.0 License. Do not forget to refer to this Library when it is used in your experiments, lectures, presentations, classes and research papers. The reference must follow this citation format.

(HORTA, 2021)

HORTA, Antonio (2021). Scikit-mcda: The Python library for multi-criteria decision aid. 
Version 0.21. [opensource], 17 jan. 2021. Available in: https://gitlab.com/cybercrafter/scikit-mcda. 
Acessed in: 17 jan. 2021.

It's a project made by Cybercrafter® ajhorta@cybercrafter.com.br

Module for Multi-Criteria Decision Aid (MCDA)

MCDA: Basis Class Module for Multi-Criteria Decision-Aid

Attributes:

  • df_original
  • weights
  • signals
  • df_normalized
  • df_weighted
  • df_decision

MCDA basis methods:

  • dataframe(alt_data, alt_labels=[], state_labels=[])
  • set_signals([MIN, MIN, MAX])

MCDA weights determination methods:

  • set_weights_manually([])
  • set_weights_by_entropy(normalization_method_for_entropy=LinearSum_)
  • set_weights_by_ranking_A()
  • set_weights_by_ranking_B()
  • set_weights_by_ranking_B_POW(default=0)
  • set_weights_by_ranking_C()
  • set_weights_by_AHP(saaty_preference_matrix)

Ranking methods A, B, B_POW and C need criteria ordered by importance C1> c2> C3 ...

Properties

  • pretty_original(tablefmt='psql')
  • pretty_normalized(tablefmt='psql')
  • pretty_weighted(tablefmt='psql')
  • pretty_decision(tablefmt='psql')

tablefmt: "psql" or "latex" or "html"

Classes for Decision-Making:

  • Class WSM: decide(normalization_method=None)
  • Class WPM: decide(normalization_method=None)
  • Class WASPAS: decide(lambda=0.5, normalization_method=None)
  • Class TOPSIS: decide(normalization_method=TopsisOriginal_)
  • Class PROMETHEE_II: decide(normalization_method=LinearMinMax_)
  • Class ELECTRE_I: decide(normalization_method=None)
  • Class VIKOR: decide()

Normalization constants: LinearMinMax_, LinearMax_, LinearSum_, Vector_, EnhancedAccuracy_ and Logarithmic_

# Use help(<class_name>) to list all attributes and methods of classes 
# e.g.

help(ELECTRE_I)

Quick Start for MCDA

from scikitmcda.topsis import TOPSIS
from scikitmcda.wsm import WSM
from scikitmcda.wpm import WPM
from scikitmcda.waspas import WASPAS
from scikitmcda.promethee_ii import PROMETHEE_II
from scikitmcda.electre_i import ELECTRE_I
from scikitmcda.vikor import VIKOR
from scikitmcda.constants import MAX, MIN, LinearMinMax_, LinearMax_, LinearSum_, Vector_, EnhancedAccuracy_, Logarithmic_ 

# Example for TOPSIS

topsis = TOPSIS()

topsis.dataframe([[250, 16, 12, 5],
                  [200, 16,  8, 3],
                  [300, 32, 16, 4],
                  [275, 32,  8, 4],
                  [225, 16,  16, 2]],
                 ["Mobile 1", "Mobile 2", "Mobile 3", "Mobile 4", "Mobile 5"],
                 ["COST", "STORAGE", "CAMERA", "DESIGN"]
                 )
print(topsis.pretty_original())

+----+----------------+--------+-----------+----------+----------+
|    | alternatives   |   COST |   STORAGE |   CAMERA |   DESIGN |
|----+----------------+--------+-----------+----------+----------|
|  0 | Mobile 1       |    250 |        16 |       12 |        5 |
|  1 | Mobile 2       |    200 |        16 |        8 |        3 |
|  2 | Mobile 3       |    300 |        32 |       16 |        4 |
|  3 | Mobile 4       |    275 |        32 |        8 |        4 |
|  4 | Mobile 5       |    225 |        16 |       16 |        2 |
+----+----------------+--------+-----------+----------+----------+

# topsis.set_weights_manually([0.5918, 0.2394, 0.1151, 0.0537])
# topsis.set_weights_by_entropy()
# topsis.set_weights_by_ranking_B_POW(0)

                                   # C1   C2     C3   C4 
w_AHP = topsis.set_weights_by_AHP([[  1,    4,    5,   7],   # C1
                                   [1/4,    1,    3,   5],   # C2
                                   [1/5,  1/3,    1,   3],   # C3
                                   [1/7,  1/5,  1/3,   1]])  # C4
print("AHP Returned:\n", w_AHP)
topsis.set_signals([MIN, MAX, MAX, MAX])

AHP Returned:
{'consistency': True, 'lambda': 4.17992665646019, 'CIndex': 0.05997555215339675, 'CRatio': 0.06663950239266306}

topsis.decide()

print("WEIGHTS:\n", topsis.weights)

WEIGHTS:
[0.5809771356405764, 0.2429005339101441, 0.12011108977871769, 0.056011240670561804]

print("NORMALIZED:\n", topsis.pretty_normalized())

NORMALIZED:
+----+----------------+----------+-----------+----------+----------+
|    | alternatives   |     COST |   STORAGE |   CAMERA |   DESIGN |
|----+----------------+----------+-----------+----------+----------|
|  0 | Mobile 1       | 0.442807 |  0.301511 | 0.428571 | 0.597614 |
|  1 | Mobile 2       | 0.354246 |  0.301511 | 0.285714 | 0.358569 |
|  2 | Mobile 3       | 0.531369 |  0.603023 | 0.571429 | 0.478091 |
|  3 | Mobile 4       | 0.487088 |  0.603023 | 0.285714 | 0.478091 |
|  4 | Mobile 5       | 0.398527 |  0.301511 | 0.571429 | 0.239046 |
+----+----------------+----------+-----------+----------+----------+

print("WEIGHTED:\n", topsis.pretty_weighted())

WEIGHTED:
+----+----------------+----------+-----------+-----------+-----------+
|    | alternatives   |     COST |   STORAGE |    CAMERA |    DESIGN |
|----+----------------+----------+-----------+-----------+-----------|
|  0 | Mobile 1       | 0.257261 | 0.0732373 | 0.0514762 | 0.0334731 |
|  1 | Mobile 2       | 0.205809 | 0.0732373 | 0.0343175 | 0.0200839 |
|  2 | Mobile 3       | 0.308713 | 0.146475  | 0.0686349 | 0.0267785 |
|  3 | Mobile 4       | 0.282987 | 0.146475  | 0.0343175 | 0.0267785 |
|  4 | Mobile 5       | 0.231535 | 0.0732373 | 0.0686349 | 0.0133892 |
+----+----------------+----------+-----------+-----------+-----------+

print("RANKING TOPSIS with", topsis.normalization_method , ":\n", topsis.pretty_decision())

RANKING TOPSIS with Vector :
+----+----------------+---------------------+--------+
|    | alternatives   |   performance score |   rank |
|----+----------------+---------------------+--------|
|  0 | Mobile 2       |            0.55711  |      1 |
|  1 | Mobile 5       |            0.513009 |      2 |
|  2 | Mobile 4       |            0.481779 |      3 |
|  3 | Mobile 3       |            0.44289  |      4 |
|  4 | Mobile 1       |            0.388243 |      5 |
+----+----------------+---------------------+--------+

topsis.decide(EnhancedAccuracy_)
print("RANKING TOPSIS with", topsis.normalization_method, ":\n", topsis.pretty_decision())

RANKING TOPSIS with EnhancedAccuracy :
+----+----------------+---------------------+--------+
|    | alternatives   |   performance score |   rank |
|----+----------------+---------------------+--------|
|  0 | Mobile 2       |            0.70887  |      1 |
|  1 | Mobile 5       |            0.638174 |      2 |
|  2 | Mobile 1       |            0.457331 |      3 |
|  3 | Mobile 4       |            0.358036 |      4 |
|  4 | Mobile 3       |            0.29113  |      5 |
+----+----------------+---------------------+--------+

Module for Decision-making Under Uncertainty (DMUU)

DMUU: Class Module for Decision-making Under Uncertainty

Attributes:

df_original = DataFrame
df_calc = DataFrame
decision = {"alternative":,
            "index":,
            "value": ,
            "criteria": ,
            "result": ,
            "type_dm": "DMUU",
            "hurwicz_coeficient":}

Criteria Methods:

  • maximax()
  • maximin()
  • laplace()
  • minimax_regret()
  • hurwicz(coef)

Properties

  • pretty_original(tablefmt='psql')
  • pretty_calc(tablefmt='psql')
  • pretty_decision(tablefmt='psql')

tablefmt: "psql" or "latex" or "html"

Methods:

  • dataframe(alt_data, alt_labels=[], state_labels=[])
  • decision_making(dmuu_criteria_list=[])

Quick Start for DMUU

from scikitmcda.dmuu import DMUU

# Defining labels for Alternatives and States")

dmuu = DMUU()

dmuu.dataframe([[5000, 2000, 100],
                [50, 50, 500]],
                ["ALT_A", "ALT_B"],
                ["STATE A", "STATE B", "STATE C"]
                )

print(dmuu.pretty_original())
+----+----------------+-----------+-----------+-----------+
|    | alternatives   |   STATE A |   STATE B |   STATE C |
|----+----------------+-----------+-----------+-----------|
|  0 | ALT_A          |      5000 |      2000 |       100 |
|  1 | ALT_B          |        50 |        50 |       500 |
+----+----------------+-----------+-----------+-----------+

# Specifying the criteria method

dmuu.minimax_regret()

print(dmuu.pretty_calc())
+----+----------------+-----------+-----------+-----------+------------------+
|    | alternatives   |   STATE A |   STATE B |   STATE C | minimax-regret   |
|----+----------------+-----------+-----------+-----------+------------------|
|  0 | ALT_A          |      5000 |      2000 |       100 | (400, 1)         |
|  1 | ALT_B          |        50 |        50 |       500 | (4950, 0)        |
+----+----------------+-----------+-----------+-----------+------------------+

print(dmuu.pretty_decision())
+---------------+---------+---------+----------------+-------------------------------+-----------+----------------------+
| alternative   |   index |   value | criteria       | result                        | type_dm   | hurwicz_coeficient   |
|---------------+---------+---------+----------------+-------------------------------+-----------+----------------------|
| ALT_A         |       0 |     400 | minimax-regret | {'ALT_A': 400, 'ALT_B': 4950} | DMUU      |                      |
+---------------+---------+---------+----------------+-------------------------------+-----------+----------------------+

# Many crietria methods

dmuu.decision_making([dmuu.maximax(), dmuu.maximin(), dmuu.hurwicz(0.8), dmuu.minimax_regret()])

print(dmuu.pretty_calc())
+----+----------------+-----------+-----------+-----------+------------------+-----------+-----------+------------------+
|    | alternatives   |   STATE A |   STATE B |   STATE C | minimax-regret   | maximax   | maximin   | hurwicz          |
|----+----------------+-----------+-----------+-----------+------------------+-----------+-----------+------------------|
|  0 | ALT_A          |      5000 |      2000 |       100 | (400, 1)         | (5000, 1) | (100, 1)  | (4020.0, 1, 0.8) |
|  1 | ALT_B          |        50 |        50 |       500 | (4950, 0)        | (500, 0)  | (50, 0)   | (410.0, 0, 0.8)  |
+----+----------------+-----------+-----------+-----------+------------------+-----------+-----------+------------------+

print(dmuu.pretty_decision())
+---------------+---------+---------+----------------+-----------------------------------+-----------+----------------------+
| alternative   |   index |   value | criteria       | result                            | type_dm   | hurwicz_coeficient   |
|---------------+---------+---------+----------------+-----------------------------------+-----------+----------------------|
| ALT_A         |       0 |    5000 | maximax        | {'ALT_A': 5000, 'ALT_B': 500}     | DMUU      |                      |
| ALT_A         |       0 |     100 | maximin        | {'ALT_A': 100, 'ALT_B': 50}       | DMUU      |                      |
| ALT_A         |       0 |    4020 | hurwicz        | {'ALT_A': 4020.0, 'ALT_B': 410.0} | DMUU      | 0.8                  |
| ALT_A         |       0 |     400 | minimax-regret | {'ALT_A': 400, 'ALT_B': 4950}     | DMUU      |                      |
+---------------+---------+---------+----------------+-----------------------------------+-----------+----------------------+

dmuu.calc_clean()
print(dmuu.pretty_calc())
+----+----------------+-----------+-----------+-----------+
|    | alternatives   |   STATE A |   STATE B |   STATE C |
|----+----------------+-----------+-----------+-----------|
|  0 | ALT_A          |      5000 |      2000 |       100 |
|  1 | ALT_B          |        50 |        50 |       500 |
+----+----------------+-----------+-----------+-----------+

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scikit-mcda-0.21.24.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

scikit_mcda-0.21.24-py3-none-any.whl (31.1 kB view details)

Uploaded Python 3

File details

Details for the file scikit-mcda-0.21.24.tar.gz.

File metadata

  • Download URL: scikit-mcda-0.21.24.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.22.0 setuptools/51.1.2 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.8.5

File hashes

Hashes for scikit-mcda-0.21.24.tar.gz
Algorithm Hash digest
SHA256 d83c982ead5828e7ac8fba447f3bb3d3ac8c011ef56b805c89155d107bef2f95
MD5 ae69f6bf2ffcd2a93823f82c529ab377
BLAKE2b-256 7b9d3568b871fc0725f62d70dd04076ec64faefa66fd7ed1de61bf87f885e377

See more details on using hashes here.

Provenance

File details

Details for the file scikit_mcda-0.21.24-py3-none-any.whl.

File metadata

  • Download URL: scikit_mcda-0.21.24-py3-none-any.whl
  • Upload date:
  • Size: 31.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.22.0 setuptools/51.1.2 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.8.5

File hashes

Hashes for scikit_mcda-0.21.24-py3-none-any.whl
Algorithm Hash digest
SHA256 980257bd7c9570eaac893e89e6134dbf6ecb3a1d2e9b6722da5d62814cf5ffd6
MD5 c491578b1455addf49bb6cf09259a10e
BLAKE2b-256 d170a4b0e6973239e9b4a7c9aab07652e5f7ffc6cde53286d65c9be3e0071298

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page