{ "cells": [ { "cell_type": "markdown", "id": "2924a3c0-272e-4daa-a56a-872c9214d2e5", "metadata": {}, "source": [ "# Illustrative example of Temporal PROMETHEE II\n", "\n", "This example demonstrates how to use the Temporal PROMETHEE II method\n", "implemented in pyrepo-mcda.\n", "\n", "The method evaluates alternatives over multiple time periods.\n", "First, PROMETHEE II net flows are calculated separately for each period.\n", "Then, variability and direction of changes are analyzed using DARIA.\n", "Finally, the scores from the most recent period are adjusted according\n", "to temporal variability." ] }, { "cell_type": "markdown", "id": "bdb918a2-0224-4890-9735-f6db71cf12b6", "metadata": {}, "source": [ "## Import required packages" ] }, { "cell_type": "code", "execution_count": 1, "id": "d3f7ce1c-ec81-4a8d-8cb4-f566b66e19e7", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "\n", "from pyrepo_mcda.mcda_methods import Temporal_PROMETHEE_II, DARIA\n", "from pyrepo_mcda.additions import rank_preferences\n", "from pyrepo_mcda.weighting_methods import equal_weighting\n", "from pyrepo_mcda.promethee_preference_functions import (\n", " preference_usual_function\n", ")" ] }, { "cell_type": "markdown", "id": "8a0cf86d-e153-4106-9c1e-1cd42457834e", "metadata": {}, "source": [ "## Decision matrices\n", "\n", "Three decision matrices are prepared for three consecutive years.\n", "\n", "Rows represent alternatives and columns represent criteria.\n", "The same alternatives and criteria must be present in all periods." ] }, { "cell_type": "code", "execution_count": 2, "id": "33f7efc8-07f4-41c0-86e4-ba66be62c835", "metadata": {}, "outputs": [], "source": [ "matrices = {\n", " \"2022\": np.array([\n", " [70, 70, 70],\n", " [50, 55, 60],\n", " [90, 90, 85],\n", " [86, 88, 87]\n", " ]),\n", " \"2023\": np.array([\n", " [71, 70, 69],\n", " [68, 70, 72],\n", " [78, 76, 74],\n", " [86, 88, 87]\n", " ]),\n", " \"2024\": np.array([\n", " [70, 71, 70],\n", " [86, 88, 87],\n", " [65, 63, 60],\n", " [86, 88, 87]\n", " ])\n", "}\n", "\n", "alternative_names = [\"A1\", \"A2\", \"A3\", \"A4\"]" ] }, { "cell_type": "markdown", "id": "6aca848a-1195-4cc0-bfdb-f49708340bbd", "metadata": {}, "source": [ "## Weights and criteria types\n", "\n", "The first criterion is a profit criterion.\n", "The second criterion is a cost criterion.\n", "The third criterion is a profit criterion.\n", "\n", "Equal weighting is used." ] }, { "cell_type": "code", "execution_count": 3, "id": "e291dbab-96e1-4456-b9ee-922fc1b686c1", "metadata": {}, "outputs": [], "source": [ "weights = equal_weighting(matrices[\"2022\"])\n", "\n", "types = np.array([\n", " 1, # profit criterion\n", " -1, # cost criterion\n", " 1 # profit criterion\n", "])" ] }, { "cell_type": "markdown", "id": "c367b1c2-81fd-4a29-acef-618fea5c2b06", "metadata": {}, "source": [ "## Create the Temporal PROMETHEE II object" ] }, { "cell_type": "code", "execution_count": 4, "id": "4b2e381d-a72f-4caf-9369-6925ecc62f31", "metadata": {}, "outputs": [], "source": [ "tp = Temporal_PROMETHEE_II()" ] }, { "cell_type": "markdown", "id": "20c481a7-6e6d-4ccb-bf5b-8a8f3e3c0c02", "metadata": {}, "source": [ "## Calculate temporal preference scores\n", "\n", "Standard deviation is used as the default variability measure." ] }, { "cell_type": "code", "execution_count": 5, "id": "97fd9b8f-2d29-4ca2-bc04-c48fc25d6d6e", "metadata": {}, "outputs": [], "source": [ "scores, (variability, direction, net_flows) = tp(\n", " matrices = matrices,\n", " weights = weights,\n", " types = types,\n", " preference_functions = [\n", " preference_usual_function,\n", " preference_usual_function,\n", " preference_usual_function\n", " ],\n", " alt_names = alternative_names\n", ")" ] }, { "cell_type": "markdown", "id": "08538cf7-7e77-474c-b6fc-78de9eebef5f", "metadata": {}, "source": [ "## Display results" ] }, { "cell_type": "code", "execution_count": 6, "id": "8d691323-d86f-4397-a371-febf1bd51203", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ScoreVariabilityDirectionRank
A1-0.1111110.0523780.03
A20.4622500.2400271.01
A3-0.5428460.209513-1.04
A40.1698440.052378-1.02
\n", "
" ], "text/plain": [ " Score Variability Direction Rank\n", "A1 -0.111111 0.052378 0.0 3\n", "A2 0.462250 0.240027 1.0 1\n", "A3 -0.542846 0.209513 -1.0 4\n", "A4 0.169844 0.052378 -1.0 2" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "results = pd.DataFrame(\n", " {\n", " \"Score\": scores,\n", " \"Variability\": variability,\n", " \"Direction\": direction,\n", " \"Rank\": rank_preferences(scores, reverse=True)\n", " },\n", " index = alternative_names\n", ")\n", "\n", "results" ] }, { "cell_type": "markdown", "id": "29cfe203-3e60-4e4d-a45f-9a470e1be66a", "metadata": {}, "source": [ "## PROMETHEE II net flows in all periods" ] }, { "cell_type": "code", "execution_count": 7, "id": "a72b42a7-b229-49ae-b9c8-d89fafb4c79b", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
202220232024
Alternatives
A1-0.111111-0.222222-0.111111
A2-0.333333-0.2222220.222222
A30.1111110.111111-0.333333
A40.3333330.3333330.222222
\n", "
" ], "text/plain": [ " 2022 2023 2024\n", "Alternatives \n", "A1 -0.111111 -0.222222 -0.111111\n", "A2 -0.333333 -0.222222 0.222222\n", "A3 0.111111 0.111111 -0.333333\n", "A4 0.333333 0.333333 0.222222" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net_flows" ] }, { "cell_type": "markdown", "id": "5eadb167-b36e-4a54-913b-398e861b85c7", "metadata": {}, "source": [ "## Use the Gini coefficient as a variability measure\n", "\n", "Temporal PROMETHEE II allows any variability measure compatible\n", "with DARIA." ] }, { "cell_type": "code", "execution_count": 8, "id": "726dd210-583d-46ba-9ec3-e985334dda7f", "metadata": {}, "outputs": [], "source": [ "daria = DARIA()\n", "\n", "scores_gini, (variability_gini, direction_gini, _) = tp(\n", " matrices = matrices,\n", " weights = weights,\n", " types = types,\n", " variability_function = daria._gini,\n", " preference_functions = [\n", " preference_usual_function,\n", " preference_usual_function,\n", " preference_usual_function\n", " ],\n", " alt_names = alternative_names\n", ")" ] }, { "cell_type": "markdown", "id": "dca9a192-7f99-4bbb-9d64-b31e0e9f7592", "metadata": {}, "source": [ "## Compare variability measures" ] }, { "cell_type": "code", "execution_count": 9, "id": "8c9a6989-f275-4fa3-b6dd-2008ea85a8c9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
STD scoresGini scores
A1-0.111111-0.111111
A20.462250-0.888889
A3-0.5428462.333333
A40.1698440.138889
\n", "
" ], "text/plain": [ " STD scores Gini scores\n", "A1 -0.111111 -0.111111\n", "A2 0.462250 -0.888889\n", "A3 -0.542846 2.333333\n", "A4 0.169844 0.138889" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "comparison = pd.DataFrame(\n", " {\n", " \"STD scores\": scores,\n", " \"Gini scores\": scores_gini\n", " },\n", " index = alternative_names\n", ")\n", "\n", "comparison" ] }, { "cell_type": "code", "execution_count": 10, "id": "e95bde50-5251-4752-be84-4f46f6b7cfbf", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
STD rankGini rank
A133
A214
A341
A422
\n", "
" ], "text/plain": [ " STD rank Gini rank\n", "A1 3 3\n", "A2 1 4\n", "A3 4 1\n", "A4 2 2" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "comparison_rankings = pd.DataFrame(\n", " {\n", " \"STD rank\": rank_preferences(scores, reverse = True),\n", " \"Gini rank\": rank_preferences(scores_gini, reverse = True)\n", " },\n", " index = alternative_names\n", ")\n", "\n", "comparison_rankings" ] }, { "cell_type": "code", "execution_count": null, "id": "3abaebce-535b-4dd7-a7d4-3e1491ba9f1e", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.14.0" } }, "nbformat": 4, "nbformat_minor": 5 }