一、問題引入
我們現實生活中的很多資料不一定都能用線性模型描述。依然是房價問題,很明顯直線非但不能很好的擬合所有資料點,而且誤差非常大,但是一條類似二次函式的曲線卻能擬合地很好。為了解決非線性模型建立線性模型的問題,我們**乙個點的值時,選擇與這個點相近的點而不是所有的點做線性回歸。基於這個思想,便產生了區域性加權線性回歸演算法。在這個演算法中,其他離乙個點越近,權重越大,對回歸係數的貢獻就越多。
二、問題分析
本演算法依然使用損失函式j,只不過是加權的j函式:
其中w(i)是權重,它根據要**的點與資料集中的點的距離來為資料集中的點賦權值。當某點離要**的點越遠,其權重越小,否則越大。乙個比較好的權重函式如下:
該函式稱為指數衰減函式,其中k為波長引數,它控制了權值隨距離下降的速率,該函式形式上類似高斯分布(正態分佈),但並沒有任何高斯分布的意義。該演算法解出回歸係數如下:
在使用這個演算法訓練資料的時候,不僅需要學習線性回歸的引數,還需要學習波長引數。這個演算法的問題在於,對於每乙個要**的點,都要重新依據整個資料集計算乙個線性回歸模型出來,使得演算法代價極高。
三、**實現
1.matlab版
(1) 區域性加權線性回歸函式
% 對所有點計算估計值
function
yhat = lwlr
(testmat, xmat, ymat, k)
[row, ~] = size(testmat);
yhat = zeros(1, row);
fori = 1:1:row
yhat(i) = lwlrpoint(testmat(i,:), xmat, ymat, k);
endend% 對單個點計算估計值
function
yhatpoint = lwlrpoint
(point, xmat, ymat, k)
[row , ~] = size(xmat);
weights = zeros(row, row);
fori = 1:1:row
diffmat = point - xmat(i, :);
weights(i,i) = exp(diffmat * diffmat.' / (-2.0 * (k ^ 2))); %計算權重對角矩陣
end xtx = xmat.' * (weights * xmat); % 奇異矩陣不能計算
if det(xtx) == 0
printf('this matrix is singular, cannot do inverse');
endtheta = xtx^-1 * (xmat.' * (weights * ymat)); %計算回歸係數
yhatpoint = point * theta;
end
(2) 匯入資料並繪圖
clc;
clear all;
data = load('d:\\ex0.txt');
x = data
(:,1:2);
y = data
(:,3);
y_hat = lwlr(x, x, y, 0.01); % 呼叫區域性加權線性回歸函式計算估計值
x_axis = (x(:, 2))'; % x座標軸為x矩陣的第二列資料
y_axis = y';
sort(x_axis); % 對x向量公升序排列
plot(x_axis, y, 'r.'); % 散點圖
hold on
plot(x_axis, y_hat, 'b.'); %回歸曲線圖
(3) 分別選取k=1.0,0.01,0.003繪圖如下:
圖1 k=1.0 欠擬合
圖2 k=0.01 最佳擬合
圖3 k=0.003 過擬合
2.python版
(1)區域性加權線性回歸函式
from numpy import *
# 對某一點計算估計值
deflwlr
(testpoint, xarr, yarr, k = 1.0):
xmat = mat(xarr); ymat = mat(yarr).t
m = shape(xmat)[0]
weights = mat(eye((m)))
for i in range(m):
diffmat = testpoint - xmat[i, :]
weights[i, i] = exp(diffmat * diffmat.t/(-2.0 * k**2)) # 計算權重對角矩陣
xtx = xmat.t * (weights * xmat) # 奇異矩陣不能計算
if linalg.det(xtx) == 0.0:
print('this matrix is singular, cannot do inverse')
return
theta = xtx.i * (xmat.t * (weights * ymat)) # 計算回歸係數
return testpoint * theta
# 對所有點計算估計值
deflwlrtest
(testarr, xarr, yarr, k = 1.0):
m = shape(testarr)[0]
yhat = zeros(m)
for i in range(m):
yhat[i] = lwlr(testarr[i], xarr, yarr, k)
return yhat
(2)匯入資料並繪圖
import matplotlib.pyplot as plt
from locally_weighted_linear_regression import locallyweightedlinearregression as lwlr
from numpy import *
xarr, yarr = lwlr.loaddataset('ex0.txt')
yhat = lwlr.lwlrtest(xarr, xarr, yarr, 0.01)
xmat = mat(xarr)
strind = xmat[:, 1].argsort(0)
xsort = xmat[strind][:, 0, :]
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(xsort[:, 1], yhat[strind])
ax.scatter(xmat[:, 1].flatten().a[0], mat(yarr).t.flatten().a[0], s = 2, c = 'red')
plt.show()
(3)分別選取k=1.0,0.01,0.003繪圖如下:
圖1 k=1.0 欠擬合
圖2 k=0.01 最佳擬合
圖3 k=0.003 過擬合
四、結果分析:很明顯,當k=1.0時,回歸曲線與散點圖欠擬合(underfitting),此時權重很大,如同將所有資料視為等權重,相當於普通線性回歸模型;當k=0.01時得到了很好的效果;當k=0.003時,回歸曲線與散點圖過擬合(overfitting),由於納入了太多的雜訊點,擬合的直線與資料點過於貼近,此時也不屬於理想的模型。
機器學習 區域性加權線性回歸
線性回歸的乙個問題時又可能出現欠擬合現象,為了解決這個問題,我們可以採用乙個方法是區域性加權線性回歸 locally weighted linner regression 簡稱lwlr。該演算法的思想就是給帶 點附近的每乙個點賦予一定的權值,然後按照簡單線性回歸求解w的方法求解,與knn一樣,這種演...
區域性加權線性回歸
簡單來說,這個過程其實是在先擬合出一條曲線,然後再用這個曲線去 需要 的點。但是如果這個曲線擬合得不好 或者說樣本資料含有大量噪音 那麼這個 結果就會很差。區域性加權線性回歸 對於乙個資料集合 x0,y0 x1,y1 xm,ym 我們 它在x點時對應的y值時,如果採用的是傳統的 線性回歸模型,那麼 ...
區域性加權線性回歸
區域性加權線性回歸是機器學習裡的一種經典的方法,彌補了普通線性回歸模型欠擬合或者過擬合的問題。機器學習裡分為無監督學習和有監督學習,線性回歸裡是屬於有監督的學習。普通的線性回歸屬於引數學習演算法 parametric learning algorithm 而區域性加權線性回歸屬於非引數學習演算法 n...