機器學習實戰——標準線性迴歸和加權線性迴歸算法

'''
機器學習實戰章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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章