# 第12节 对时间序列的影像进行非线性拟合：简单求解

## 1 数据说明

* LANDSAT/LT5\_L1T\_TOA
* 详细的说明可以看注释

## 2 结果展示

![](/files/-M9m0q5ZuS_O15ZJLbO5)

## 3 详细代码

```python
// Array Example:
// Linear Modeling of an ImageCollection

// longitude and latitude
var lon = 114.05;
var lat = 30.49;
var roi= ee.FeatureCollection("users/comingboy1118/China/CH_shi");
var roi= roi.filter(ee.Filter.eq("市","武汉市"));
Map.addLayer(roi,{},"roi")
// This function masks the input with a threshold on the simple cloud score.
var cloudMask = function(img) {
  var cloudscore = ee.Algorithms.Landsat.simpleCloudScore(img).select('cloud');
  return img.updateMask(cloudscore.lt(50));
};

// Load a Landsat 5 image collection.
var collection = ee.ImageCollection('LANDSAT/LT5_L1T_TOA')
  // Filter to get only two years of data.
  .filterDate('2005-04-01', '2018-04-01')
  // Filter to get only imagery at a point of interest.
  .filterBounds(ee.Geometry.Point(lon, lat))
  // Mask clouds by mapping the cloudMask function over the collection.
  .map(cloudMask)
  // Select NIR and red bands only.
  .select(['B4', 'B3'])
  // Sort the collection in chronological order.
  .sort('system:time_start', true);

// This function computes the predictors and the response from the input.
var makeVariables = function(image) {
  // Compute time in fractional years relative to the start of the Epoch.
  var year = image.date().difference(ee.Date('1970-01-01'), 'year');
  // Compute the season in radians, one cycle per year.
  var season = ee.Image(year.multiply(2 * Math.PI));
  // Return an image of the predictors followed by the response.
  return image.select()
    .addBands(ee.Image(1))                                  // 0. constant term
    .addBands(ee.Image(year).rename('t'))                   // 1. linear change
    .addBands(season.sin().rename('sin'))                   // 2. seasonal change
    .addBands(season.cos().rename('cos'))                   // 3. seasonal change
    .addBands(image.normalizedDifference().rename('NDVI'))  // 4. response variable
    .toFloat();
};

// Define the axes of variation in the collection array.
var imageAxis = 0;
var bandAxis = 1;

// Convert the collection to an array.
var array = collection.map(makeVariables).toArray();

// Check the length of the image axis (number of images).
var arrayLength = array.arrayLength(imageAxis);
// Update the mask to ensure that the number of images is greater than or
// equal to the number of predictors (the linear model is solveable).
array = array.updateMask(arrayLength.gt(4));

// Get slices of the array according to positions along the band axis.
var predictors = array.arraySlice(bandAxis, 0, 4);
var response = array.arraySlice(bandAxis, 4);

// Solve for linear regression coefficients in three different ways.
// All three methods produce equivalent results, but some are easier.
// coefficients the hard way
var coefficients1 = predictors.arrayTranspose().matrixMultiply(predictors)
  .matrixInverse().matrixMultiply(predictors.arrayTranspose())
    .matrixMultiply(response);
// coefficients the easy way
var coefficients2 = predictors.matrixPseudoInverse()
  .matrixMultiply(response);
// coefficients the easiest way
var coefficients3 = predictors.matrixSolve(response);

// turn the results into a multi-band image
var coefficientsImage = coefficients3
  .arrayProject([0]) // get rid of the extra dimensions
  .arrayFlatten([
    ['constant', 'trend', 'sin', 'cos']
]);

// use this mask for cartographic purposes, to get rid of water areas
var hansenImage = ee.Image('UMD/hansen/global_forest_change_2013');
var mask = hansenImage.select('datamask').eq(1);

// display the result
Map.setCenter(lon, lat, 8);
Map.addLayer(coefficientsImage.mask(mask).clip(roi), {
  bands: ['sin', 'trend', 'cos'],
  min: [-0.05, -0.1, -0.05],
  max: [0.05, 0.1, 0.05],
});

// plot the results
var fitted = collection.map(makeVariables).map(function(image) {
  var coeffs = coefficientsImage.select(['constant', 'trend', 'sin', 'cos']);
  var predicted = image
    .select(['constant', 't', 'sin', 'cos'])
    .multiply(coeffs)
    .reduce('sum')
    .rename('fitted');
  return image.select('NDVI').addBands(predicted);
});
print(fitted,'fitted')

var roi = ee.Geometry.Point(lon, lat);

print(Chart.image.series(fitted.select(['NDVI','fitted']), roi, ee.Reducer.mean(), 30)
    .setChartType('LineChart')
    .setSeriesNames([ 'NDVI',"fitted"])
    .setOptions({
      title: 'Original and fitted values',
      lineWidth: 1,
      pointSize: 3,
      fontSize: 16
}));
```

### 激励自己，尽可能每周更新1-2篇，2020加油！！！

### 需要交流或者有项目合作可以加微信好友 (姓名+专业+学校)

### 微信号：comingboy0701

### 公众号：猿人充电站


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://comingboy.gitbook.io/gee/di-5-zhang/5.12-jie.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
