CEEMDAN battery forecasting

Split a battery’s capacity curve into components using only its first 118 cycles, forecast each one, and score the summed forecast on the last 50 cycles against simpler forecasts.

The card below names the data source and the course-project notebook this demo is based on. The settings of the models on this page are in “How the current models were trained” below and in “Did the models learn the training series?”.

Data source. NASA Battery Dataset — per-cycle discharge capacity for lithium-ion cells B0005, B0006, B0007 and B0018, as the two CSVs in original_data/ hold it. Detailed dataset provenance and usage conditions are on the Dataset page.

Notebook lineage

Source / context
PC5251 course project submission — a student project titled "Lithium-ion Battery capicity Life Prediction" (the misspelling is the notebook's). Written in Google Colab. Its motivation cell cites doi 10.19799/j.cnki.2095-4239.2022.0341 as the paper whose CEEMDAN + random-forest approach it follows.
Notebook
CapicityPrediction.ipynb

What the data files contain

Each row sets one statement from the notebook’s source record (“Card says”) beside what the raw files in original_data/ actually contain, measured by reading the files (“The file says”). The verdict gives the result; dataset identity and unit are confirmed by the Dataset page’s check against NASA’s official files.

Property Card says The file says Verdict

Data file: original_data/NASAbattery.csv — sha256 a03c4c961de3ca65…, 12,717 bytes, 168 data rows. Collection span, read from original_data/metadata.csv: 2008-04-02 → 2008-08-20. Origin and citation: see the Dataset page.

How the current models were trained

Each LSTM: LSTM(1,16) → LSTM(16,8) → Linear(8,1). It reads a window of 16 values; each series is standardized using its training values only; Adam optimizer, learning rate 0.001. Settings were chosen by fitting cycles 1–88 and forecasting cycles 89–118 recursively; for this step CEEMDAN was recomputed on cycles 1–88 only. The chosen settings were then refitted on cycles 1–118, with CEEMDAN recomputed on those cycles. Raw LSTM: delta target, 300 epochs. Component LSTMs: delta target, 300 epochs (delta = predict the change from the last value). The residue is constant to rounding error and is carried forward without a model.

What the capacity curve itself shows

The capacity of battery B0005 (the charge one full discharge delivers, in Ah), one value per charge–discharge cycle, before anything is decomposed. The split is fixed first: cycles 1–118 are the training interval and the shaded band, cycles 119–168, is used only for scoring. CEEMDAN, the random forest and every LSTM see the training interval alone. As in the Battery SOH demo (SOH: state of health), the aim is to forecast the decline and read off the remaining useful life: the number of cycles until capacity falls below a failure threshold.

training interval held-out measured capacity failure threshold (dashed)

Capacity falls from 1.856 Ah to 1.325 Ah over 168 cycles, and first stays at or below 1.4 Ah for five consecutive cycles at cycle 125. The question is whether a model fitted only on cycles 1–118 can forecast this decline.

Findings

Five facts about the decomposition and the split, each computed from the saved results.

The residue is zero

CEEMDAN splits the curve into intrinsic mode functions (IMFs: oscillating components, ordered fast to slow) plus a residue, whatever is left over. Here the 4 IMFs already add up to the curve on their own.

largest |residue| 4.4 × 10^-16 Ah, rounding error, across 118 values · energy share 0.0% · forest importance 0.0%

In effect the decomposition has 4 components, not 5. The residue column stays in every table so that the components still add up exactly; it contributes nothing.

One component is the degradation curve

IMF 4 is the slow trend: it holds almost all the variance and tracks capacity almost perfectly, while the fast components together hold what is left.

IMF 4: energy 98.2% · r = 0.993 · importance 73.8% — every other component together: energy 1.8%

Forecasting this curve is, to a first approximation, forecasting one component. That is why the slow component’s extrapolation matters most.

The decomposition is exactly additive

Adding all 5 component values at a cycle returns the measured capacity at that cycle, to floating-point precision.

max |Σ components − capacity| = 0.0 × 10^0 Ah across 118 training cycles

This is why a random forest given the components reconstructs capacity almost perfectly (training R² 0.9978): the target is the sum of its inputs.

The held-out cycles are kept out of every fit

Every component series stops at the split, and every prediction series starts one cycle after it.

components 118 values · predictions 50 values · 118 + 50 = 168 cycles in the file

This removes the leakage in the original notebook, which decomposed all 168 cycles, so its components were computed from the same data its model was then scored on.

Failure happens inside the held-out window

Capacity crosses both failure thresholds after the split, so finding the remaining useful life on this battery takes a real forecast.

1.4 Ah at cycle 125 (7 after the split) · 1.3 Ah at cycle 162 (44 after the split)

A forecast has to cross the threshold to give a remaining useful life at all, whatever its average error.

What a row and a column are here

Rows × columns handed to the random forest

—

One row per training cycle, one column per CEEMDAN component. A random forest (many decision trees, averaged) learns to reproduce each row's measured capacity, shown in the key column beside the matrix, from these columns; its importance scores rank the components. The 50 held-out cycles are not in this matrix.

118
rows · training cycles 1–118
5
columns · 4 IMFs + residue
0.9978
forest R² on these rows
0.0 × 10^0
max |Σ row − capacity| (Ah)

How a row is built

  • A row is one training cycle. Row X[i,:] holds the 5 component values at that cycle, and they sum to the cycle's measured capacity.
  • A column is one component. Column X[:,j] is a whole time series — IMF 1, IMF 2, IMF 3, IMF 4, residue — produced by CEEMDAN from the training interval alone.
  • A cell x_ij is one component's contribution to one cycle. Column magnitudes run from 4.4 × 10^-16 to 1.833 Ah, which is why the colour scale is per column.
  • Nothing is dropped. All 118 training cycles become rows; the 50 held-out cycles are excluded by the split rule, not by a filter.

The matrix itself

One thin strip per training cycle, one block column per component, plus a key column with the measured capacity the forest is asked to reproduce. Hover over a cell to read its value. Click a cell to select its row X[i,:], its column X[:,j] and the cell itself x_ij; the Row view and Column view update to show them.

− column max+ column max

Rows sorted by cycle (chronological), ascending — the matrix, the key column and the table below all use this one order, so a row means the same thing in all three.

Row view

The 5 numbers CEEMDAN produced for cycle 1. Each bar is that value against its own column maximum, because the columns are orders of magnitude apart.

IMF 1
0.00628 Ah
IMF 2
0.00810 Ah
IMF 3
0.00948 Ah
IMF 4 x_ij
1.83263 Ah
residue
-0.00000 Ah
Σ row1.85649 Ah
measured capacity at cycle 11.85649 Ah

Column view

A column is a time series: IMF 4 over the 118 training cycles. Energy share 98.2% · correlation with capacity 0.993 · forest importance 73.8%. The dashed marker is the selected row, cycle 1.

Colour: each column is scaled by its own largest absolute value (printed beside the column name) and mapped onto a diverging colour scale centred on zero. One scale for the whole matrix would not work: IMF 4 reaches 1.833 Ah while every other column stays at or below 0.0386 Ah, so 4 of the 5 columns would look blank. The key column uses a sequential colour scale over measured capacity, low to high.

The matrix as numbers — every row, the same values the colours encode
cycleIMF 1IMF 2IMF 3IMF 4residueΣ rowcapacity
10.006280.008100.009481.83263-0.000001.856491.85649
20.000890.005310.007361.832770.000001.846331.84633
3-0.005100.002600.004991.832860.000001.835351.83535
4-0.001950.001820.002491.832900.000001.835261.83526
5-0.000880.002640.000001.832890.000001.834651.83465
60.001320.00394-0.002421.83282-0.000001.835661.83566
70.003160.00400-0.004721.83270-0.000001.835151.83515
8-0.003090.00322-0.006911.832530.000001.825761.82576
9-0.001370.00282-0.008981.832300.000001.824771.82477
100.000890.00259-0.010881.832020.000001.824611.82461
110.003640.00179-0.012501.831680.000001.824621.82462
12-0.003430.00012-0.013781.831290.000001.814201.81420
13-0.00079-0.00161-0.014691.830840.000001.813751.81375
140.00302-0.00470-0.015201.83033-0.000001.813441.81344
15-0.00228-0.00959-0.015301.829760.000001.802601.80260
160.00294-0.01503-0.014941.829140.000001.802111.80211
170.00462-0.01639-0.014091.828450.000001.802581.80258
18-0.00147-0.01040-0.012761.827690.000001.803071.80307
19-0.014610.00149-0.010971.82686-0.000001.802781.80278
200.015720.01415-0.008801.825960.000001.847031.84703
210.008620.02015-0.006321.824970.000001.847421.84742
22-0.003010.01889-0.003591.82389-0.000001.836181.83618
23-0.009180.01293-0.000681.822710.000001.825781.82578
24-0.003790.005160.002301.821440.000001.825111.82511
250.00339-0.003100.005231.820060.000001.825581.82558
26-0.00161-0.010950.008021.818570.000001.814031.81403
270.00494-0.017670.010531.81697-0.000001.814771.81477
280.00449-0.018430.012661.815250.000001.813971.81397
29-0.01140-0.013530.014291.813400.000001.802771.80277
30-0.01889-0.003720.015251.81143-0.000001.804081.80408
310.020150.006930.015381.809340.000001.851801.85180
32-0.002950.012020.014501.807130.000001.830701.83070
33-0.009150.011740.012511.804800.000001.819901.81990
34-0.010650.008060.009541.802360.000001.809311.80931
35-0.003630.002600.005841.799790.000001.804611.80461
360.00205-0.001470.001701.797100.000001.799381.79938
37-0.00084-0.00240-0.002621.794290.000001.788441.78844
380.00133-0.00294-0.006821.791360.000001.782921.78292
39-0.00184-0.00279-0.010631.788300.000001.773031.77303
400.00207-0.00045-0.013701.78511-0.000001.773041.77304
41-0.000430.00206-0.015561.78180-0.000001.767871.76787
42-0.002410.00216-0.015801.77836-0.000001.762321.76232
430.00787-0.00081-0.014241.774800.000001.767621.76762
440.00618-0.00346-0.011161.771110.000001.762671.76267
45-0.00400-0.00462-0.006941.767290.000001.751731.75173
46-0.01563-0.00385-0.002011.76335-0.000001.741851.74185
47-0.02563-0.000710.003141.759290.000001.736091.73609
480.026340.004130.008041.755110.000001.793621.79362
490.012950.007210.012201.750830.000001.783191.78319
50-0.002570.008370.015131.746440.000001.767361.76736
51-0.008860.007520.016421.74193-0.000001.757021.75702
52-0.011350.004890.016021.737310.000001.746871.74687
53-0.005730.000610.014261.732580.000001.741721.74172
540.00125-0.004080.011511.727740.000001.736421.73642
550.00194-0.006620.008191.722810.000001.726321.72632
56-0.00065-0.005990.004671.717780.000001.715811.71581
570.00035-0.003740.001261.71267-0.000001.710531.71053
580.00101-0.00069-0.001781.707470.000001.706011.70601
590.001040.00126-0.004191.702200.000001.700311.70031
600.002190.00140-0.005871.696860.000001.694581.69458
610.000270.00010-0.006931.691460.000001.684901.68490
62-0.00307-0.00078-0.007681.68600-0.000001.674471.67447
630.00284-0.00033-0.008431.680490.000001.674571.67457
64-0.002380.00052-0.009361.674950.000001.663721.66372
65-0.000310.00053-0.010561.669360.000001.659011.65901
660.001980.00003-0.011911.66375-0.000001.653851.65385
67-0.00174-0.00055-0.013171.65812-0.000001.642651.64265
68-0.00013-0.00030-0.014171.652460.000001.637861.63786
690.000180.00060-0.014851.646800.000001.632741.63274
700.000960.00092-0.015261.641120.000001.627751.62775
710.001710.00043-0.015461.635450.000001.622131.62213
72-0.00151-0.00134-0.015591.629780.000001.611331.61133
730.00161-0.00334-0.015811.624110.000001.606561.60656
740.00305-0.00371-0.016291.618450.000001.601511.60151
75-0.00353-0.00183-0.017091.612810.000001.590371.59037
76-0.005600.00227-0.018081.607190.000001.585791.58579
77-0.005280.00768-0.019061.601600.000001.584941.58494
780.007310.01201-0.019831.596030.000001.595531.59553
79-0.008210.01265-0.020211.59049-0.000001.574731.57473
80-0.008710.00870-0.020071.584990.000001.564901.56490
81-0.001770.00139-0.019381.579530.000001.559771.55977
820.01088-0.00744-0.018071.574110.000001.559481.55948
830.01815-0.01609-0.016111.568740.000001.554691.55469
840.02128-0.02236-0.013471.563420.000001.548871.54887
850.01493-0.02475-0.010101.558160.000001.538241.53824
860.00419-0.02315-0.006081.55295-0.000001.527911.52791
87-0.00160-0.01608-0.001611.547820.000001.528531.52853
88-0.01949-0.003650.003051.542740.000001.522651.52265
89-0.038580.010670.007651.537750.000001.517491.51749
900.038080.022970.011951.532830.000001.605821.60582
91-0.008000.028170.015691.527990.000001.563851.56385
92-0.020780.026980.018651.523240.000001.548091.54809
93-0.027620.020660.020761.518570.000001.532381.53238
94-0.020890.011790.022051.514010.000001.526951.52695
95-0.017870.002690.022601.509530.000001.516961.51696
96-0.01052-0.005200.022461.50516-0.000001.511901.51190
97-0.00442-0.011600.021701.50089-0.000001.506561.50656
98-0.00014-0.015420.020381.496730.000001.501551.50155
99-0.00371-0.016690.018571.492670.000001.490841.49084
100-0.00360-0.015580.016331.488730.000001.485871.48587
101-0.00633-0.011880.013721.484900.000001.480411.48041
102-0.01048-0.006350.010861.481190.000001.475211.47521
1030.00057-0.000120.007861.477590.000001.485901.48590
1040.012720.004370.004881.47413-0.000001.496091.49609
1050.002140.005840.002031.470780.000001.480801.48080
106-0.001970.00477-0.000621.46757-0.000001.469751.46975
107-0.010120.00265-0.003131.464500.000001.453901.45390
108-0.002180.00036-0.005581.461550.000001.454151.45415
1090.00548-0.00114-0.008071.458750.000001.455021.45502
1100.00484-0.00122-0.010671.45609-0.000001.449041.44904
111-0.00126-0.00030-0.013351.453580.000001.438671.43867
112-0.002520.00079-0.016031.451210.000001.433451.43345
1130.001710.00128-0.018581.448990.000001.433401.43340
1140.001140.00084-0.020851.446930.000001.428061.42806
1150.00071-0.00017-0.022651.445030.000001.422921.42292
116-0.00027-0.00180-0.023791.443290.000001.417431.41743
117-0.00255-0.00268-0.024071.441710.000001.412411.41241
118-0.00222-0.00214-0.023361.44030-0.000001.412581.41258

Additive components, fast to slow

The idea being tested. Fast components tend to be measurement noise; the slow component is the degradation trend. Decompose-then-forecast assumes that forecasting each smooth component is easier than forecasting the noisy sum: split the curve, forecast the pieces, add them back up. This section tests that idea on battery B0005: first the components, then which of them the random forest relies on, then the error on the held-out cycles.

CEEMDAN splits the training interval (cycles 1–118) into intrinsic mode functions (IMFs) plus a residue. Each row shows one component over the training cycles; hover over a curve to read its values. The bar is the random forest’s importance for that component; energy share and correlation with capacity add two further measures.

Which components carry the curve

How to read the importance chart

Each bar is one component's share of the forest's importance; hover over a bar for its energy share and correlation. IMF 4 dominates: 73.8% of the importance, 98.2% of the component energy and correlation 0.993 with capacity. That is the slow degradation trend. The fast components carry little energy and little importance: they add little to reconstructing the curve.

Did the models learn the training series?

How settings were chosen: each model was fitted on cycles 1–88 and then forecast cycles 89–118 recursively. Two targets (the next value, “level”, or the change from the last value, “delta”) and three training lengths (100, 300 and 600 epochs) were compared. The setting with the lowest validation RMSE was refitted on cycles 1–118.

PipelineTargetEpochsValidation RMSE (Ah)
Raw LSTMdelta3000.02846
CEEMDAN + LSTMdelta3000.04392
Training fit versus repeating the previous value

One-step errors on the training cycles for each series: the fitted model against simply repeating the previous value. The residue, which is constant, is skipped.

SeriesFitted MSE (Ah²)Previous-value MSE (Ah²)
Raw capacity2.158e-42.335e-4
IMF 17.101e-51.816e-4
IMF 21.409e-62.455e-5
IMF 38.127e-76.427e-6
IMF 41.185e-71.692e-5
residue0.000e+04.254e-32

Training loss for the raw LSTM and for the LSTM fitted to each component, on the training interval. Lower means a closer fit to the training cycles.

Training MSE in Ah² (original units, log scale), recorded every tenth update. Each line ends at the number of epochs chosen on the validation cycles. The constant residue has no model.

Predict the next 50 cycles from the known past

All forecasts start after cycle 118 and feed their predictions back as input, without receiving later measurements. The raw LSTM is one LSTM trained on the capacity curve directly; CEEMDAN + LSTM adds up one LSTM forecast per component; persistence repeats the last training value; the linear trend extends the slope of the last 16 values.

How to read this chart: the measured line is the battery’s capacity on cycles 119–168; each coloured line is one forecast (legend at the top of this section). The dashed line is the failure threshold chosen in the Failure threshold menu. Hover to compare every forecast with the measurement at one cycle.

Scored on cycles 119–168 (50 values). Lowest RMSE under recursive rollout: Raw LSTM at 0.018 Ah.

Model diagnostics · one-step prediction

Here the raw LSTM gets the 16 true previous measurements at every step (teacher forcing), so each prediction is only one cycle ahead. Comparing it with the same model’s recursive forecast shows how much error builds up when predictions become inputs.

Measured capacity One-step prediction Recursive forecast
Raw LSTM evaluationRMSE (Ah)MAE (Ah)
One step with measured history0.00980.0064
Recursive 50-cycle forecast0.01780.0149

Only the raw LSTM is evaluated one step ahead.

Held-out error

Cycles 119–168, 50 values, using recursive rollout. RMSE and MAE are in Ah, MSE in Ah². Lower is better.

modelMSERMSEMAE
Raw LSTM3.17e-40.0180.015
CEEMDAN + LSTM2.65e-30.0520.047
Linear trend5.60e-30.0750.065
Persistence5.82e-30.0760.068

Remaining useful life

The first cycle at which capacity stays at or below 1.4 Ah for five consecutive cycles, for the measured curve and for each recursive forecast. Error is the distance from the measured crossing; “no crossing” means the forecast never reaches the threshold by cycle 168.

curvecrossing cycleerror
Measured capacity125—
Raw LSTM1232 cycles
CEEMDAN + LSTM14419 cycles
Persistence—no crossing
Linear trend1205 cycles

What this analysis shows

Retraining improved the CEEMDAN + LSTM forecast

Its recursive RMSE on cycles 119–168 fell from 0.2961 Ah in the archived run to 0.0515 Ah. The rerun changed scaling, network architecture, optimizer settings and how settings were chosen, all at once.

How the forecasts rank

Recursive RMSE on cycles 119–168, lowest first: Raw LSTM 0.0178 Ah · CEEMDAN + LSTM 0.0515 Ah · Linear trend 0.0748 Ah · Persistence 0.0763 Ah. Given measured history at every step (one step ahead), the raw LSTM reaches 0.0098 Ah.

Settings were chosen on cycles 89–118

Each pipeline’s target and training length were chosen by forecasting cycles 89–118 from a fit on cycles 1–88; cycles 119–168 were used only for the final scores.

Glossary

Terms used on this page, with what they mean for this battery and this analysis.

The measurement

Capacity (Ah)

The charge a full discharge delivers, one number per cycle. On battery B0005 it starts at 1.856 Ah and ends at 1.325 Ah.

Cycle

One charge followed by one discharge. Cycles are numbered from 1; they are the x-axis of every chart and the rows of the design matrix. The Dataset page numbers the same discharges from 0, so its discharge 0 is cycle 1 here.

Capacity fade

The downward drift of capacity with cycling. It is not monotonic: the curve recovers locally, which is why a smooth fit and a decomposition disagree about what is noise.

Failure threshold

A capacity level treated as end of life. Two are used here, 1.4 Ah and 1.3 Ah, and a crossing counts only when it is sustained for five consecutive cycles, so a single dip does not declare failure.

Remaining useful life (RUL)

The number of cycles until that sustained crossing. Here it is read off a forecast curve, so a model that never crosses has no RUL at all rather than a large error.

The decomposition

CEEMDAN

Complete Ensemble Empirical Mode Decomposition with Adaptive Noise. It splits a 1-D signal into additive, data-adaptive oscillations plus a residue by repeatedly sifting the signal with small noise realisations added (100 of them here, noise seed 100). It is not a fixed filter bank: the components are derived from this signal, so decomposing a longer signal gives different components.

Intrinsic mode function (IMF)

One additive component, ordered fast to slow. Here there are 4: the first three are small oscillations and IMF 4 is the degradation trend.

Residue

What is left after every IMF is removed. On this run it is empty: all 118 stored values are approximately zero at floating-point precision, so it is carried through the arithmetic and contributes nothing.

Energy share

The variance of one component as a fraction of the total across components. It answers “how much of the movement is this?”, which is a different question from importance.

Correlation with capacity

Pearson r between a component and the training capacity curve. High r means the component follows the level of the curve, not merely part of its variance.

Leakage

Using information that would not be available at prediction time. EMD-family methods compute every component from the whole signal, so decomposing the full curve and then scoring on its tail lets the tail influence its own features. This demo avoids it by decomposing the training cycles only.

Chronological holdout

The split rule used here: cycles 1–118 for everything that is fitted, cycles 119–168 excluded from fitting and from choosing settings.

The models and the scoring

Design matrix (as used here)

The 118 × 5 table handed to the random forest: one row per training cycle, one column per component, target = measured capacity.

Random-forest importance

The share of split quality attributable to a column, averaged over the trees. Because the columns sum to the target, it measures how much each component contributes to reconstructing capacity.

LSTM

Long short-term memory network: a neural network that reads a sequence step by step and keeps a memory of earlier steps. Here: LSTM(1,16) → LSTM(16,8) → Linear(8,1), with standardized inputs and a target that is either the next value (level) or the change from the last value (delta). The target and number of epochs are chosen on cycles 89–118 (see “How the current models were trained”).

Window

The 16 consecutive values a model sees as input. It also sets how much history a rollout needs before it can start.

Teacher forcing (protocol A)

Scoring in which each prediction receives the true previous window. Errors cannot accumulate, so it measures the one-step fit and not forecasting.

Recursive rollout (protocol B)

Scoring in which each prediction is fed back as input. Errors compound, which is what a real forecast has to survive.

Persistence baseline

Repeat the last training measurement for every held-out cycle. It has no parameters, so it sets the minimum a learned model has to beat to show any skill.

Linear-trend baseline

Fit a straight line to the last 16 values, step one cycle forward, repeat. This extrapolates a local slope without training a neural model.

MSE, RMSE, MAE

Mean squared error, its square root, and mean absolute error, all over the 50 held-out cycles. RMSE is in Ah, so it is directly comparable with the capacity axis.

R²

Fraction of variance explained. Reported here only for the random forest on its training rows, where it is near 1 because the components add up to capacity.