Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- JMP User Community
- :
- Discussions
- :
- Segmented regression

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

Highlighted

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

Oct 8, 2012 5:34 PM
(9806 views)

Does anyone know how to perform a segmented regression and calculate the breakpoint (where the 2 lines meet) on JMP?

1 ACCEPTED SOLUTION

Accepted Solutions

Highlighted

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

As Dodo suggests, piecewise regression can be done with the Nonlinear platform. Below is an example based on the broken-stick example above.

```
New Table( "piecewise",
Add Rows( 20 ),
New Column( "X",
Continuous,
Set Values( [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] )
),
New Column( "Y",
Numeric,
Set Values( [15, 12, 27, 31, 26, 31, 42, 47, 56, 56, 47, 46, 36, 44, 38, 35, 34, 35, 25, 19] )
),
New Column( "Ypred",
Numeric,
Formula( Parameter( {a = 20, b = 1, c = -10, d = 10}, a + b * :X + c * (:X - d) * (:X > d) ) )
)
);
Nonlinear( Y( :Y ), X( :Ypred ), Newton, Finish );
```

4 REPLIES 4

Highlighted
##

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

Re: Segmented regression

If it's a simple broken stick relationship, you could do something like this:

```
// Create a broken stick relationship with some noise;
x = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
y = [15, 12, 27, 31, 26, 31, 42, 47, 56, 56, 47, 46, 36, 44, 38, 35, 34, 35, 25, 19];
expr_FX = expr(a + b*x + c*(x-d):*(x>d));
expr_SSE = expr(sum((y-expr_FX)^2));
// Supply a set of starting values;
a = 20; b = 1; c = -10; d = 15;
print("Starting values:");
show(a, b, c, d);
sse = minimize(expr_SSE, {a, b, c, d}, << tolerance(1e-5));
print("Final estimates:");
show(a, b, c, d);
show(eval(expr_FX));
```

I've based the above on the Least Squares Example in the JMP 10 Manual, Chapter 8, substituting a broken stick relationship in the expression for the exponential model in the example. The break point will be parameter d, as that's the x value at which the slope of the line changes. Note that when you multiply the two matrices (x-d) and (x>d) together, you'll need the element-wise product :* as opposed to a simple multiplication. You'll also probably need a relatively good starting value for the break point for the expression to converge. In this example, all the output is written to the log.

Presumably this could also be set up in the nonlinear platform (Analyze | Modeling | Nonlinear), but I haven't tried that yet as I'm not very familiar with using formulae within data tables. Does that help at all?

Highlighted

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

As Dodo suggests, piecewise regression can be done with the Nonlinear platform. Below is an example based on the broken-stick example above.

```
New Table( "piecewise",
Add Rows( 20 ),
New Column( "X",
Continuous,
Set Values( [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] )
),
New Column( "Y",
Numeric,
Set Values( [15, 12, 27, 31, 26, 31, 42, 47, 56, 56, 47, 46, 36, 44, 38, 35, 34, 35, 25, 19] )
),
New Column( "Ypred",
Numeric,
Formula( Parameter( {a = 20, b = 1, c = -10, d = 10}, a + b * :X + c * (:X - d) * (:X > d) ) )
)
);
Nonlinear( Y( :Y ), X( :Ypred ), Newton, Finish );
```

Highlighted
##

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

Re: Segmented regression

Thanks I will try this out!

Highlighted
##

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

Re: Segmented regression

I tried this just recently, it makes more sense to me than the Nonlinear platform utility. I'd be interested in understanding how the iteration scheme is converging on my solution? I tried picking a reasonable value of d (the cutpoint) for my data, and it seemed to work better when I "locked" the value of d and re-clicked the "Go" button on the platform dialogue window that is generated from the Nonlinear platform launched using the:

` Nonlinear( Y( :Y ), X( :Ypred ), Newton, Finish );`

portion of the code.

Is there an easy way to change this short script to call a data table instead? (of manually entering in the values for X and Y)?

I'm sure this is a "JSL Novice Question" so I apologize in advance.....

I took this in a cloogey way and copy-pasted just the following into my saved datable with Columns, {X, Y, Ypred} and my populated data:

```
Parameter( {a = 5, b = 45, c = -100, d = 0.109}, a + b * :X + c * (:X - d) * (:X > d) );
Nonlinear( Y( :Y ), X( :Ypred ), Newton, Finish );
```

and that's how I arrived at my result for my data! Thanks again for this contribution to the community.