'''
機器學習實戰章8
一個矩陣x(樣本數據屬性矩陣)和y(樣本數據y矩陣)可擬合出一條直線
標準線性迴歸只擬合出一條直線,局部加權線性迴歸共更新x矩陣m-1次,在相鄰兩個數據之間都回歸出直線,共得到m-1條直線,連接起來就近似曲線了
改變lwlr()函數的k值,可以改變曲線的平滑度和擬合度,大家有興趣可以試試
本代碼使用的資源和文件在文末
'''
from numpy import *
'''
該函數解析用tab鍵分離的文本文件,若該文件內有m條數據
dataMat:如其名,屬性矩陣,m x 2
labelMat:y值矩陣,m x 1
'''
def loadDataSet(fileName):
numFeat = len(open(fileName).readline().split('\t')) - 1 #獲取屬性數,前兩列是屬性,最後一列是y值
dataMat = []; labelMat = []
fr = open(fileName)
for line in fr.readlines():
lineArr =[]
curLine = line.strip().split('\t')
for i in range(numFeat):
lineArr.append(float(curLine[i]))
dataMat.append(lineArr)
labelMat.append(float(curLine[-1]))
return dataMat,labelMat #函數有多個返回值其實是返回了一個tuple
"""
標準迴歸,計算最佳擬合直線
返回m x 1的迴歸係數矩陣
"""
def standRegres(xArr,yArr):
xMat = mat(xArr); yMat = mat(yArr).T
xTx = xMat.T*xMat
if linalg.det(xTx) == 0.0:#判斷xTx矩陣行列式是否爲0,linalg是numpy提供的線性代數庫
print( "This matrix is 不可逆的, cannot 求逆")
return
ws = xTx.I * (xMat.T*yMat)
return ws
'''
加權局部線性迴歸
以待預測數據爲中心對所有樣本數據賦予一定的權重得到新x矩陣,相鄰兩點間迴歸出直線,上述過程重複m-1次,連接在一起近似平滑的曲線
k是參數,由用戶指定,這也是lwlr中唯一要考慮的參數
testPoint: 1 * 2 一條測試數據,不是一個點
weights:m * m
xMat: m * 2
yMat: m * 1
ws: 2 * 1
'''
def lwlr(testPoint,xArr,yArr,k):
xMat = mat(xArr); yMat = mat(yArr).T
m = shape(xMat)[0] # m 樣本數據數
weights = mat(eye((m))) #eye()創建m階單位矩陣,是方陣,即該矩陣爲每個樣本點初始化了一個權重1
for j in range(m):
diffMat = testPoint - xMat[j,:] #樣本點與待遇測點的距離
#exp():以e爲底的指數函數。隨着樣本點與待預測點距離遞增,權重以指數級衰減。這種設置權重的方法叫高斯核類型。
weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2))
xTx = xMat.T * (weights * xMat) # x = weights * xMat,相當於更新了x(樣本)矩陣
if linalg.det(xTx) == 0.0:
print( "This matrix cannot do inverse")
return
ws = xTx.I * (xMat.T * (weights * yMat)) #求sei ta的算法式子也更新,得到迴歸係數(sei ta)2 * 1
return testPoint * ws # 返回lwlr對testPoint(樣本數據)的預測值
'''
本函數對所有樣本數據調用lwlr(),得到所有預測值
'''
def lwlrTest(testArr,xArr,yArr,k): #loops over all the data points and applies lwlr to each one
m = shape(testArr)[0]
yHat = zeros(m)
for i in range(m):
yHat[i] = lwlr(testArr[i],xArr,yArr,k)
return yHat
"""
xarr,yarr是數組,loadDataSet()的返回值
"""
def show(xarr,yarr,yHat):
xMat = mat(xarr) # 數組轉化成矩陣 m * 2
yMat = mat(yarr) # 數組轉化成矩陣1 * m
#排序
strInd = xMat[:,1].argsort(0) #對樣本x升序排序並返回索引
xSort = xMat[strInd][:,0,:]
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(xSort[:,1],yHat[strInd])# xSort是橫座標,yHat是對應的縱座標,plot按索引順序在相鄰兩點連線。如果不排序就會來回畫
ax.scatter(xMat[:,1].flatten().A[0],yMat.T.flatten().A[0],s = 2,c = 'red') # 畫出所有原始數據
plt.show()
xarr,yarr = loadDataSet("ex0.txt")
yHat = lwlrTest(xarr,xarr,yarr,0.03)
show(xarr,yarr,yHat)
"""
print(corrcoef(yHat.T,yMat))
corrcoef(yEstimate,yActual):計算真實值和預測值的相關性,兩個參數都應是行向量
輸出
[[1. 0.98647356]
[0.98647356 1. ]]
表示相關性爲0.98647356
"""
機器學習實戰代碼百度雲:提取碼8569