Detectors¶
Factory Functions¶
get_detector(name, **kwargs)
¶
Get a detector instance by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Detector name (e.g., "sliding_window", "pelt", "bottom_up"). |
required |
**kwargs
|
Parameters to pass to the detector constructor. |
{}
|
Returns:
| Type | Description |
|---|---|
BaseDetector
|
Configured detector instance. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If detector name is not recognized. |
ImportError
|
If detector requires unavailable dependencies. |
Example
detector = get_detector("pelt", penalty=5) result = detector.fit_detect(x, y)
Source code in src/trend_classifier/detectors/__init__.py
list_detectors()
¶
List available detector names.
Returns:
| Type | Description |
|---|---|
list[str]
|
List of registered detector names. |
Base Classes¶
BaseDetector
¶
Bases: ABC
Abstract base class for trend detection algorithms.
All detection algorithms should inherit from this class and implement the required methods. This enables the Strategy pattern for swapping algorithms at runtime.
Example
class MyDetector(BaseDetector): ... name = "my_detector" ... def fit(self, x, y): ... self._x, self._y = x, y ... return self ... def detect(self): ... # Detection logic here ... return DetectionResult(segments=SegmentList())
Source code in src/trend_classifier/detectors/base.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | |
name
abstractmethod
property
¶
Return the algorithm name for identification.
fit(x, y)
abstractmethod
¶
Fit the detector to the data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
ndarray
|
Array of x values (indices or timestamps). |
required |
y
|
ndarray
|
Array of y values (signal values). |
required |
Returns:
| Type | Description |
|---|---|
BaseDetector
|
Self for method chaining. |
Source code in src/trend_classifier/detectors/base.py
detect()
abstractmethod
¶
Detect trend changes and return segments.
Must be called after fit().
Returns:
| Type | Description |
|---|---|
DetectionResult
|
DetectionResult containing segments and metadata. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called before fit(). |
Source code in src/trend_classifier/detectors/base.py
fit_detect(x, y)
¶
Convenience method to fit and detect in one call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
ndarray
|
Array of x values. |
required |
y
|
ndarray
|
Array of y values. |
required |
Returns:
| Type | Description |
|---|---|
DetectionResult
|
DetectionResult containing segments and metadata. |
Source code in src/trend_classifier/detectors/base.py
DetectionResult
dataclass
¶
Result from a trend detection algorithm.
Attributes:
| Name | Type | Description |
|---|---|---|
segments |
SegmentList
|
List of detected segments with trend information. |
breakpoints |
list[int]
|
List of indices where trend changes occur. |
metadata |
dict
|
Algorithm-specific metadata (e.g., cost values, statistics). |
Source code in src/trend_classifier/detectors/base.py
__len__()
¶
Detector Implementations¶
SlidingWindowDetector¶
SlidingWindowDetector
¶
Bases: BaseDetector
Sliding window trend detector using linear regression.
This is the original algorithm from trend_classifier. It slides a window across the time series, fits a linear trend in each window, and detects segment boundaries when slope or offset changes exceed thresholds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
int
|
Window size (number of samples per window). |
60
|
overlap_ratio
|
float
|
Overlap between adjacent windows (0-1). |
0.33
|
alpha
|
float | None
|
Threshold for slope change detection. None to disable. |
2.0
|
beta
|
float | None
|
Threshold for offset change detection. None to disable. |
2.0
|
metrics_for_alpha
|
Metrics
|
Error metric for slope comparison. |
RELATIVE_ABSOLUTE_ERROR
|
metrics_for_beta
|
Metrics
|
Error metric for offset comparison. |
RELATIVE_ABSOLUTE_ERROR
|
Example
detector = SlidingWindowDetector(n=40, alpha=2.0) result = detector.fit_detect(x, y) print(f"Found {len(result.segments)} segments")
Source code in src/trend_classifier/detectors/sliding_window.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | |
__init__(n=60, overlap_ratio=0.33, alpha=2.0, beta=2.0, metrics_for_alpha=Metrics.RELATIVE_ABSOLUTE_ERROR, metrics_for_beta=Metrics.RELATIVE_ABSOLUTE_ERROR)
¶
Source code in src/trend_classifier/detectors/sliding_window.py
from_config(config)
classmethod
¶
Create detector from a Config object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
Config
|
Configuration object with detector parameters. |
required |
Returns:
| Type | Description |
|---|---|
SlidingWindowDetector
|
Configured SlidingWindowDetector instance. |
Source code in src/trend_classifier/detectors/sliding_window.py
fit(x, y)
¶
Fit the detector to data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
ndarray
|
Array of x values (indices). |
required |
y
|
ndarray
|
Array of y values (signal). |
required |
Returns:
| Type | Description |
|---|---|
SlidingWindowDetector
|
Self for method chaining. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If data is too short for window size. |
Source code in src/trend_classifier/detectors/sliding_window.py
detect(progress_callback=None)
¶
Detect trend segments using sliding window analysis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress_callback
|
Optional callback(current, total) for progress. |
None
|
Returns:
| Type | Description |
|---|---|
DetectionResult
|
DetectionResult with segments and breakpoints. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called before fit(). |
Source code in src/trend_classifier/detectors/sliding_window.py
BottomUpDetector¶
BottomUpDetector
¶
Bases: BaseDetector
Bottom-up merge segmentation detector.
This algorithm starts with many small segments and iteratively merges adjacent segments with the smallest merge cost until reaching the desired number of segments or a cost threshold.
This approach is good for noisy data as it considers the full signal before making decisions, unlike sliding window methods.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_segments
|
int
|
Maximum number of segments to produce. |
10
|
merge_cost_threshold
|
float | None
|
Stop merging when cost exceeds this value. If None, uses max_segments to determine stopping point. |
None
|
initial_segment_size
|
int
|
Size of initial segments before merging. |
5
|
Example
detector = BottomUpDetector(max_segments=10) result = detector.fit_detect(x, y) print(f"Found {len(result.segments)} segments")
Source code in src/trend_classifier/detectors/bottom_up.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | |
__init__(max_segments=10, merge_cost_threshold=None, initial_segment_size=5)
¶
Source code in src/trend_classifier/detectors/bottom_up.py
fit(x, y)
¶
Fit the detector to data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
ndarray
|
Array of x values (indices). |
required |
y
|
ndarray
|
Array of y values (signal). |
required |
Returns:
| Type | Description |
|---|---|
BottomUpDetector
|
Self for method chaining. |
Source code in src/trend_classifier/detectors/bottom_up.py
detect()
¶
Detect segments using bottom-up merging.
Returns:
| Type | Description |
|---|---|
DetectionResult
|
DetectionResult with segments and breakpoints. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called before fit(). |
Source code in src/trend_classifier/detectors/bottom_up.py
PELTDetector¶
PELTDetector
¶
Bases: BaseDetector
PELT change point detector using the ruptures library.
PELT (Pruned Exact Linear Time) is an efficient algorithm for detecting multiple change points in a signal. It finds the optimal segmentation by minimizing a cost function with a penalty for each change point.
This detector requires the ruptures library to be installed:
pip install ruptures
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
Cost model for segment evaluation. Options: - "l2": Least squares (default, good for mean shifts) - "l1": Least absolute deviation (robust to outliers) - "rbf": Kernel-based (detects distribution changes) - "linear": Linear regression model |
'l2'
|
penalty
|
float | None
|
Penalty value for adding change points. Higher values result in fewer segments. If None, uses BIC-derived penalty. |
None
|
min_size
|
int
|
Minimum segment length. |
2
|
jump
|
int
|
Subsample factor for change point candidates. |
1
|
Example
detector = PELTDetector(model="l2", penalty=3) result = detector.fit_detect(x, y) print(f"Found {len(result.segments)} segments")
Note
For financial time series, try: - model="linear" with penalty=1-5 for trend detection - model="l2" with penalty=5-20 for level shifts
Source code in src/trend_classifier/detectors/pelt.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | |
__init__(model='l2', penalty=None, min_size=2, jump=1)
¶
Source code in src/trend_classifier/detectors/pelt.py
fit(x, y)
¶
Fit the detector to data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
ndarray
|
Array of x values (indices). |
required |
y
|
ndarray
|
Array of y values (signal). |
required |
Returns:
| Type | Description |
|---|---|
PELTDetector
|
Self for method chaining. |
Source code in src/trend_classifier/detectors/pelt.py
detect()
¶
Detect change points and create segments.
Returns:
| Type | Description |
|---|---|
DetectionResult
|
DetectionResult with segments and breakpoints. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called before fit(). |