线性模型拟合笔记

我们大学以前学到的函数大多都是单调的一个函数曲线,偶尔遇到分类讨论的函数等等,但如果在实际运用中,我们很难找到一个对应现实数据的曲线来表示我们想要表示的函数,更别说利用类似的曲线建立模型,预测数据了。

因而,我们需要运用数据算法来建立许多个y=ax+b这样的函数,然后通过一定的筛选,运算,来计算出来我们所需要的拟合过的线性函数。

1.1线性模型预测

要学会用线性模型预测,我们得先处理好数据来得到我们需要的y=kx+b的系数等等

首先我们先介绍np.linalg.lstsq(A,B)[0],这个函数功能性很强

不过我们得先得到X和Y的值,这里的xy就是对应上述公式中的AB。而这里X里右边加了一列1就是为了能在矩阵相乘的时候得到y=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+01
  9.23510942e+00  5.64371349e+01  3.39752190e+02  1.09966123e+01
  1.17850355e+02  3.62349967e+02  1.71766016e+01  3.60095747e+02
  1.50182872e+02  1.55346049e+02  1.68522321e+02  1.07359014e+02
  1.07221832e+02  9.92455079e+01]

这里我们选用n=4来进行拟合,我们也可以改变n的值来看n为多少时曲线更能拟合。

这里我们 x=np.linalg.lstsq(A,B)[0],因此x的值就是函数里的k和b的集合,然后将B.dot(x)就是将矩阵数字相乘后相加,完成了kx+b的步骤,因此我们可以得到pred值,这个值因为我们原函数里有实际值,所以可以进行一定的对比,几乎是近似的,因此说明拟合曲线有一定的效果

1.2趋势线

当我们并不需要完全拟合数据,单纯就是表现函数趋势的时候我们会选用趋势线

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来方便后续进行计算,然后是用1.1里介绍的linalg.lstsq来求得k和b这里直接用x【0】表示k,x【1】表示b,然后算出trendline的函数曲线

2.多函数运算

2.1协方差

在面对两个股票的时候,我们可以通过计算协方差来判断他们的趋势,他们的相关性大小等等,借此我们有时可以通过一个股票来预测另外一个股票的趋势

 这里我们可以通过两组随机数初步认识协方差的计算步骤,首先我们得算出平均数,接着离差就是原数组和平均数的差,最后cov就是我们的协方差,协方差为正就说明两个数组正相关,一个越大,另外一个也越大

2.2相关系数,相关矩阵,协方差矩阵

 相关系数是基于协方差基础之上的,相关系数绝对值越大,说明两个函数的关系越强,反之则越弱

相关矩阵则是根据相关系数来构成的,主对角线上为1,就是函数与自己的相关性,副对角线上就是两个函数对各自的相关系数

协方差矩阵和协方差的数据稍微有点不同,因为单纯协方差运算时,只靠样本来运算,而协方差矩阵时总体数组进行计算,因此数据会有所偏差

这里我们通过实例来了解一下

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        )
#计算两只股票协方差
#平均值
ave_a=aclosing_price.mean()
ave_b=bclosing_price.mean()
#离差
dev_a=aclosing_price-ave_a
dev_b=bclosing_price-ave_b

#协方差
cov=np.mean(dev_a*dev_b)
print(cov)
#相关系数
coef=cov/(np.std(aclosing_price)*np.std(bclosing_price))
print(coef)
#相关矩阵
m=np.corrcoef(aclosing_price ,bclosing_price)
print(m)

#协方差矩阵
print(np.cov(aclosing_price ,bclosing_price))

可以看到输出的第二个就是相关系数,与第三个输出的相关系数的副对角线上数值相同,而协方差矩阵中0.0018稍微比样本运算的0.0017稍微大了一点也可见一斑,计算上并不会有太大影响。

3.多项式拟合

3.1polyfit,polyval,polyder,roots方法

在了解多项式拟合的时候,我们得先了解这个过程

1).#根据一组样本,给出最高次幂,求出拟合系数
np.polyfit(x,y,最高次幂)->P

这里的P就是y=kx**n+k1x**中的未知数系数【k,k1】这样,当我们已知x和y的时候,可以规定一个最高次幂类似于3,4这样来得到P

2)#根据拟合系数和自变量求得拟合数
np.polyval(P,X)->y'

我们要注意,这里的y是y’了,是我们想要拟合的函数的y而不是原函数的y,通过刚刚第一步求得的P,就可以算出来y‘

3)#根据拟合系数求得多项式导函数的导数
np.polyder(P)->Q

相比大学里学用的导数,这里只用一个公式就可以算出来函数对于x的一阶求导后函数的系数,算是很方便的式子

4)#已知多项式系数Q求得函数根
np.root(Q)->根

最后一步就是通过刚刚我们求得到的Q来算出原方程的根,即函数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='原函数')
plt.scatter(xs,ys,label='根函数',c='r',s=100)

通过这个方法,我们就可以找到函数的根

3.2拟合函数

其实在刚刚3.1中就涉及到了拟合函数的概念,我们可以通过P和X来得到拟合过的线性函数

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)
#绘制差价函数曲线
diff_price=aclosing_price-bclosing_price
plt.plot(date,diff_price,c='dodgerblue',label='差价函数曲线')
#拟合差价函数
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='拟合差价函数'
        ,color='r'
        ,ls='--',alpha=0.5,linewidth=2    )

 

这里的poly_price就是新拟合出来的y’,对待两个股票的差价组成的函数,我们可以通过线性拟合函数得知函数的趋势以及预测数据

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值