kneeliverse.multi_knee
The following module provides one algorithm that transfroms any single knee detection algorithm into a multi-knee one.
1# coding: utf-8 2 3''' 4The following module provides one algorithm that transfroms 5any single knee detection algorithm into a multi-knee one. 6''' 7 8__author__ = 'Mário Antunes' 9__version__ = '1.0' 10__email__ = 'mario.antunes@ua.pt' 11__status__ = 'Development' 12__license__ = 'MIT' 13__copyright__ = ''' 14Copyright (c) 2021-2023 Stony Brook University 15Copyright (c) 2021-2023 The Research Foundation of SUNY 16''' 17 18import logging 19import numpy as np 20import kneeliverse.linear_fit as lf 21import kneeliverse.metrics as metrics 22 23 24logger = logging.getLogger(__name__) 25 26 27#TODO: support all the other metrics 28def multi_knee(get_knee: callable, points: np.ndarray, t1: float = 0.001, t2: int = 3, cost: metrics.Metrics = metrics.Metrics.smape) -> np.ndarray: 29 """ 30 Wrapper that convert a single knee point detection into a multi knee point detector. 31 32 It uses recursion on the left and right parts of the curve after detecting the current knee. 33 34 Args: 35 get_knee (callable): method that returns a single knee point 36 points (np.ndarray): numpy array with the points (x, y) 37 t1 (float): the coefficient of determination used as a threshold (default 0.01) 38 t2 (int): the mininum number of points used as a threshold (default 3) 39 cost (metrics.Metrics): the cost method used to evaluate a point set (default: metrics.Metrics.smape) 40 41 Returns: 42 np.ndarray: knee points on the curve 43 """ 44 45 stack = [(0, len(points))] 46 knees = [] 47 48 while stack: 49 left, right = stack.pop() 50 pt = points[left:right] 51 52 if len(pt) > t2: 53 if len(pt) <= 2: 54 if cost is metrics.Metrics.rmspe: 55 r = 0.0 56 else: 57 r = 1.0 58 else: 59 coef = lf.linear_fit_points(pt) 60 if cost is metrics.Metrics.r2: 61 r = lf.linear_r2_points(pt, coef) 62 else: 63 r = lf.smape_points(pt, coef) 64 65 curved = r < t1 if cost is metrics.Metrics.r2 else r >= t1 66 67 if curved: 68 rv = get_knee(pt) 69 if rv is not None: 70 idx = rv + left 71 knees.append(idx) 72 stack.append((left, idx+1)) 73 stack.append((idx+1, right)) 74 knees.sort() 75 return np.array(knees)
logger =
<Logger kneeliverse.multi_knee (WARNING)>
def
multi_knee( get_knee: <built-in function callable>, points: numpy.ndarray, t1: float = 0.001, t2: int = 3, cost: kneeliverse.metrics.Metrics = <Metrics.smape: 'smape'>) -> numpy.ndarray:
29def multi_knee(get_knee: callable, points: np.ndarray, t1: float = 0.001, t2: int = 3, cost: metrics.Metrics = metrics.Metrics.smape) -> np.ndarray: 30 """ 31 Wrapper that convert a single knee point detection into a multi knee point detector. 32 33 It uses recursion on the left and right parts of the curve after detecting the current knee. 34 35 Args: 36 get_knee (callable): method that returns a single knee point 37 points (np.ndarray): numpy array with the points (x, y) 38 t1 (float): the coefficient of determination used as a threshold (default 0.01) 39 t2 (int): the mininum number of points used as a threshold (default 3) 40 cost (metrics.Metrics): the cost method used to evaluate a point set (default: metrics.Metrics.smape) 41 42 Returns: 43 np.ndarray: knee points on the curve 44 """ 45 46 stack = [(0, len(points))] 47 knees = [] 48 49 while stack: 50 left, right = stack.pop() 51 pt = points[left:right] 52 53 if len(pt) > t2: 54 if len(pt) <= 2: 55 if cost is metrics.Metrics.rmspe: 56 r = 0.0 57 else: 58 r = 1.0 59 else: 60 coef = lf.linear_fit_points(pt) 61 if cost is metrics.Metrics.r2: 62 r = lf.linear_r2_points(pt, coef) 63 else: 64 r = lf.smape_points(pt, coef) 65 66 curved = r < t1 if cost is metrics.Metrics.r2 else r >= t1 67 68 if curved: 69 rv = get_knee(pt) 70 if rv is not None: 71 idx = rv + left 72 knees.append(idx) 73 stack.append((left, idx+1)) 74 stack.append((idx+1, right)) 75 knees.sort() 76 return np.array(knees)
Wrapper that convert a single knee point detection into a multi knee point detector.
It uses recursion on the left and right parts of the curve after detecting the current knee.
Arguments:
- get_knee (callable): method that returns a single knee point
- points (np.ndarray): numpy array with the points (x, y)
- t1 (float): the coefficient of determination used as a threshold (default 0.01)
- t2 (int): the mininum number of points used as a threshold (default 3)
- cost (metrics.Metrics): the cost method used to evaluate a point set (default: metrics.Metrics.smape)
Returns:
np.ndarray: knee points on the curve