¿Cómo hacer una regresión lineal por partes con múltiples nudos desconocidos?

14

¿Hay algún paquete para hacer una regresión lineal por partes que pueda detectar los múltiples nudos automáticamente? Gracias. Cuando uso el paquete strucchange. No pude detectar los puntos de cambio. No tengo idea de cómo detecta los puntos de cambio. De las parcelas, pude ver que hay varios puntos que quiero que me ayuden a elegirlos. ¿Alguien podría dar un ejemplo aquí?

Honglang Wang
fuente
1
Esta parece ser la misma pregunta que stats.stackexchange.com/questions/5700/… . Si difiere de manera sustancial, háganoslo saber editando su pregunta para reflejar las diferencias; de lo contrario, lo cerraremos como un duplicado.
whuber
1
He editado la pregunta.
Honglang Wang
1
Creo que puede hacer esto como un problema de optimización no lineal. Simplemente escriba la ecuación de la función que se ajustará, con los coeficientes y las ubicaciones de los nudos como parámetros.
mark999
1
Creo que el segmentedpaquete es lo que estás buscando.
AlefSin
1
Tuve un problema idéntico, lo resolví con el segmentedpaquete de R : stackoverflow.com/a/18715116/857416
un ben diferente

Respuestas:

8

¿ Sería aplicable MARS ? R tiene el paquete earthque lo implementa.

Wayne
fuente
8

En general, es un poco extraño querer ajustar algo como lineal por partes. Sin embargo, si realmente desea hacerlo, entonces el algoritmo MARS es el más directo. Desarrollará una función un nudo a la vez; y luego generalmente elimina el número de nudos para combatir los árboles de decisión de ala demasiado ajustados. Puede acceder al algoritmo MARS en R mediante eartho mda. En general, se ajusta al GCV que no está tan alejado del otro criterio de información (AIC, BIC, etc.)

MARS realmente no le dará un ajuste "óptimo" ya que los nudos crecen uno a la vez. Realmente sería bastante difícil ajustar un número de nudos verdaderamente "óptimo" ya que las posibles permutaciones de la colocación de nudos explotarían rápidamente.

En general, esta es la razón por la cual las personas recurren a suavizar las estrías. La mayoría de las estrías de suavizado son cúbicas solo para que puedas engañar a un ojo humano para que no vea las discontinuidades. Sin embargo, sería bastante posible hacer una spline de suavizado lineal. La gran ventaja de suavizar splines es su único parámetro para optimizar. Eso le permite llegar rápidamente a una solución verdaderamente "óptima" sin tener que buscar entre permutaciones. Sin embargo, si realmente desea buscar puntos de inflexión y tiene suficientes datos para hacerlo, entonces algo como MARS probablemente sea su mejor opción.

Aquí hay un código de ejemplo para splines de suavizado lineal penalizado en R:

require(mgcv);data(iris);
gam.test <- gam(Sepal.Length ~ s(Petal.Width,k=6,bs='ps',m=0),data=iris)
summary(gam.test);plot(gam.test);

Sin embargo, los nudos reales elegidos no se correlacionarán necesariamente con ningún punto de inflexión verdadero.

Shea Parkes
fuente
3

Lo programé desde cero una vez hace unos años, y tengo un archivo Matlab para hacer una regresión lineal por partes en mi computadora. Alrededor de 1 a 4 puntos de interrupción son computacionalmente posibles para aproximadamente 20 puntos de medición más o menos. 5 o 7 puntos de quiebre comienzan a ser realmente demasiado.

El enfoque matemático puro, como lo veo, es probar todas las combinaciones posibles sugeridas por el usuario mbq en la pregunta vinculada en el comentario debajo de su pregunta.

Como las líneas ajustadas son todas consecutivas y adyacentes (sin superposiciones), la combinatoria seguirá el triángulo de Pascal. Si hubiera superposiciones entre los puntos de datos usados ​​por los segmentos de línea, creo que la combinatoria seguiría los números de Stirling del segundo tipo.

La mejor solución en mi mente es elegir la combinación de líneas ajustadas que tenga la desviación estándar más baja de los valores de correlación R ^ 2 de las líneas ajustadas. Trataré de explicar con un ejemplo. Sin embargo, tenga en cuenta que preguntar cuántos puntos de ruptura se deben encontrar en los datos es similar a hacer la pregunta "¿Cuánto dura la costa de Gran Bretaña?" como en uno de los documentos de Benoit Mandelbrots (matemático) sobre fractales. Y existe una compensación entre el número de puntos de ruptura y la profundidad de regresión.

Ahora al ejemplo.

yxxy

xyR2line1R2line2sumofR2valuesstandarddeviationofR2111,0000,04001,04000,6788221,0000,01181,01180,6987331,0000,00041,00040,7067441,0000,00311,00310,7048551,0000,01351,01350,6974661,0000,02381,02380,6902771,0000,02771,02770,6874881,0000,02221,02220,6913991,0000,00931,00930,700410101,0001,9781,0000,70711190,97090,02710,99800,66731280,89510,11391,00900,55231370,77340,25581,02920,36591460,61340,43211,04550,12811550,43210,61341,04550,12821640,25580,77331,02910,36591730,11390,89511,00900,55231820,02720,97080,99800,667219101,0001,0000,70712020,00941,0001,00940,70042130,02221,0001,02220,69142240,02781,0001,02780,68742350,02391,0001,02390,69022460,01361,0001,01360,69742570,00321,0001,00320,70482680,00041,0001,00040,70682790,01181,0001,01180,698728100,041,0001,040,6788

These y values have the graph:

idealized data

Which clearly has two break points. For the sake of argument we will calculate the R^2 correlation values (with the Excel cell formulas (European dot-comma style)):

=INDEX(LINEST(B1:$B$1;A1:$A$1;TRUE;TRUE);3;1)
=INDEX(LINEST(B1:$B$28;A1:$A$28;TRUE;TRUE);3;1)

for all possible non-overlapping combinations of two fitted lines. All the possible pairs of R^2 values have the graph:

R^2 values

The question is which pair of R^2 values should we choose, and how do we generalize to multiple break points as asked in the title? One choice is to pick the combination for which the sum of the R-square correlation is the highest. Plotting this we get the upper blue curve below:

sum of R squared and standard deviation of R squared

The blue curve, the sum of the R-squared values, is the highest in the middle. This is more clearly visible from the table with the value 1,0455 as the highest value. However it is my opinion that the minimum of the red curve is more accurate. That is, the minimum of the standard deviation of the R^2 values of the fitted regression lines should be the best choice.

Piece wise linear regression - Matlab - multiple break points

Mats Granvik
fuente
1

There is a pretty nice algorithm described in Tomé and Miranda (1984).

The proposed methodology uses a least-squares approach to compute the best continuous set of straight lines that fit a given time series, subject to a number of constraints on the minimum distance between breakpoints and on the minimum trend change at each breakpoint.

The code and a GUI are available in both Fortran and IDL from their website: http://www.dfisica.ubi.pt/~artome/linearstep.html

arkaia
fuente
0

... first of all you must to do it by iterations, and under some informative criterion, like AIC AICc BIC Cp; because you can get an "ideal" fit, if number of knots K = number od data points N, ok. ... first put K = 0; estimate L = K + 1 regressions, calculate AICc, for instance; then assume minimal number of data points at a separate segment, say L = 3 or L = 4, ok ... put K = 1; start from L-th data as the first knot, calculate SS or MLE, ... and step by step the next data point as a knot, SS or MLE, up to the last knot at the N - L data; choose the arrangement with the best fit (SS or MLE) calculate AICc ... ... put K = 2; ... use all previous regressions (that is their SS or MLE), but step by step divide a single segment into all possible parts ... choose the arrangement with the best fit (SS or MLE) calculate AICc ... if the last AICc occurs greater then the previous one: stop the iterations ! This is an optimal solution under AICc criterion, ok

Maciek
fuente
AIC, BIC can't be used because they penalised for extra parameters, which is clearly not the case here.
HelloWorld
0

I once came across a program called Joinpoint. On their website they say it fits a joinpoint model where "several different lines are connected together at the 'joinpoints'". And further: "The user supplies the minimum and maximum number of joinpoints. The program starts with the minimum number of joinpoint (e.g. 0 joinpoints, which is a straight line) and tests whether more joinpoints are statistically significant and must be added to the model (up to that maximum number)."

The NCI uses it for trend modelling of cancer rates, maybe it fits your needs as well.

psj
fuente
0

In order to fit to data a piecewise function :

enter image description here

where a1,a2,p1,q1,p2,q2,p3,q3 are unknown parameters to be approximately computed, there is a very simple method (not iterative, no initial guess, easy to code in any math computer language). The theory given page 29 in paper : https://fr.scribd.com/document/380941024/Regression-par-morceaux-Piecewise-Regression-pdf and from page 30 :

enter image description here

For example, with the exact data provided by Mats Granvik the result is :

enter image description here

Without scattered data, this example is not very signifiant. Other examples with scattered data are shown in the referenced paper.

JJacquelin
fuente
0

You can use the mcp package if you know the number of change points to infer. It gives you great modeling flexibility and a lot of information about the change points and regression parameters, but at the cost of speed.

The mcp website contains many applied examples, e.g.,

library(mcp)

# Define the model
model = list(
  response ~ 1,  # plateau (int_1)
  ~ 0 + time,    # joined slope (time_2) at cp_1
  ~ 1 + time     # disjoined slope (int_3, time_3) at cp_2
)

# Fit it. The `ex_demo` dataset is included in mcp
fit = mcp(model, data = ex_demo)

Then you can visualize:

plot(fit)

enter image description here

Or summarise:

summary(fit)

Family: gaussian(link = 'identity')
Iterations: 9000 from 3 chains.
Segments:
  1: response ~ 1
  2: response ~ 1 ~ 0 + time
  3: response ~ 1 ~ 1 + time

Population-level parameters:
    name match  sim  mean lower  upper Rhat n.eff
    cp_1    OK 30.0 30.27 23.19 38.760    1   384
    cp_2    OK 70.0 69.78 69.27 70.238    1  5792
   int_1    OK 10.0 10.26  8.82 11.768    1  1480
   int_3    OK  0.0  0.44 -2.49  3.428    1   810
 sigma_1    OK  4.0  4.01  3.43  4.591    1  3852
  time_2    OK  0.5  0.53  0.40  0.662    1   437
  time_3    OK -0.2 -0.22 -0.38 -0.035    1   834

Disclaimer: I am the developer of mcp.

Jonas Lindeløv
fuente
The use of "detect" in the question indicates the number--and even the existence--of changepoints are not known beforehand.
whuber