I am not sure what is called "noise" in the question, from the description, I think it is about removing outliers. This solution uses Quantile regression twice: to detect the outliers, and then to find quantile regression curves in the data without the outliers.
Load the package:
Import["https://raw.githubusercontent.com/antononcube/MathematicaForPrediction/master/QuantileRegression.m"]
Adding x-coordinates to the data:
data = Transpose[{Range[Length[data]], data}];
Selection of quantiles to detect the outliers:
qs = {0.05, 0.5, 0.98};
{qs[[1]], 1 - qs[[-1]]}*Length[data]
(* {25.6, 10.24} *)
Quantile regression with the selected quantiles:
qfuncs = QuantileRegression[data, 15, qs];
Finding the top outliers:
topOutliers = Select[data, qfuncs[[-1]][#[[1]]] < #[[2]] &]
(* {{54, 8.16422}, {145, 8.16422}, {155, 8.14875}, {203,
8.19841}, {289, 8.14254}, {370, 8.17358}, {433, 8.17358}} *)
Finding the bottom outliers:
bottomOutliers = Select[data, qfuncs[[1]][#[[1]]] > #[[2]] &]
(* {{29, 7.9156}, {78, 8.08349}, {81, 7.98714}, {101,
8.03685}, {127, 7.99335}, {140, 8.01821}, {178, 7.8689}, {182,
8.07728}, {220, 8.08349}, {263, 7.98714}, {268, 8.00884}, {323,
8.12381}, {331, 8.12696}, {334, 8.09276}, {386, 8.0617}, {387,
8.05243}, {406, 8.08349}, {454, 8.0617}, {456, 8.05864}, {486,
8.07412}, {496, 8.10833}} *)
Plot data, regression quantiles, and outliers:
qfPlot = ListLinePlot[
Table[{#, qfuncs[[i]][#]} & /@
Rescale[Range[0, 1, 0.005], {0, 1}, MinMax[data[[All, 1]]]], {i,
1, Length[qfuncs]}], PerformanceGoal -> "Quality",
PlotRange -> All, PlotTheme -> "Detailed", PlotLegends -> qs];
Show[{ListPlot[data, PlotRange -> All, PlotStyle -> {GrayLevel[0.5]},
PlotTheme -> "Detailed"], qfPlot,
ListPlot[{topOutliers, bottomOutliers}, PlotStyle -> {{
Blue, PointSize[0.01]}, {Red, PointSize[0.01]}}]},
ImageSize -> 600]
Remove the outliers from the data:
newData = Complement[data, Join[topOutliers, bottomOutliers]];
Make another quantile regression computation over the new data. (This time is to facilitate analysis instead of detecting outliers.)
Block[{data = newData, qfuncs, qs = {0.05, 0.25, 0.5, 0.75, 0.95}},
qfuncs = QuantileRegression[data, 40, qs];
Show[{ListPlot[data, PlotStyle -> GrayLevel[0.5], PlotRange -> All,
PlotTheme -> "Detailed"],
ListLinePlot[
Transpose@
Map[Thread[{#, Through[qfuncs[#]]}] &,
Rescale[Range[0, 1, 0.005], {0, 1}, MinMax[data[[All, 1]]]]],
PlotStyle -> Map[If[# == 0.5, Thick, Thin] &, qs],
PlotLegends -> qs]}, ImageSize -> 600]]
Obviously other methods of signal analysis can be applied to the cleaned data. In this particular case, the cleaned data would give better results for the conditional PDF/CDF reconstruction shown in this blog post "Estimation of conditional density distributions".
MovingAverage
orTrimmedMean
on the data, together withBlockMap
. $\endgroup$TrimmedMean
you will be able to remove outliers on a given window (defined by, e.g.BlockMap
) before taking the average. This should be smoother in principle. $\endgroup$