线性模型拟合笔记
我們大學以前學到的函數(shù)大多都是單調(diào)的一個函數(shù)曲線,偶爾遇到分類討論的函數(shù)等等,但如果在實際運用中,我們很難找到一個對應現(xiàn)實數(shù)據(jù)的曲線來表示我們想要表示的函數(shù),更別說利用類似的曲線建立模型,預測數(shù)據(jù)了。
因而,我們需要運用數(shù)據(jù)算法來建立許多個y=ax+b這樣的函數(shù),然后通過一定的篩選,運算,來計算出來我們所需要的擬合過的線性函數(shù)。
1.1線性模型預測
要學會用線性模型預測,我們得先處理好數(shù)據(jù)來得到我們需要的y=kx+b的系數(shù)等等
首先我們先介紹np.linalg.lstsq(A,B)[0],這個函數(shù)功能性很強
不過我們得先得到X和Y的值,這里的xy就是對應上述公式中的AB。而這里X里右邊加了一列1就是為了能在矩陣相乘的時候得到y(tǒng)=kx+b這樣比較干凈的式子,這里可以通過實例介紹一下。
date=np.linspace(1,31,30)
np.random.seed(1)
h=np.random.randint(1,100,size=30)
plt.figure('random stock',facecolor='lightgray')
plt.title('random stock',fontsize=18)
plt.xlabel('日期',fontsize=14)
plt.ylabel('股值',fontsize=14)
plt.grid()
plt.gca().xaxis.set_major_formatter(ticker.FormatStrFormatter('%.f日'))
plt.gca().yaxis.set_major_formatter(ticker.FormatStrFormatter('%.f比率'))
mean=np.mean(h)
plt.plot(date,h,label='Actual'
??????? ,color='r'
??????? ,ls='--',alpha=0.2)
#整理A和B
N=4
pred_price=np.zeros(30-N*2)
for i in range(pred_price.size):
??? A=np.zeros((N,N))
??? for j in range(N):
??????? A[j, ]=h[i+j:i+j+N]
??? B=h[i+N:i+N*2]
??? x=np.linalg.lstsq(A,B)[0]
??? pred=B.dot(x)
??? pred_price[i]=pred
print(x)
print(A)
print(B)
#預測
print(pred_price)
#實際
plt.plot(date[N*2:],pred_price,
??????? marker='o',color='orangered',
??????? label='Prediction')
?
輸出值:
x:[-0.88450763 1.04683535 1.0525915 -0.28124775] A:[[15. 51. 69. 88.][51. 69. 88. 88.][69. 88. 88. 95.][88. 88. 95. 97.]] B:[88 95 97 87] pred_price:[ 6.46750295e+03 -5.55541783e+03 3.14212281e+02 7.57373027e+01-2.29655198e+01 -5.24244331e+00 9.29324887e+01 -1.06184268e+019.23510942e+00 5.64371349e+01 3.39752190e+02 1.09966123e+011.17850355e+02 3.62349967e+02 1.71766016e+01 3.60095747e+021.50182872e+02 1.55346049e+02 1.68522321e+02 1.07359014e+021.07221832e+02 9.92455079e+01]這里我們選用n=4來進行擬合,我們也可以改變n的值來看n為多少時曲線更能擬合。
這里我們 x=np.linalg.lstsq(A,B)[0],因此x的值就是函數(shù)里的k和b的集合,然后將B.dot(x)就是將矩陣數(shù)字相乘后相加,完成了kx+b的步驟,因此我們可以得到pred值,這個值因為我們原函數(shù)里有實際值,所以可以進行一定的對比,幾乎是近似的,因此說明擬合曲線有一定的效果
1.2趨勢線
當我們并不需要完全擬合數(shù)據(jù),單純就是表現(xiàn)函數(shù)趨勢的時候我們會選用趨勢線
date,opening_price,highest_price,lowest_price,closing_price=np.loadtxt('30a.csv'
????????? ,delimiter=','
????????? ,usecols=(0,1,2,4,3),
????????? unpack=True,
????????? dtype='M8[D],f8,f8,f8,f8',
????????? )
days=date.astype(int)
print(len(days))
trendprice=(highest_price+lowest_price+closing_price)/3
plt.xticks(rotation=45)
plt.plot(date,closing_price,label='Actual'
??????? ,color='r'
??????? ,ls='--',alpha=0.5??????? )
plt.scatter(date,trendprice,label='Trend',
?????????? color='b',marker='D',
?????????? s=80)
A=np.column_stack((days,np.ones_like(days)))
B=trendprice
x=np.linalg.lstsq(A,B)[0]
trend_line=x[0]*days +x[1]
plt.plot(date,trend_line,
??????? color='g',label='TrendLine')??????? ?
plt.gcf()
不過在這里我們首先是先求出了趨勢點,把每天的收盤價最高價最低價求了平均值,然后通過散點圖進行標記
A=np.column_stack((days,np.ones_like(days)))注意這里的column_stack,其實就是對于我前面說的將X中右邊一列全都化成1來方便后續(xù)進行計算,然后是用1.1里介紹的linalg.lstsq來求得k和b這里直接用x【0】表示k,x【1】表示b,然后算出trendline的函數(shù)曲線
2.多函數(shù)運算
2.1協(xié)方差
在面對兩個股票的時候,我們可以通過計算協(xié)方差來判斷他們的趨勢,他們的相關性大小等等,借此我們有時可以通過一個股票來預測另外一個股票的趨勢
?這里我們可以通過兩組隨機數(shù)初步認識協(xié)方差的計算步驟,首先我們得算出平均數(shù),接著離差就是原數(shù)組和平均數(shù)的差,最后cov就是我們的協(xié)方差,協(xié)方差為正就說明兩個數(shù)組正相關,一個越大,另外一個也越大
2.2相關系數(shù),相關矩陣,協(xié)方差矩陣
?相關系數(shù)是基于協(xié)方差基礎之上的,相關系數(shù)絕對值越大,說明兩個函數(shù)的關系越強,反之則越弱
相關矩陣則是根據(jù)相關系數(shù)來構成的,主對角線上為1,就是函數(shù)與自己的相關性,副對角線上就是兩個函數(shù)對各自的相關系數(shù)
協(xié)方差矩陣和協(xié)方差的數(shù)據(jù)稍微有點不同,因為單純協(xié)方差運算時,只靠樣本來運算,而協(xié)方差矩陣時總體數(shù)組進行計算,因此數(shù)據(jù)會有所偏差
這里我們通過實例來了解一下
date,aclosing_price=np.loadtxt('30a.csv'
????????? ,delimiter=','
????????? ,usecols=(0,3),
????????? unpack=True,
????????? dtype='M8[D],f8',
????????? )
bclosing_price=np.loadtxt('30b.csv'
????????? ,delimiter=','
????????? ,usecols=(3),
????????? unpack=True,
????????? dtype='f8',
????????? )
#繪制收盤價折線圖
plt.figure('COV',facecolor='lightgray')
plt.title('COV',fontsize=18)
plt.xlabel('date',fontsize=14)
plt.ylabel('closingprice',fontsize=14)
plt.grid(ls=":")
import matplotlib.dates as md
ax=plt.gca()
ax.xaxis.set_major_locator(md.WeekdayLocator(byweekday=md.MO))
ax.xaxis.set_major_formatter(md.DateFormatter('%d %b %y'))
ax.xaxis.set_minor_locator(md.DayLocator())
date=date.astype(md.datetime.datetime)
plt.plot(date,aclosing_price,label='a30股票'
??????? ,color='r'
??????? ,ls='--',alpha=0.5??????? )
plt.plot(date,bclosing_price,label='b30股票'
??????? ,color='b'
??????? ,ls='-',alpha=0.5??????? )
#計算兩只股票協(xié)方差
#平均值
ave_a=aclosing_price.mean()
ave_b=bclosing_price.mean()
#離差
dev_a=aclosing_price-ave_a
dev_b=bclosing_price-ave_b
#協(xié)方差
cov=np.mean(dev_a*dev_b)
print(cov)
#相關系數(shù)
coef=cov/(np.std(aclosing_price)*np.std(bclosing_price))
print(coef)
#相關矩陣
m=np.corrcoef(aclosing_price ,bclosing_price)
print(m)
#協(xié)方差矩陣
print(np.cov(aclosing_price ,bclosing_price))
可以看到輸出的第二個就是相關系數(shù),與第三個輸出的相關系數(shù)的副對角線上數(shù)值相同,而協(xié)方差矩陣中0.0018稍微比樣本運算的0.0017稍微大了一點也可見一斑,計算上并不會有太大影響。
3.多項式擬合
3.1polyfit,polyval,polyder,roots方法
在了解多項式擬合的時候,我們得先了解這個過程
1).#根據(jù)一組樣本,給出最高次冪,求出擬合系數(shù)
np.polyfit(x,y,最高次冪)->P
這里的P就是y=kx**n+k1x**中的未知數(shù)系數(shù)【k,k1】這樣,當我們已知x和y的時候,可以規(guī)定一個最高次冪類似于3,4這樣來得到P
2)#根據(jù)擬合系數(shù)和自變量求得擬合數(shù)
np.polyval(P,X)->y'
我們要注意,這里的y是y’了,是我們想要擬合的函數(shù)的y而不是原函數(shù)的y,通過剛剛第一步求得的P,就可以算出來y‘
3)#根據(jù)擬合系數(shù)求得多項式導函數(shù)的導數(shù)
np.polyder(P)->Q
相比大學里學用的導數(shù),這里只用一個公式就可以算出來函數(shù)對于x的一階求導后函數(shù)的系數(shù),算是很方便的式子
4)#已知多項式系數(shù)Q求得函數(shù)根
np.root(Q)->根
最后一步就是通過剛剛我們求得到的Q來算出原方程的根,即函數(shù)k為0的時候類似的解
P=[4,3,-1000,1]
x=np.linspace(-20,20,1000)
y=np.polyval(P,x)
Q=np.polyder(P)
xs=np.roots(Q)
ys=np.polyval(P,xs)
plt.plot(x,y,label='原函數(shù)')
plt.scatter(xs,ys,label='根函數(shù)',c='r',s=100)
通過這個方法,我們就可以找到函數(shù)的根
3.2擬合函數(shù)
其實在剛剛3.1中就涉及到了擬合函數(shù)的概念,我們可以通過P和X來得到擬合過的線性函數(shù)
date,aclosing_price=np.loadtxt('30a.csv'
????????? ,delimiter=','
????????? ,usecols=(0,3),
????????? unpack=True,
????????? dtype='M8[D],f8',
????????? )
bclosing_price=np.loadtxt('30b.csv'
????????? ,delimiter=','
????????? ,usecols=(3),
????????? unpack=True,
????????? dtype='f8',
????????? )
ax=plt.gca()
ax.xaxis.set_major_locator(md.WeekdayLocator(byweekday=md.MO))
ax.xaxis.set_major_formatter(md.DateFormatter('%d %b %y'))
ax.xaxis.set_minor_locator(md.DayLocator())
date=date.astype(md.datetime.datetime)
#繪制差價函數(shù)曲線
diff_price=aclosing_price-bclosing_price
plt.plot(date,diff_price,c='dodgerblue',label='差價函數(shù)曲線')
#擬合差價函數(shù)
days=date.astype('M8[D]').astype('int32')
P=np.polyfit(days,diff_price,20)
poly_price=np.polyval(P,days)
plt.plot(date,poly_price,label='擬合差價函數(shù)'
??????? ,color='r'
??????? ,ls='--',alpha=0.5,linewidth=2??? )
?
這里的poly_price就是新擬合出來的y’,對待兩個股票的差價組成的函數(shù),我們可以通過線性擬合函數(shù)得知函數(shù)的趨勢以及預測數(shù)據(jù)
?
?
?
總結
- 上一篇: 解决windows10和ubuntu双系
- 下一篇: 数据库中创建存储过程的方法