Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Help] Linear Regression examples #149

Closed
tinvaan opened this issue Jun 8, 2016 · 22 comments
Closed

[Help] Linear Regression examples #149

tinvaan opened this issue Jun 8, 2016 · 22 comments

Comments

@tinvaan
Copy link

tinvaan commented Jun 8, 2016

I know there's an example on Linear Regression but that is done by including D3 libraries to draw the plots etc.
My requirement is to create simple plots/lines using linear regression on a mapbox project using the leafletjs API.
I don't think there's a need to include the D3 libraries et. all for this purpose. There must be an easier way out. All I need is to display a line on the map, which can be achieved by using Polylines. I'm just not sure how the values returned by the linearRegression() or linearRegressionLine() functions can be used for this purpose.

Any help would be much appreciated.

@brylie
Copy link

brylie commented Jun 9, 2016

What format is the data, lat/long? Do you have a code example?

@tinvaan
Copy link
Author

tinvaan commented Jun 9, 2016

Yes, the data format is lat/long. Is it required to convert data to cartesian form before applying the linearRegression* functions ? If yes, that would mean converting the cartesian points back to geodetic coordinates, which I don't think is straightforward, is it ?

Here's the code and this is how my plot on the map looks right now.
screenshot_20160609_130627
Is it because I'm using lat/long input data or is it a flawed logic on my side ?
The yellow line is my attempt at plotting the output of the linearRegressionLine() function and the markers on the red line are the input data.

The following files are relevant,

  1. app.js
  2. map.js
  3. path.js

@brylie
Copy link

brylie commented Jun 9, 2016

One thing might be to check if your coordinates cross the prime meridian.

@tinvaan
Copy link
Author

tinvaan commented Jun 9, 2016

So, passing lat/long data as input to the functions are not an issue, right ?

@tinvaan
Copy link
Author

tinvaan commented Jun 9, 2016

And how does checking if coordinates cross the prime meridian help ? I don't know of the logic behind that.

@brylie
Copy link

brylie commented Jun 9, 2016

Ah, I was thinking of the possibility of coordinates crossing from 180 to -180. Sorry.

@brylie
Copy link

brylie commented Jun 9, 2016

Would you please provide an example array of geographic coordinates? Lets isolate this issue a bit.

@brylie
Copy link

brylie commented Jun 9, 2016

OK, I did some experimentation. It seems like the regression line code needs several steps. Here is my work-in-progress:

var ss = require("simple-statistics");

var coordinates = [
    [61.508122,23.746948], // Tampere, Finland
    [60.984933,24.472046], // Hämeenlinna, Finland
    [60.191889,24.927979] // Helsinki, Finland
];

// Create a regression object in slope intercept form
var regression = ss.linearRegression(coordinates);

// Create a linear regression function, which provides a y coordinate for any given x coordinate
var regressionLine = ss.linearRegressionLine(regression);

// Create an y coordinate based on the first coordinate in array
var regressionStart = regressionLine(coordinates[0][0]);

// Create a y coordinate for last x coordinate in array
var regressionEnd = regressionLine(coordinates[2][0]);

@tinvaan
Copy link
Author

tinvaan commented Jun 9, 2016

Oh cool, did you get a chance to test how the line looks on a map ?
Here's an example array of geographic coordinates : http://dpaste.com/3QRK3R2

These are points that aren't too far apart on the Arabian sea. I clicked at a series on points manually on the map and extracted their lat,long values.

@brylie
Copy link

brylie commented Jun 9, 2016

I am still workin g on the process. I think I am on the right path, or line :-)

@tinvaan
Copy link
Author

tinvaan commented Jun 9, 2016

@brylie oh that's great. I just happened to edit my previous comment FYI.

@brylie
Copy link

brylie commented Jun 9, 2016

OK, here is my working code:

var ss = require("simple-statistics");

var coordinates = [
    [61.508122,23.746948], // Tampere, Finland
    [60.984933,24.472046], // Hämeenlinna, Finland
    [60.191889,24.927979] // Helsinki, Finland
];

// Create a regression object in slope intercept form
var regression = ss.linearRegression(coordinates);

// Create a linear regression function, 
// which provides a y coordinate for any given x coordinate
var regressionFunction = ss.linearRegressionLine(regression);

// Set up starting and ending X coordinates
var regressionStartX = coordinates[0][0];
var lastCoordinateIndex = coordinates.length - 1;
var regressionEndX = coordinates[lastCoordinateIndex][0];

// Calculate starting and ending Y coordinates
var regressionStartY = regressionFunction(regressionStartX);
var regressionEndY = regressionFunction(regressionEndX);

var regressionLine = [
    [regressionStartX, regressionStartY],
    [regressionEndX, regressionEndY]
];


regressionLine;

You can try it out by pasting it in the NPM simple-statistics package sandbox. Then, click Run and select Map coordinates list in the dropdown box next to the Array output.

@brylie
Copy link

brylie commented Jun 9, 2016

Does that seem to work as expected?

@tinvaan
Copy link
Author

tinvaan commented Jun 9, 2016

Wow. That does look legit. I'm just gonna check on my map for sanity. I now realize that you only had to pass the start and end points of the regression line. I was iterating over all the points in the coordinate list and that obviously wasn't helping the cause :-)

@tinvaan
Copy link
Author

tinvaan commented Jun 9, 2016

@brylie it works perfectly ! Thank you so much for your help :-) 👍 💯
screenshot_20160609_145724

@tinvaan tinvaan closed this as completed Jun 9, 2016
@brylie
Copy link

brylie commented Jun 9, 2016

You're welcome :-) One more thing though, what happens if a shipping route goes from, say, Tokyo to Los Angeles? I am concerned how the linear regression might perform when crossing the international date line, or 180 to -180.

@tinvaan
Copy link
Author

tinvaan commented Jun 9, 2016

I honestly haven't thought about that because I only had the southern coast of India in mind. Let's see how your algo works in that case. Posting the screenshot soon.

@brylie
Copy link

brylie commented Jun 9, 2016

OK, cool.

@tinvaan
Copy link
Author

tinvaan commented Jun 9, 2016

@brylie hmm, your concerns seem to have come true.
screenshot_20160609_151400

Also worth noting that I'm drawing these lines for every 5th marker that's created on the map. if (no_of_markers % 5 == 0) { drawRegressionLine() } or something like that.

@brylie
Copy link

brylie commented Jun 9, 2016

Well there might be a geospatial processing/analysis library that is better equipped to handle the international date line issue. E.g. Turf.js seems promising.

@tinvaan
Copy link
Author

tinvaan commented Jun 9, 2016

Thanks! There are still a few more things on the TODO (eg: these lat/long inputs should come from a remote device - android phone for eg) and I'm working on that as well. I'll take a look at Turf.js as soon as other things are sorted out :)

@brylie
Copy link

brylie commented Jun 9, 2016

Cool. Neat project :-)

tinvaan added a commit to tinvaan/NOC that referenced this issue Jun 9, 2016
tinvaan added a commit to tinvaan/NOC that referenced this issue Jan 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants