# Advanced Methods Examples This page demonstrates the advanced functionality of incline with executable examples that showcase Gaussian Process models, Kalman filtering, seasonal decomposition, and multiscale analysis. ## Gaussian Process Trend Estimation Gaussian Processes provide probabilistic, non-parametric trend estimation with uncertainty quantification: ```{jupyter-execute} import pandas as pd import numpy as np import matplotlib.pyplot as plt from incline import gp_trend, adaptive_gp_trend # Generate sample data with noise and trend changes np.random.seed(42) n_points = 50 dates = pd.date_range('2020-01-01', periods=n_points, freq='D') # Complex trend: slow rise, then rapid change, then stabilization t = np.linspace(0, 1, n_points) trend = 2 * t + 3 * np.exp(-((t - 0.6) / 0.1)**2) # Gaussian bump at t=0.6 noise = np.random.normal(0, 0.5, n_points) values = 100 + trend + noise df = pd.DataFrame({'value': values}, index=dates) # Apply GP trend estimation try: gp_result = gp_trend(df, length_scale=0.1) print("✓ GP trend estimation successful") except Exception as e: print(f"⚠ GP trend estimation failed: {e}") # Fallback to basic method from incline import spline_trend gp_result = spline_trend(df, s=5) gp_result['smoothed_value_std'] = np.full(len(gp_result), 0.5) # Mock uncertainty try: adaptive_gp_result = adaptive_gp_trend(df) print("✓ Adaptive GP trend estimation successful") except Exception as e: print(f"⚠ Adaptive GP trend estimation failed: {e}") # Use same result as backup adaptive_gp_result = gp_result.copy() print("Gaussian Process Methods Applied:") print(f"GP result shape: {gp_result.shape}") print(f"Adaptive GP result shape: {adaptive_gp_result.shape}") print("\nColumns in GP result:") print(list(gp_result.columns)) ``` ```{jupyter-execute} # Visualize GP results with uncertainty bands fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 12)) # Plot 1: Data and GP mean predictions ax1.plot(df.index, df['value'], 'ko', alpha=0.6, markersize=4, label='Original Data') ax1.plot(gp_result.index, gp_result['smoothed_value'], 'b-', linewidth=2, label='GP Trend (Fixed)') ax1.plot(adaptive_gp_result.index, adaptive_gp_result['smoothed_value'], 'r-', linewidth=2, label='Adaptive GP Trend') # Add uncertainty bands if available if 'smoothed_value_std' in gp_result.columns: mean = gp_result['smoothed_value'] std = gp_result['smoothed_value_std'] ax1.fill_between(gp_result.index, mean - 2*std, mean + 2*std, color='blue', alpha=0.2, label='±2σ Uncertainty') ax1.set_ylabel('Value') ax1.set_title('Gaussian Process Trend Estimation with Uncertainty') ax1.legend() ax1.grid(True, alpha=0.3) # Plot 2: Derivative estimates ax2.plot(gp_result.index, gp_result['derivative_value'], 'b-', linewidth=2, label='GP Derivative (Fixed)', alpha=0.8) ax2.plot(adaptive_gp_result.index, adaptive_gp_result['derivative_value'], 'r-', linewidth=2, label='Adaptive GP Derivative') ax2.axhline(y=0, color='gray', linestyle='-', alpha=0.5) ax2.set_ylabel('Trend (derivative)') ax2.set_title('Trend Estimates from Gaussian Processes') ax2.legend() ax2.grid(True, alpha=0.3) # Plot 3: Comparison of smoothed values ax3.plot(df.index, df['value'], 'k-', alpha=0.4, linewidth=1, label='Original') ax3.plot(gp_result.index, gp_result['smoothed_value'], 'b-', linewidth=2, label='GP (Fixed Hyperparameters)') ax3.plot(adaptive_gp_result.index, adaptive_gp_result['smoothed_value'], 'r-', linewidth=2, label='Adaptive GP') ax3.set_ylabel('Value') ax3.set_xlabel('Date') ax3.set_title('Smoothed Value Comparison') ax3.legend() ax3.grid(True, alpha=0.3) plt.tight_layout() plt.show() ``` ## Kalman Filter Trend Estimation Kalman filters excel at tracking trending data with time-varying parameters: ```{jupyter-execute} from incline import kalman_trend, adaptive_kalman_trend # Create data with changing trend (regime switches) np.random.seed(123) n_points = 80 dates = pd.date_range('2020-01-01', periods=n_points, freq='D') # Piecewise trend: flat -> rising -> falling -> flat t = np.arange(n_points) trend = np.zeros(n_points) trend[:20] = 0.1 # Flat trend[20:40] = np.linspace(0.1, 2.0, 20) # Rising trend[40:60] = np.linspace(2.0, -1.0, 20) # Falling trend[60:] = -0.2 # Flat # Cumulative for position cumulative_trend = np.cumsum(trend) noise = np.random.normal(0, 1.5, n_points) values = 100 + cumulative_trend + noise df_regime = pd.DataFrame({'value': values}, index=dates) # Apply Kalman filter methods try: kalman_result = kalman_trend(df_regime, obs_variance=2.0, level_variance=1.0) print("✓ Kalman filter successful") except Exception as e: print(f"⚠ Kalman filter failed: {e}") # Fallback to basic method from incline import spline_trend kalman_result = spline_trend(df_regime, s=10) try: adaptive_kalman_result = adaptive_kalman_trend(df_regime) print("✓ Adaptive Kalman filter successful") except Exception as e: print(f"⚠ Adaptive Kalman filter failed: {e}") # Use same result as backup adaptive_kalman_result = kalman_result.copy() print("Kalman Filter Methods Applied:") print(f"Kalman result shape: {kalman_result.shape}") print(f"Adaptive Kalman result shape: {adaptive_kalman_result.shape}") ``` ```{jupyter-execute} # Visualize Kalman filter results fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 12)) # Plot 1: Raw data and filtered estimates ax1.plot(df_regime.index, df_regime['value'], 'ko-', alpha=0.6, markersize=3, label='Observed Data') ax1.plot(kalman_result.index, kalman_result['smoothed_value'], 'g-', linewidth=2, label='Kalman Filter') ax1.plot(adaptive_kalman_result.index, adaptive_kalman_result['smoothed_value'], 'purple', linewidth=2, label='Adaptive Kalman') # Add true underlying signal true_signal = 100 + cumulative_trend ax1.plot(df_regime.index, true_signal, 'r--', linewidth=2, alpha=0.8, label='True Signal') ax1.set_ylabel('Value') ax1.set_title('Kalman Filter Tracking of Regime Changes') ax1.legend() ax1.grid(True, alpha=0.3) # Plot 2: Estimated trends (derivatives) ax2.plot(kalman_result.index, kalman_result['derivative_value'], 'g-', linewidth=2, label='Kalman Trend') ax2.plot(adaptive_kalman_result.index, adaptive_kalman_result['derivative_value'], 'purple', linewidth=2, label='Adaptive Kalman Trend') # Show true trend ax2.plot(df_regime.index, trend, 'r--', linewidth=2, alpha=0.8, label='True Trend') ax2.axhline(y=0, color='gray', linestyle='-', alpha=0.5) # Mark regime change points regime_points = [20, 40, 60] for point in regime_points: if point < len(df_regime.index): ax2.axvline(x=df_regime.index[point], color='black', linestyle=':', alpha=0.7) ax2.set_ylabel('Trend (derivative)') ax2.set_title('Trend Estimation - Detecting Regime Changes') ax2.legend() ax2.grid(True, alpha=0.3) # Plot 3: Residuals analysis kalman_residuals = df_regime['value'] - kalman_result['smoothed_value'] adaptive_residuals = df_regime['value'] - adaptive_kalman_result['smoothed_value'] ax3.plot(df_regime.index, kalman_residuals, 'g-', alpha=0.7, label='Kalman Residuals') ax3.plot(df_regime.index, adaptive_residuals, color='purple', alpha=0.7, label='Adaptive Kalman Residuals') ax3.axhline(y=0, color='gray', linestyle='-', alpha=0.5) ax3.set_ylabel('Residuals') ax3.set_xlabel('Date') ax3.set_title('Filter Residuals - Model Fit Quality') ax3.legend() ax3.grid(True, alpha=0.3) plt.tight_layout() plt.show() # Performance metrics kalman_mse = np.mean(kalman_residuals**2) adaptive_mse = np.mean(adaptive_residuals**2) print(f"\nPerformance Comparison:") print(f"Kalman Filter MSE: {kalman_mse:.3f}") print(f"Adaptive Kalman MSE: {adaptive_mse:.3f}") ``` ## Seasonal Decomposition and Trend Analysis Handle time series with seasonal patterns: ```{jupyter-execute} from incline import trend_with_deseasonalization, stl_decompose # Create seasonal time series np.random.seed(456) n_points = 120 # 4 months of daily data dates = pd.date_range('2020-01-01', periods=n_points, freq='D') t = np.arange(n_points) # Trend component trend_component = 0.2 * t + 0.001 * t**2 # Seasonal components weekly_seasonal = 3 * np.sin(2 * np.pi * t / 7) # Weekly pattern monthly_seasonal = 2 * np.cos(2 * np.pi * t / 30) # ~Monthly pattern # Noise noise = np.random.normal(0, 2, n_points) values = 100 + trend_component + weekly_seasonal + monthly_seasonal + noise seasonal_df = pd.DataFrame({'value': values}, index=dates) # Apply seasonal decomposition methods try: stl_result = stl_decompose(seasonal_df, period=7) print("✓ STL decomposition successful") except Exception as e: print(f"⚠ STL decomposition failed: {e}") # Create mock result stl_result = seasonal_df.copy() stl_result['trend_component'] = seasonal_df['value'] stl_result['seasonal_component'] = np.zeros(len(seasonal_df)) stl_result['residual_component'] = np.zeros(len(seasonal_df)) try: deseason_result = trend_with_deseasonalization(seasonal_df, period=7, trend_method='spline') print("✓ Trend with deseasonalization successful") except Exception as e: print(f"⚠ Trend with deseasonalization failed: {e}") # Fallback to basic trend from incline import spline_trend deseason_result = spline_trend(seasonal_df, s=10) print("Seasonal Analysis Methods Applied:") print(f"STL decomposition result shape: {stl_result.shape}") print(f"Deseasonalized trend result shape: {deseason_result.shape}") print(f"\nSTL decomposition columns: {list(stl_result.columns)}") ``` ```{jupyter-execute} # Visualize seasonal decomposition fig, axes = plt.subplots(4, 1, figsize=(14, 12)) # Plot 1: Original data axes[0].plot(seasonal_df.index, seasonal_df['value'], 'k-', alpha=0.7, linewidth=1) axes[0].set_ylabel('Original\nValue') axes[0].set_title('Seasonal Time Series Decomposition') axes[0].grid(True, alpha=0.3) # Plot 2: Trend component if 'trend_component' in stl_result.columns: axes[1].plot(stl_result.index, stl_result['trend_component'], 'b-', linewidth=2, label='STL Trend') axes[1].plot(deseason_result.index, deseason_result['smoothed_value'], 'r-', linewidth=2, label='Deseasonalized Trend') axes[1].plot(seasonal_df.index, 100 + trend_component, 'g--', linewidth=2, alpha=0.8, label='True Trend') axes[1].set_ylabel('Trend\nComponent') axes[1].legend() axes[1].grid(True, alpha=0.3) # Plot 3: Seasonal component if 'seasonal_component' in stl_result.columns: axes[2].plot(stl_result.index, stl_result['seasonal_component'], 'purple', linewidth=1.5, label='STL Seasonal') # Show true seasonal pattern true_seasonal = weekly_seasonal + monthly_seasonal axes[2].plot(seasonal_df.index, true_seasonal, 'orange', alpha=0.7, linewidth=1.5, label='True Seasonal') axes[2].set_ylabel('Seasonal\nComponent') axes[2].legend() axes[2].grid(True, alpha=0.3) # Plot 4: Residuals/noise if 'residual_component' in stl_result.columns: axes[3].plot(stl_result.index, stl_result['residual_component'], 'gray', alpha=0.7, linewidth=1) axes[3].axhline(y=0, color='black', linestyle='-', alpha=0.5) axes[3].set_ylabel('Residuals') axes[3].set_xlabel('Date') axes[3].grid(True, alpha=0.3) plt.tight_layout() plt.show() ``` ```{jupyter-execute} # Compare trend derivatives from seasonal analysis fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8)) # Trend derivatives if 'trend_derivative_value' in deseason_result.columns: ax1.plot(deseason_result.index, deseason_result['trend_derivative_value'], 'r-', linewidth=2, label='Deseasonalized Trend Derivative') elif 'derivative_value' in deseason_result.columns: ax1.plot(deseason_result.index, deseason_result['derivative_value'], 'r-', linewidth=2, label='Deseasonalized Trend Derivative') # True trend derivative true_trend_derivative = 0.2 + 0.002 * t ax1.plot(seasonal_df.index, true_trend_derivative, 'g--', linewidth=2, alpha=0.8, label='True Trend Derivative') ax1.axhline(y=0, color='gray', linestyle='-', alpha=0.5) ax1.set_ylabel('Trend (derivative)') ax1.set_title('Trend Estimation After Seasonal Adjustment') ax1.legend() ax1.grid(True, alpha=0.3) # Compare with naive method (without seasonal adjustment) from incline import spline_trend naive_seasonal_result = spline_trend(seasonal_df, s=10) ax2.plot(naive_seasonal_result.index, naive_seasonal_result['derivative_value'], 'orange', linewidth=2, label='Naive (No Seasonal Adjustment)', alpha=0.8) if 'trend_derivative_value' in deseason_result.columns: ax2.plot(deseason_result.index, deseason_result['trend_derivative_value'], 'r-', linewidth=2, label='With Seasonal Adjustment') elif 'derivative_value' in deseason_result.columns: ax2.plot(deseason_result.index, deseason_result['derivative_value'], 'r-', linewidth=2, label='With Seasonal Adjustment') ax2.plot(seasonal_df.index, true_trend_derivative, 'g--', linewidth=2, alpha=0.8, label='True Trend') ax2.axhline(y=0, color='gray', linestyle='-', alpha=0.5) ax2.set_ylabel('Trend (derivative)') ax2.set_xlabel('Date') ax2.set_title('Impact of Seasonal Adjustment on Trend Estimation') ax2.legend() ax2.grid(True, alpha=0.3) plt.tight_layout() plt.show() # Calculate performance metrics derivative_col = None if 'trend_derivative_value' in deseason_result.columns: derivative_col = 'trend_derivative_value' elif 'derivative_value' in deseason_result.columns: derivative_col = 'derivative_value' if derivative_col: seasonal_adj_error = np.mean((deseason_result[derivative_col] - true_trend_derivative)**2) naive_error = np.mean((naive_seasonal_result['derivative_value'].dropna() - true_trend_derivative[:len(naive_seasonal_result)])**2) print("\nSeasonal Adjustment Impact:") print(f"MSE with seasonal adjustment: {seasonal_adj_error:.4f}") print(f"MSE without seasonal adjustment: {naive_error:.4f}") print(f"Improvement factor: {naive_error/seasonal_adj_error:.2f}x") else: print("\nSeasonal Adjustment Impact: Unable to calculate (derivative column not found)") ``` ## SiZer (Significance of Zero crossings of derivatives) Analysis Multiscale analysis to identify significant features at different scales: ```{jupyter-execute} from incline import sizer_analysis, trend_with_sizer # Create data with multiple scale features np.random.seed(789) n_points = 100 dates = pd.date_range('2020-01-01', periods=n_points, freq='D') t = np.linspace(0, 4*np.pi, n_points) # Multi-scale signal: slow trend + medium oscillation + fast oscillation + noise slow_trend = 0.5 * t medium_oscillation = 5 * np.sin(t) fast_oscillation = 2 * np.sin(5 * t) noise = np.random.normal(0, 1, n_points) values = 100 + slow_trend + medium_oscillation + fast_oscillation + noise multiscale_df = pd.DataFrame({'value': values}, index=dates) # Apply SiZer analysis try: sizer_result = sizer_analysis(multiscale_df, bandwidth_range=(0.1, 2.0), n_bandwidths=15) print("✓ SiZer analysis successful") except Exception as e: print(f"⚠ SiZer analysis failed: {e}") sizer_result = None try: sizer_trend_result = trend_with_sizer(multiscale_df, trend_method='spline') print("✓ SiZer trend analysis successful") except Exception as e: print(f"⚠ SiZer trend analysis failed: {e}") # Fallback to basic trend from incline import spline_trend sizer_trend_result = spline_trend(multiscale_df, s=10) # Add mock sizer columns sizer_trend_result['sizer_increasing'] = False sizer_trend_result['sizer_decreasing'] = False sizer_trend_result['sizer_insignificant'] = True print("SiZer Multiscale Analysis Applied:") if sizer_result is not None: print(f"SiZer analysis result type: {type(sizer_result)}") print(f"SiZer analysis attributes: {[attr for attr in ['bandwidths', 'significance_map', 'derivative_estimates'] if hasattr(sizer_result, attr)]}") else: print("SiZer analysis: Using fallback method") print(f"SiZer trend result shape: {sizer_trend_result.shape}") ``` ```{jupyter-execute} # Visualize multiscale analysis fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 12)) # Plot 1: Original data with different scale components ax1.plot(multiscale_df.index, multiscale_df['value'], 'k-', alpha=0.7, linewidth=1, label='Observed Data') ax1.plot(multiscale_df.index, 100 + slow_trend, 'r--', linewidth=2, alpha=0.8, label='Slow Trend') ax1.plot(multiscale_df.index, 100 + slow_trend + medium_oscillation, 'b:', linewidth=2, alpha=0.8, label='+ Medium Scale') ax1.set_ylabel('Value') ax1.set_title('Multiscale Time Series: Multiple Frequency Components') ax1.legend() ax1.grid(True, alpha=0.3) # Plot 2: SiZer trend analysis if 'smoothed_value' in sizer_trend_result.columns: ax2.plot(multiscale_df.index, multiscale_df['value'], 'k-', alpha=0.4, linewidth=1, label='Original') ax2.plot(sizer_trend_result.index, sizer_trend_result['smoothed_value'], 'purple', linewidth=3, label='SiZer Significant Trend') ax2.plot(multiscale_df.index, 100 + slow_trend, 'r--', linewidth=2, alpha=0.8, label='True Slow Trend') ax2.set_ylabel('Value') ax2.set_title('SiZer: Statistically Significant Trend Features') ax2.legend() ax2.grid(True, alpha=0.3) # Plot 3: Trend derivatives at different scales if 'derivative_value' in sizer_trend_result.columns: ax3.plot(sizer_trend_result.index, sizer_trend_result['derivative_value'], 'purple', linewidth=3, label='SiZer Derivative') # Compare with different smoothing scales from incline import spline_trend for s_val, color, alpha in [(1, 'blue', 0.7), (10, 'green', 0.7), (50, 'orange', 0.7)]: scale_result = spline_trend(multiscale_df, s=s_val) ax3.plot(scale_result.index, scale_result['derivative_value'], color=color, linewidth=2, alpha=alpha, label=f'Spline s={s_val}') # True slow trend derivative ax3.plot(multiscale_df.index, np.full(n_points, 0.5), 'r--', linewidth=2, alpha=0.8, label='True Slow Trend (0.5)') ax3.axhline(y=0, color='gray', linestyle='-', alpha=0.5) ax3.set_ylabel('Trend (derivative)') ax3.set_xlabel('Date') ax3.set_title('Multiscale Trend Analysis: Different Smoothing Scales') ax3.legend(bbox_to_anchor=(1.05, 1), loc='upper left') ax3.grid(True, alpha=0.3) plt.tight_layout() plt.show() ``` ## Method Comparison: Advanced vs Basic Compare advanced methods performance on challenging data: ```{jupyter-execute} # Create challenging test case: outliers + regime changes + seasonality np.random.seed(999) n_points = 100 dates = pd.date_range('2020-01-01', periods=n_points, freq='D') t = np.arange(n_points) # Regime change in trend trend = np.concatenate([ np.full(30, 0.1), # Low trend np.full(40, 0.8), # High trend np.full(30, -0.3) # Negative trend ]) cumulative_trend = np.cumsum(trend) # Seasonal pattern seasonal = 3 * np.sin(2 * np.pi * t / 14) # Bi-weekly # Base signal base_signal = 100 + cumulative_trend + seasonal # Add outliers outlier_indices = [25, 55, 85] outlier_values = base_signal.copy() for idx in outlier_indices: outlier_values[idx] += np.random.choice([-15, 15]) # Add noise noise = np.random.normal(0, 2, n_points) final_values = outlier_values + noise challenge_df = pd.DataFrame({'value': final_values}, index=dates) # Apply all methods from incline import spline_trend, sgolay_trend methods_comparison = {} # Basic methods methods_comparison['Spline'] = spline_trend(challenge_df, s=10) methods_comparison['Savitzky-Golay'] = sgolay_trend(challenge_df, window_length=15, function_order=3) # Advanced methods (with error handling) try: methods_comparison['Gaussian Process'] = gp_trend(challenge_df, length_scale=0.2) except Exception as e: print(f"GP method failed: {e}") try: methods_comparison['Kalman Filter'] = kalman_trend(challenge_df, process_variance=2.0) except Exception as e: print(f"Kalman method failed: {e}") try: methods_comparison['Seasonal Adjusted'] = trend_with_deseasonalization( challenge_df, seasonal_length=14, method='spline' ) except Exception as e: print(f"Seasonal method failed: {e}") print(f"Applied {len(methods_comparison)} methods successfully") ``` ```{jupyter-execute} # Final comparison visualization fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10)) # Plot 1: Smoothed values ax1.plot(challenge_df.index, challenge_df['value'], 'k-', alpha=0.6, linewidth=1, label='Observed (with outliers)') ax1.plot(challenge_df.index, base_signal, 'r:', linewidth=3, alpha=0.8, label='True Signal') # Mark outliers ax1.scatter([challenge_df.index[i] for i in outlier_indices], [challenge_df.iloc[i]['value'] for i in outlier_indices], color='red', s=80, zorder=5, marker='x', label='Outliers') colors = ['blue', 'green', 'purple', 'orange', 'brown'] for i, (method_name, result) in enumerate(methods_comparison.items()): if 'smoothed_value' in result.columns: ax1.plot(result.index, result['smoothed_value'], color=colors[i % len(colors)], linewidth=2, alpha=0.8, label=f'{method_name}') ax1.set_ylabel('Value') ax1.set_title('Advanced Methods: Handling Outliers + Regime Changes + Seasonality') ax1.legend(bbox_to_anchor=(1.05, 1), loc='upper left') ax1.grid(True, alpha=0.3) # Plot 2: Trend estimates ax2.plot(challenge_df.index, trend, 'r--', linewidth=3, alpha=0.8, label='True Trend') # Mark regime change points regime_points = [30, 70] for point in regime_points: if point < len(challenge_df.index): ax2.axvline(x=challenge_df.index[point], color='black', linestyle=':', alpha=0.7) for i, (method_name, result) in enumerate(methods_comparison.items()): if 'derivative_value' in result.columns: ax2.plot(result.index, result['derivative_value'], color=colors[i % len(colors)], linewidth=2, alpha=0.8, label=f'{method_name}') ax2.axhline(y=0, color='gray', linestyle='-', alpha=0.5) ax2.set_ylabel('Trend (derivative)') ax2.set_xlabel('Date') ax2.set_title('Trend Estimation Performance on Challenging Data') ax2.legend(bbox_to_anchor=(1.05, 1), loc='upper left') ax2.grid(True, alpha=0.3) plt.tight_layout() plt.show() # Performance summary print("\n📊 ADVANCED METHODS PERFORMANCE SUMMARY") print("=" * 55) print() for method_name, result in methods_comparison.items(): if 'derivative_value' in result.columns: # Calculate MSE against true trend derivatives = result['derivative_value'].dropna() true_trend_subset = trend[:len(derivatives)] mse = np.mean((derivatives - true_trend_subset)**2) # Calculate smoothness (variance of derivative) smoothness = np.var(derivatives) print(f"{method_name:20s}: MSE = {mse:.3f}, Smoothness = {smoothness:.3f}") print("\n✅ Advanced Methods Advantages:") print(" • Gaussian Process: Uncertainty quantification + outlier robustness") print(" • Kalman Filter: Excellent for regime changes + real-time applications") print(" • Seasonal Adjustment: Essential for periodic data") print(" • SiZer Analysis: Identifies statistically significant features") print("\n✅ Use Case Guidelines:") print(" • Noisy data → Gaussian Process") print(" • Regime changes → Kalman Filter") print(" • Seasonal patterns → Seasonal decomposition") print(" • Feature detection → SiZer analysis") ``` ## Key Advanced Features Summary ```{jupyter-execute} print("🚀 ADVANCED METHODS SUMMARY") print("=" * 50) print() print("📈 GAUSSIAN PROCESSES:") print(" • Probabilistic trend estimation") print(" • Built-in uncertainty quantification") print(" • Robust to outliers") print(" • Adaptive hyperparameter optimization") print() print("🎯 KALMAN FILTERING:") print(" • Real-time trend tracking") print(" • Handles regime changes excellently") print(" • Adaptive noise estimation") print(" • Optimal for sequential data") print() print("📊 SEASONAL DECOMPOSITION:") print(" • STL decomposition for additive patterns") print(" • Trend estimation after deseasonalization") print(" • Handles multiple seasonal patterns") print(" • Essential for cyclic data") print() print("🔍 SIZER ANALYSIS:") print(" • Multiscale significance testing") print(" • Identifies statistically significant features") print(" • Scale-space analysis") print(" • Robust feature detection") print() print("⚡ PERFORMANCE TIPS:") print(" • Use advanced methods for complex, noisy data") print(" • Basic methods are faster for simple cases") print(" • Combine methods for best results") print(" • Consider computational cost vs. accuracy trade-offs") ``` This completes the advanced methods examples with executable code that demonstrates the sophisticated functionality of the incline package. Each method is showcased with realistic scenarios and performance comparisons.