Commit 3bf99043 authored by Le Roux Erwan's avatar Le Roux Erwan
Browse files

[SCM][SCORE TREND] add mann kendall score

parent 25f49d22
No related merge requests found
Showing with 57 additions and 31 deletions
+57 -31
import numpy as np
class AbstractScore(object):
class AbstractTrendScore(object):
"""A score that should be equal to zero is there is no trend
positive if we suppose a positive trend
negative if we suppose a negative trend
@classmethod
def get_detailed_score(cls, sorted_years, sorted_maxima, top_n):
sorted_maxima = np.array(sorted_maxima)
year_top_score_max = cls.year_from_top_score(sorted_years[-top_n:], sorted_maxima[-top_n:], top_max=True)
year_top_score_min = cls.year_from_top_score(sorted_years[:top_n], sorted_maxima[:top_n], top_max=False)
We don't care what happen before the change point.
All we want to focus on, is the potential trend that could exist in the data after a potential change point"""
def __init__(self, starting_years, number_of_top_values) -> None:
self.number_of_top_values = number_of_top_values
self.starting_years = starting_years
def get_detailed_score(self, years_after_change_point, maxima_after_change_point):
raise NotImplementedError
class MannKendall(AbstractTrendScore):
def get_detailed_score(self, years_after_change_point, maxima_after_change_point):
score = 0.0
for i, xi in enumerate(maxima_after_change_point[:-1]):
for xj in maxima_after_change_point[i+1:]:
score += np.sign(xj - xi)
return [score, score, score]
class SortedScore(AbstractTrendScore):
def get_detailed_score(self, years_after_change_point, maxima_after_change_point):
# Get sorted years and sorted maxima
sorted_years, sorted_maxima = zip(
*sorted(zip(years_after_change_point, maxima_after_change_point), key=lambda s: s[1]))
sorted_years, sorted_maxima = list(sorted_years), np.array(sorted_maxima)
year_top_score_max = self.year_from_top_score(sorted_years[-self.number_of_top_values:],
sorted_maxima[-self.number_of_top_values:], top_max=True)
year_top_score_min = self.year_from_top_score(sorted_years[:self.number_of_top_values],
sorted_maxima[:self.number_of_top_values], top_max=False)
score_difference = year_top_score_max - year_top_score_min
return [score_difference, year_top_score_max, year_top_score_min]
@classmethod
def year_from_top_score(cls, top_sorted_years, top_sorted_maxima, top_max=None):
def year_from_top_score(self, top_sorted_years, top_sorted_maxima, top_max=None):
raise NotImplementedError
class MeanScore(AbstractScore):
class MeanScore(SortedScore):
@classmethod
def year_from_top_score(cls, top_sorted_years, top_sorted_maxima, top_max=None):
def year_from_top_score(self, top_sorted_years, top_sorted_maxima, top_max=None):
return np.mean(top_sorted_years)
class MedianScore(AbstractScore):
class MedianScore(SortedScore):
@classmethod
def year_from_top_score(cls, top_sorted_years, top_sorted_maxima, top_max=None):
def year_from_top_score(self, top_sorted_years, top_sorted_maxima, top_max=None):
return np.median(top_sorted_years)
class WeigthedScore(AbstractScore):
class WeigthedScore(SortedScore):
@classmethod
def year_from_top_score(cls, top_sorted_years, top_sorted_maxima, top_max=None):
def year_from_top_score(self, top_sorted_years, top_sorted_maxima, top_max=None):
assert isinstance(top_max, bool)
if not top_max:
top_sorted_maxima = np.sum(top_sorted_maxima) - top_sorted_maxima
......
......@@ -3,7 +3,7 @@ from typing import Generator, List
import numpy as np
from experiment.meteo_france_SCM_study.abstract_score import WeigthedScore
from experiment.meteo_france_SCM_study.abstract_score import WeigthedScore, MannKendall
from experiment.meteo_france_SCM_study.abstract_study import AbstractStudy
from experiment.meteo_france_SCM_study.crocus.crocus import CrocusDepth, CrocusSwe, ExtendedCrocusDepth, \
ExtendedCrocusSwe, CrocusDaysWithSnowOnGround
......@@ -187,8 +187,8 @@ def maxima_analysis():
temporal_non_stationarity=True,
verbose=True,
multiprocessing=True,
complete_non_stationary_trend_analysis=True)
study_visualizer.score = WeigthedScore
complete_non_stationary_trend_analysis=True,
score_class=MannKendall)
study_visualizer.visualize_all_score_wrt_starting_year()
# study_visualizer.visualize_all_independent_temporal_trend()
# study_visualizer.visualize_all_mean_and_max_graphs()
......@@ -196,9 +196,8 @@ def maxima_analysis():
def main_run():
# normal_visualization(temporal_non_stationarity=True)
# trend_analysis()
all_scores_vizu()
# maxima_analysis()
# all_scores_vizu()
maxima_analysis()
# all_normal_vizu()
# annual_mean_vizu_compare_durand_study(safran=True, take_mean_value=True, altitude=2100)
......
......@@ -10,7 +10,7 @@ import numpy as np
import pandas as pd
import seaborn as sns
from experiment.meteo_france_SCM_study.abstract_score import MeanScore, WeigthedScore
from experiment.meteo_france_SCM_study.abstract_score import MeanScore, WeigthedScore, AbstractTrendScore
from experiment.meteo_france_SCM_study.abstract_study import AbstractStudy
from experiment.meteo_france_SCM_study.visualization.study_visualization.non_stationary_trends import \
ConditionalIndedendenceLocationTrendTest, MaxStableLocationTrendTest, IndependenceLocationTrendTest
......@@ -58,7 +58,8 @@ class StudyVisualizer(object):
verbose=False,
multiprocessing=False,
complete_non_stationary_trend_analysis=False,
normalization_under_one_observations=True):
normalization_under_one_observations=True,
score_class=MeanScore):
self.massif_id_to_smooth_maxima = {}
self.temporal_non_stationarity = temporal_non_stationarity
......@@ -88,7 +89,8 @@ class StudyVisualizer(object):
self.window_size_for_smoothing = 1 # other value could be
self.number_of_top_values = 10 # 1 if we just want the maxima
self.score = WeigthedScore
self.score_class = score_class
self.score = self.score_class(self.starting_years, self.number_of_top_values) # type: AbstractTrendScore
# PLOT ARGUMENTS
self.show = False if self.save_to_file else show
......@@ -357,13 +359,12 @@ class StudyVisualizer(object):
massif_name_to_scores = {}
for massif_id, massif_name in enumerate(self.study.study_massif_names):
years, smooth_maxima = self.smooth_maxima_x_y(massif_id)
sorted_years, sorted_maxima = zip(*[(i + self.study.start_year_and_stop_year[0], e)
for i, e in sorted(enumerate(smooth_maxima), key=lambda s: s[1])])
sorted_years, sorted_maxima = list(sorted_years), list(sorted_maxima)
detailed_scores = []
for j, starting_year in enumerate(self.starting_years):
detailed_scores.append(self.score.get_detailed_score(sorted_years, sorted_maxima, self.number_of_top_values))
sorted_years.remove(starting_year)
detailed_scores.append(self.score.get_detailed_score(years, smooth_maxima))
assert years[0] == starting_year, "{} {}".format(years[0], starting_year)
years = years[1:]
smooth_maxima = smooth_maxima[1:]
massif_name_to_scores[massif_name] = np.array(detailed_scores)
return massif_name_to_scores
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment