1. 程式人生 > >matlab做三維線性擬合(多元線性迴歸,準確來說不叫插值)

matlab做三維線性擬合(多元線性迴歸,準確來說不叫插值)

matlab三維擬合(多元線性迴歸)

問題描述

今天同學問了我一個問題,大概意思是給了你三列輸入資料,一列輸出資料,想用一個線性超平面做一個最小二乘擬合(注意這裡不能叫插值)。

一點思考

剛聽到這個問題,同學說的是做插值,說想要做一個插值,這種說法不準確的,不想說迴歸的話,你可以說這是一個擬合。插值和擬合的區別在哪呢?插值要求你做出來的函式(比如說多項式插值)要經過所有給定的資料點,而擬合只要求儘可能地經過,但不要求所有點都落在函式上。“儘可能”,可以說是基於最小二乘的一種儘可能。一般我們說的n次多項式插值(一維),是給你若干個資料點,讓你去做n次多項式插值,如果給定的點的個數小等於n+1,那麼這個插值多項式是存在的,它能保證給定的已知資料點都落在這個多項式(影象)上,但是不一定唯一,如果給定的點大於n+1,那麼不好意思,這時候,插值函式不存在,也就說不能插值。擬合,要求你給定一個函式表示式,裡面帶有未知數(輸入),也帶有一些未知的引數,現在讓你去確定這些未知引數,使得這個表示式儘可能地去擬合一些輸入點。
簡單地說,就是插值要求已給定的每個點都精確落在函式上,單這個要求不滿足時,插值就不存在。擬合是給定你函式形式,要求已給定的每個點都儘可能地落在函式上,它總是存在的。但給定n+1個點,那麼n次多項式插值和n次多項式擬合就是一樣樣的,精確且唯一。

簡單分析

同學說的這個問題啊,你要是一心覺得這是個插值問題,就容易想到matlab中的interp3這個函式,而且裡面也有一個引數是選定為線性插值。為什麼多個數據點,但是還會有線性插值這東西的存在呢?聽起來跟我前面說的矛盾。其實啊,matlab的interp函式的插值是區域性的,也就是說,它所謂的線性插值,插出來的是分段線性函式 ,用的是兩個相鄰的點來做線性插值,這和我們的要求是不一樣的。
怎麼辦呢?對於三維的線性擬合問題,有一些內建的matlab函式是可以用的,比如說rstool、griddata、regress和fitlm等等。我這裡以regress為例,來做個實現。

實現

regress函式是用來做迴歸的,所謂的多維的線性擬合,不就是多元線性迴歸麼,如果學過一點統計的話,這個是不難理解的。
regress的基本用法就是[b,bint,r,rint,stats] = regress(y,X);

  • 這裡的 b是擬合得到方程的係數矩陣,b(1)表示X的第一列代表的變數座標分量的係數(一般設為常數項),b(2)表示X的第二列代表的變數座標分量的係數(比如可以設為x1)……以此類推……
  • bint是迴歸係數的區間
  • r殘差
  • rint置信區間
  • stats用於檢驗迴歸模型是否正確,分別是R的平方(越接近1越好),F值,P值(儘可能小,比如說P<0.05就表示擬合很好)。

此時,我care的只是b值多少,在看看stats的第一個值是不是接近1。
給出一個簡單的程式碼示例如下:

clc
clear

%% 多元線性迴歸模型
y=[7613.51  7850.91  8381.86  9142.81 10813.6]';
x1=[7666 7704 8148 8571 8679 ]';
x2=[16.22 16.85 17.93 17.28 17.23]';
x3 = x1.*x2;
X=[ones(size(y,1)) x1 x2 x3];
[b,bint,r,rint,stats] = regress(y,X);
rcoplot(r,rint) 
%% 預測和計算
X_in = [8000 50 10000]';%測試資料,每一列表示一個變數
X_pre = [ones(size(X_in,1),1) X_in];
y_pre = X_pre*b;

這裡的X在每一列變數構成的變數集前面再加一列1,表示擬合結果中,這一列“變數”對應的係數值為常數。那麼你在輸入新的資料做預測的時候,也得在變數前面加一列1。rcoplot拿來幹嘛用呢?大概就是想用殘差圖讓你直觀地看看擬合的效果如何,看不同沒事,之家看R方值是不是靠近1也是很夠了。
因為是三維的,每個變數都有三個值(對應三個座標分量),這個時候,一般是用點的顏色深淺來代表函式值,想要做個圖直觀看一下擬合效果是不大好弄的。

以上就是三維或者更高維資料點的全域性擬合的一個方法,全域性的擬合,不代表區域性的插值,這個不能interp函式混為一談。這種擬合放到統計中,叫做迴歸。迴歸往往和最小化誤差和是分不開的,這種思想就叫做最小二乘。