日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python实现线性回归预测_机器学习实战笔记(Python实现)-08-线性回归

發布時間:2025/3/12 python 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python实现线性回归预测_机器学习实战笔记(Python实现)-08-线性回归 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

---------------------------------------------------------------------------------------

本系列文章為《機器學習實戰》學習筆記,內容整理自書本,網絡以及自己的理解,如有錯誤歡迎指正。

---------------------------------------------------------------------------------------

1、線性回歸

現有一數據集,其分布如下圖所示,

通過觀察發現可以通過一個線性方程去擬合這些數據點。可設直線方程為 y=wx. 其中w稱為回歸系數。那么現在的問題是,如何從一堆x和對應的y中確定w?一個常用的方法就是找出使誤差最小的w。這里的誤差是指預測y值和真實y值之間的差值,我們采用平方誤差,寫作:

用矩陣還可以寫作:

?,如果對w求導,得到

,令其等于零,解出w為:

注意此處公式包含對矩陣求逆,所以求解時需要先對矩陣是否可逆做出判斷。以上求解w的過程也稱為“普通最小二乘法”。

Python實現代碼如下:

1 from numpy import *

2

3 defloadDataSet(fileName):4 '''導入數據'''

5 numFeat = len(open(fileName).readline().split('\t')) - 1

6 dataMat = []; labelMat =[]7 fr =open(fileName)8 for line infr.readlines():9 lineArr =[]10 curLine = line.strip().split('\t')11 for i inrange(numFeat):12 lineArr.append(float(curLine[i]))13 dataMat.append(lineArr)14 labelMat.append(float(curLine[-1]))15 returndataMat,labelMat16

17 defstandRegres(xArr,yArr):18 '''求回歸系數'''

19 xMat = mat(xArr); yMat =mat(yArr).T20 xTx = xMat.T*xMat21 if linalg.det(xTx) == 0.0:#判斷行列式是否為0

22 print("This matrix is singular, cannot do inverse")23 return

24 ws = xTx.I * (xMat.T*yMat)#也可以用NumPy庫的函數求解:ws=linalg.solve(xTx,xMat.T*yMatT)

25 returnws26

27 if __name__ == "__main__":28 '''線性回歸'''

29 xArr,yArr=loadDataSet('ex0.txt')30 ws=standRegres(xArr,yArr)31 xMat=mat(xArr)32 yMat=mat(yArr)33 #預測值

34 yHat=xMat*ws35

36 #計算預測值和真實值得相關性

37 corrcoef(yHat.T,yMat)#0.986

38

39 #繪制數據集散點圖和最佳擬合直線圖

40 #創建圖像并繪出原始的數據

41 importmatplotlib.pyplot as plt42 fig=plt.figure()43 ax=fig.add_subplot(111)44 ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0])45 #繪最佳擬合直線,需先要將點按照升序排列

46 xCopy=xMat.copy()47 xCopy.sort(0)48 yHat = xCopy*ws49 ax.plot(xCopy[:,1],yHat)50 plt.show()

幾乎任一數據集都可以用上述方法建立模型,只是需要判斷模型的好壞,計算預測值yHat和實際值yMat這兩個序列的相關系數,可以查看它們的匹配程度。

2、局部加權線性回歸

局部加權線性回歸給待預測點附近的每個點賦予一定的權重,用于解決線性回歸可能出現的欠擬合現象。與kNN法類似,這種算法每次預測均需要事先選取出對應的數據子集,然后在這個子集上基于最小均分差來進行普通的回歸。該算法解出回歸系數的形式如下:

其中w是一個權重矩陣,通常采用核函數來對附近的點賦予權重,最常用的核函數是高斯核,如下:

這樣就構建了一個只含對角元素的權重矩陣W并且點x與x(i)越近,w(i,i)將會越大,k值控制衰減速度,且k值越小被選用于訓練回歸模型的數據集越小。

Python實現代碼:

1 def lwlr(testPoint,xArr,yArr,k=1.0):2 '''局部加權線性回歸函數'''

3 xMat = mat(xArr); yMat =mat(yArr).T4 m =shape(xMat)[0]5 weights = mat(eye((m)))#創建對角矩陣

6 for j inrange(m):7 diffMat = testPoint -xMat[j,:]8 #高斯核計算權重

9 weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2))10 xTx = xMat.T * (weights *xMat)11 if linalg.det(xTx) == 0.0:12 print("This matrix is singular, cannot do inverse")13 return

14 ws = xTx.I * (xMat.T * (weights *yMat))15 return testPoint *ws16

17 def lwlrTest(testArr,xArr,yArr,k=1.0):18 '''為數據集中每個點調用lwlr()'''

19 m =shape(testArr)[0]20 yHat =zeros(m)21 for i inrange(m):22 yHat[i] =lwlr(testArr[i],xArr,yArr,k)23 returnyHat24

25 if __name__ == "__main__":26 '''局部加權線性回歸'''

27 xArr,yArr=loadDataSet('ex0.txt')28 #擬合

29 yHat=lwlrTest(xArr,xArr,yArr,0.01)30 #繪圖

31 xMat=mat(xArr)32 yMat=mat(yArr)33 srtInd = xMat[:,1].argsort(0)34 xSort=xMat[srtInd][:,0,:]35 importmatplotlib.pyplot as plt36 fig=plt.figure()37 ax=fig.add_subplot(111)38 ax.plot(xSort[:,1],yHat[srtInd])39 ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0],s=2,c='red')40 plt.show()

k取0.01的結果

實際上,對k取不同值時有如下結果:

3、嶺回歸

如果數據的特征比樣本點多(n>m),也就是說輸入數據的矩陣x不是滿秩矩陣。而非滿秩矩陣在求逆時會出錯,所以此時不能使用之前的線性回歸方法。為解決這個問題,統計學家引入了嶺回歸的概念。

簡單來說,嶺回歸就是在矩陣xTx上加一個λI從而使得矩陣非奇異,進而能對?xTx+λI 求逆,其中I是一個mxm的單位矩陣。在這種情況下,回歸系數的計算公式將變成:

這里通過引入λ來限制了所有w之和,通過引入該懲罰項,能減少不重要的參數,這個技術在統計學中也叫縮減。

Python實現代碼:

1 def ridgeRegres(xMat,yMat,lam=0.2):2 '''計算嶺回歸系數'''

3 xTx = xMat.T*xMat4 denom = xTx + eye(shape(xMat)[1])*lam5 if linalg.det(denom) == 0.0:6 print("This matrix is singular, cannot do inverse")7 return

8 ws = denom.I * (xMat.T*yMat)9 returnws10

11 defridgeTest(xArr,yArr):12 '''用于在一組lambda上測試結果'''

13 xMat = mat(xArr); yMat=mat(yArr).T14 yMean =mean(yMat,0)15 yMat = yMat - yMean #數據標準化

16 xMeans =mean(xMat,0)17 xVar =var(xMat,0)18 xMat = (xMat - xMeans)/xVar #所有特征減去各自的均值并除以方差

19 numTestPts = 30 #取30個不同的lambda調用函數

20 wMat = zeros((numTestPts,shape(xMat)[1]))21 for i inrange(numTestPts):22 ws = ridgeRegres(xMat,yMat,exp(i-10))23 wMat[i,:]=ws.T24 returnwMat25

26 if __name__ == "__main__":27 '''嶺回歸'''

28 abX,abY=loadDataSet('abalone.txt')29 ridgeWeights = ridgeTest(abX,abY)#得到30組回歸系數

30 #縮減效果圖

31 importmatplotlib.pyplot as plt32 fig=plt.figure()33 ax=fig.add_subplot(111)34 ax.plot(ridgeWeights)35 plt.show()

運行之后得到下圖,橫軸表示第i組數據,縱軸表示該組數據對應的回歸系數值。從程序中可以看出lambda的取值為?exp(i-10) 其中i=0~29。所以結果圖的最左邊,即λ最小時,可以得到所有系數的原始值(與線性回歸一致);而在右邊,系數全部縮減為0;在中間部分的某些值可以取得最好的預測效果。

4、前向逐步回歸

前向逐步回歸算法屬于一種貪心算法,即每一步盡可能減少誤差。一開始,所有的權重都設為1,然后每一步所做的決策是對某個權重增加或減少一個很小的值。

該算法偽代碼如下所示:

Python實現代碼:

1 defregularize(xMat):2 '''數據標準化函數'''

3 inMat =xMat.copy()4 inMeans =mean(inMat,0)5 inVar =var(inMat,0)6 inMat = (inMat - inMeans)/inVar7 returninMat8

9 defrssError(yArr,yHatArr):10 '''計算均方誤差大小'''

11 return ((yArr-yHatArr)**2).sum()12

13 def stageWise(xArr,yArr,eps=0.01,numIt=100):14 '''

15 逐步線性回歸算法16 eps:表示每次迭代需要調整的步長17 '''

18 xMat = mat(xArr); yMat=mat(yArr).T19 yMean =mean(yMat,0)20 yMat = yMat -yMean21 xMat =regularize(xMat)22 m,n=shape(xMat)23 returnMat = zeros((numIt,n)) #testing code remove

24 #為了實現貪心算法建立ws的兩份副本

25 ws = zeros((n,1)); wsTest = ws.copy(); wsMax =ws.copy()26 for i inrange(numIt):27 print(ws.T)28 lowestError =inf;29 for j in range(n):#對每個特征

30 for sign in [-1,1]:#分別計算增加或減少該特征對誤差的影響

31 wsTest =ws.copy()32 wsTest[j] += eps*sign33 yTest = xMat*wsTest34 rssE =rssError(yMat.A,yTest.A)35 #取最小誤差

36 if rssE <37 lowesterror="rssE38" wsmax="wsTest39" ws="wsMax.copy()40" returnmat returnreturnmat42>

43 if __name__ == "__main__":44 '''前向逐步線性回歸'''

45 abX,abY=loadDataSet('abalone.txt')46 stageWise(abX,abY,0.01,200)

運行結果如下:

上述結果中值得注意的是w1和w6都是0,這表明它們不對目標值造成任何影響,也就是說這些特征很可能是不需要的。另外,第一個權重在0.04和0.05之間來回震蕩,這是因為步長eps太大的緣故,一段時間后系數就已經飽和并在特定值之間來回震蕩。

5、實例:預測樂高玩具套裝的價格

5.1 收集數據

原書介紹了從Google上在線獲取數據的方式,但是經測試該網址已經不可用,此處采用從離線網頁中爬取的方式收集數據。實現代碼如下:

1 defsetDataCollect(retX, retY):2 '''數據獲取方式一(不可用)'''

3 #searchForSet(retX, retY, 8288, 2006, 800, 49.99)

4 #searchForSet(retX, retY, 10030, 2002, 3096, 269.99)

5 #searchForSet(retX, retY, 10179, 2007, 5195, 499.99)

6 #searchForSet(retX, retY, 10181, 2007, 3428, 199.99)

7 #searchForSet(retX, retY, 10189, 2008, 5922, 299.99)

8 #searchForSet(retX, retY, 10196, 2009, 3263, 249.99)

9 '''數據獲取方式二'''

10 scrapePage("setHtml/lego8288.html","data/lego8288.txt",2006, 800, 49.99)11 scrapePage("setHtml/lego10030.html","data/lego10030.txt", 2002, 3096, 269.99)12 scrapePage("setHtml/lego10179.html","data/lego10179.txt", 2007, 5195, 499.99)13 scrapePage("setHtml/lego10181.html","data/lego10181.txt", 2007, 3428, 199.99)14 scrapePage("setHtml/lego10189.html","data/lego10189.txt", 2008, 5922, 299.99)15 scrapePage("setHtml/lego10196.html","data/lego10196.txt", 2009, 3263, 249.99)16

17 defscrapePage(inFile,outFile,yr,numPce,origPrc):18 from bs4 importBeautifulSoup19 fr = open(inFile,'r',encoding= 'utf8'); fw=open(outFile,'a') #a is append mode writing

20 soup =BeautifulSoup(fr.read())21 i=1

22 currentRow = soup.findAll('table', r="%d" %i)23 while(len(currentRow)!=0):24 title = currentRow[0].findAll('a')[1].text25 lwrTitle =title.lower()26 if (lwrTitle.find('new') > -1) or (lwrTitle.find('nisb') > -1):27 newFlag = 1.0

28 else:29 newFlag = 0.0

30 soldUnicde = currentRow[0].findAll('td')[3].findAll('span')31 if len(soldUnicde)==0:32 print("item #%d did not sell" %i)33 else:34 soldPrice = currentRow[0].findAll('td')[4]35 priceStr =soldPrice.text36 priceStr = priceStr.replace('$','') #strips out $

37 priceStr = priceStr.replace(',','') #strips out ,

38 if len(soldPrice)>1:39 priceStr = priceStr.replace('Free shipping', '') #strips out Free Shipping

40 print("%s\t%d\t%s" %(priceStr,newFlag,title))41 fw.write("%d\t%d\t%d\t%f\t%s\n" %(yr,numPce,newFlag,origPrc,priceStr))42 i += 1

43 currentRow = soup.findAll('table', r="%d" %i)44 fw.close()45

46 if __name__ == "__main__":47 '''樂高玩具價格預測'''

48   #爬取數據49   setDataCollect()

50 #讀取數據,這里已將以上方式獲取到的數據文本整合成為一個文件即legoAllData.txt

51 xmat,ymat = loadDataSet("data/legoAllData.txt")

5.2 訓練算法

首先我們用普通的線性回歸模型擬合數據看效果,擬合之前需要先添加對應常數項的特征X0

1 if __name__ == "__main__":2 '''樂高玩具價格預測'''

3 #爬取數據

4 #setDataCollect()

5 #讀取數據,這里已將以上方式獲取到的數據文本整合成為一個文件即legoAllData.txt

6 #xMat,yMat = loadDataSet("data/legoAllData.txt")

7 #添加對應常數項的特征X0(X0=1)

8 lgX=mat(ones((76,5)))9 lgX[:,1:5]=mat(xmat)10 lgY=mat(ymat).T11

12 #用標準回歸方程擬合

13 ws1=standRegres(lgX,mat(ymat)) #求標準回歸系數

14 yHat = lgX*ws1 #預測值

15 err1 = rssError(lgY.A,yHat.A) #計算平方誤差

16 cor1 = corrcoef(yHat.T,lgY.T) #計算預測值和真實值得相關性

測試結果為相關性cor1:0.7922,平方誤差和err1:3552526,顯然擬合效果還可以進一步提升。

接下來我們用交叉驗證測試嶺回歸:

1 def crossValidation(xArr,yArr,numVal=10):2 '''

3 交叉驗證測試嶺回歸4 numVal:交叉驗證次數5 '''

6 m =len(yArr)7 indexList =list(range(m))8 errorMat = zeros((numVal,30))9 for i inrange(numVal):10 trainX=[]; trainY=[]11 testX = []; testY =[]12 random.shuffle(indexList)#打亂順序

13 for j in range(m):#構建訓練和測試數據,10%用于測試

14 if j < m*0.9:15 trainX.append(xArr[indexList[j]])16 trainY.append(yArr[indexList[j]])17 else:18 testX.append(xArr[indexList[j]])19 testY.append(yArr[indexList[j]])20 wMat = ridgeTest(trainX,trainY) #30組不同參數下的回歸系數集

21 for k in range(30):#遍歷30個回歸系數集

22 matTestX = mat(testX); matTrainX=mat(trainX)23 meanTrain =mean(matTrainX,0)24 varTrain =var(matTrainX,0)25 matTestX = (matTestX-meanTrain)/varTrain #用訓練參數標準化測試數據

26 yEst = matTestX * mat(wMat[k,:]).T + mean(trainY)#預測值

27 errorMat[i,k]=rssError(yEst.T.A,array(testY))#計算預測平方誤差

28 #print(errorMat[i,k])

29 #在完成所有交叉驗證后,errorMat保存了ridgeTest()每個lambda對應的多個誤差值

30 meanErrors = mean(errorMat,0)#計算每組平均誤差

31 minMean =float(min(meanErrors))32 bestWeights = wMat[nonzero(meanErrors==minMean)]#平均誤差最小的組的回歸系數即為所求最佳

33 #嶺回歸使用了數據標準化,而strandRegres()則沒有,因此為了將上述比較可視化還需將數據還原

34 xMat = mat(xArr); yMat=mat(yArr).T35 meanX = mean(xMat,0); varX =var(xMat,0)36 unReg = bestWeights/varX #還原后的回歸系數

37 constant = -1*sum(multiply(meanX,unReg)) + mean(yMat) #常數項

38 print("the best model from Ridge Regression is:\n",unReg)39 print("with constant term:",constant)40 returnunReg,constant41

42

43 if __name__ == "__main__":44 '''樂高玩具價格預測'''

45 #用交叉驗證測試嶺回歸

46 ws2,constant = crossValidation(xmat,ymat,10)47 yHat2 = mat(xmat)*ws2.T +constant48 err2 =rssError(lgY.A,yHat2.A)49 cor2 = corrcoef(yHat2.T,lgY.T)

測試結果為相關性cor2:0.7874,平方誤差和err2:3827083,與最小二乘法比較好并沒有太大差異。其實這種分析方法使得我們可以挖掘大量數據的內在規律。在僅有4個特征時,該方法的效果也許并不明顯;但如果有100個以上的特征,該方法就會變得十分有效:它可以指出哪些特征是關鍵的,而哪些特征是不重要的。

THE END.

37>

總結

以上是生活随笔為你收集整理的python实现线性回归预测_机器学习实战笔记(Python实现)-08-线性回归的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 另类激情亚洲 | 美国色综合 | 中文字幕在线播放第一页 | 欧美一级无毛 | 国产一区二区三区视频在线 | 18在线观看视频 | 日本一二三不卡 | 亚洲免费精品视频在线观看 | 中日精品一色哟哟 | 亚洲日本香蕉视频 | 天堂久久精品 | 精品乱子伦一区二区三区 | 视频二区 | 久草视频中文在线 | 高清久久 | 欧美一区二区三区公司 | 亚洲无线观看 | 国产一区二区a | 尤物网站在线观看 | av在线免费网站 | 玖草视频在线观看 | 国产精品久久中文字幕 | 国产大学生自拍视频 | 美女高潮在线 | 午夜精产品一区二区在线观看的 | 国产一区二区三区播放 | 成人性生交大片免费看 | 奇米成人影视 | 日韩av在线播放不卡 | 久久久久久中文 | 日本亲子乱子伦xxxx50路 | 一本大道熟女人妻中文字幕在线 | 美日韩一区二区三区 | 亚洲图色在线 | 中文成人在线 | 最新国产在线视频 | 国产第十页 | 色香影视 | 亚洲国产精品久久久久久 | 夜夜嗨国产 | 国产不卡在线视频 | 在线超碰av | 黄网站在线免费看 | 亚洲精品高清在线 | 欧美成人一区二区三区高清 | 91精品久久久久久久 | 久久精品国产露脸对白 | 色猫咪av在线 | 日日摸日日添日日碰9学生露脸 | 国产午夜精品久久久久久久久久 | 欧美做受69 | av夜夜| 亚洲蜜桃精久久久久久久久久久久 | jizz免费视频 | 日本人妻不卡一区二区三区中文字幕 | 成年人免费看黄色 | 乌克兰做爰xxxⅹ性视频 | 99久久网站 | 中文字幕88页 | 日韩女同互慰一区二区 | 悠悠色综合网 | ww黄色| 国产黄站| 都市激情亚洲一区 | av网站网址 | 日韩资源在线观看 | 亚洲成人精品一区 | 日本不卡二区 | 久久精品国产欧美亚洲人人爽 | 综合精品| 97国产精品人人爽人人做 | 看了下面会湿的视频 | www香蕉视频 | 久久久久久国产精品免费免费 | 国产女主播自拍 | 在线观看视频www | 操极品| xxxxwwww国产| 日本精品在线观看 | 免费看日产一区二区三区 | 久久国语对白 | 欧美理论在线 | 久久国产乱子伦精品 | 欧美日韩色片 | 夜夜嗨av一区二区三区四区 | 中文字幕第十一页 | 无码精品人妻一二三区红粉影视 | 91高清免费视频 | 韩国一区二区在线观看 | 日韩人妻一区 | 国产熟妇一区二区三区aⅴ网站 | 日韩欧美一区二区三区久久婷婷 | 免费看60分钟黄视频 | 97精品在线视频 | 美女视频在线观看免费 | 性欧美日韩| 超碰人人人 | 日日骑夜夜操 | 欧美日韩在线观看视频 |