python实现一般最小二乘系统辨识方法
问题:
对于一个未知参数的系统,往往需要用到系统辨识的方法,例如对于一个单输入单输出系统:
Z(k)+a1*Z(k-1)+a2*Z(k-2)=b1*U(k-1)+b2*U(k-2)+V(k)
其中:V(k)=c1*v(k)+c2*v(k-1)+c3*v(k-3)
输入信号采用四阶幅值为1的M序列,高斯噪声v(k)均值为0,方差为0.1。
假设真值为a1=1.6,a2=0.7,b1=1.0,b2=0.4,c1=1.0,c2=1.6,c3=0.7。需要对以上参数进行辨识。
方法:
一般最小二乘法是系统辨识中最简单的辨识方法之一,其MATLAB实现方法十分简单,我发现网上一大把,所以我决定“翻译”一个python版的一般最小二乘辨识方法供读者参考。
本文用到的库:
import numpy as np
import matplotlib.pyplot as plt
from operator import xor
from numpy.linalg import inv
M序列的产生:
在python中,M序列的产生方法与matlab类似,先产生随机数,然后采用四阶移位寄存器滤波变换,得到我们想要的M序列。
#M序列产生
L=16
#设置M序列周期
#定义初始值
y=np.zeros(L)
u=np.zeros(L)
y1=1
y2=1
y3=1
y4=0
for i in range(0,L):
x1=xor(y3,y4)
x2=y1
x3=y2
x4=y3
y[i]=y4
if y[i]>0.5:
u[i]=-1
else:
u[i]=1
y1=x1
y2=x2
y3=x3
y4=x4
plt.figure(num=2)
x=np.linspace(0,15,16)
plt.bar(x,u,width=0.1)
plt.title('输入信号M序列')
高斯分布噪声:
这里采用的是random库中的函数,可以看到,我们设置的均值为0,方差为0.1。
#产生一组16个N(0,1)的高斯分布的随机噪声
mu=0
sigma=0.1
samplenum=16
n=np.random.normal(mu,sigma,samplenum)
plt.figure(num=1)
plt.plot(n)
plt.title("高斯分布随机噪声")
最小二乘辨识程序:
#最小二乘辨识过程
z=np.zeros(16) for k in range(2,15):
z[k]=-1.6*z[k-1]-0.7*z[k-2]+1.0*u[k-1]+0.4*u[k-2]+1.0*n[k]+1.6*n[k-1]+0.7*n[k-2] plt.figure(num=3)
plt.bar(x,z,width=0.1)
plt.title('输出观测值') H=np.array([[-z[1],-z[0],u[1],u[0]],[-z[2],-z[1],u[2],u[1]],[-z[3],-z[2],u[3],u[2]],[-z[4],-z[3],u[4],u[3]],[-z[5],-z[4],u[5],u[4]],[-z[6],-z[5],u[6],u[5]],[-z[7],-z[6],u[7],u[6]],[-z[8],-z[7],u[8],u[7]],[-z[9],-z[8],u[9],u[8]],[-z[10],-z[9],u[10],u[9]],[-z[11],-z[10],u[11],u[10]],[-z[12],-z[11],u[12],u[11]],[-z[13],-z[12],u[13],u[12]],[-z[14],-z[13],u[14],u[13]]])
Z=np.array([z[2],z[3],z[4],z[5],z[6],z[7],z[8],z[9],z[10],z[11],z[12],z[13],z[14],z[15]]) In_1=np.transpose(H)
In_2=np.dot(In_1,H)
In_3=inv(In_2)
In_4=np.dot(In_3,In_1)
c=np.dot(In_4,Z)
分离参数:
#分离参数并显示
a1=c[0]
a2=c[1]
b1=c[2]
b2=c[3]
print("a1的值是:",a1)
print("a2的值是:",a2)
print("b1的值是:",b1)
print("b2的值是:",b2)
注意:
由于在python中plt的库是不支持中文的,所以要加上这些代码,保证输出的图片标题的中文显示正常。
#显示中文字体
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
结果:
在网上找了半天python画针状图的资料,发现没有。。所以强行用瘦了的柱状图表示针状图了。
总结:
可以看出Python写的系统辨识误差还是有一些的,不过也是受到一般最小二乘参数辨识方法的限制,如果采用递推最小二乘,增广最小二乘等方法可能会进一步提高准确性。笔者尝试过递推最小二乘,但是与MATLAB相比,其代码量大大增加,因此在系统辨识方法上,不建议都用Python来写,MATLAB是个不错的选择。当然,喜欢写python的话,这都不是问题。
代码全文:
# -*- coding: utf-8 -*-
"""
Created on Wed Sep 20 16:11:27 2017
@author: Hangingter
"""
#一般最小二乘辨识 #导入相应科学计算的包
import numpy as np
import matplotlib.pyplot as plt
from operator import xor
from numpy.linalg import inv #显示中文字体
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
#产生一组16个N(0,1)的高斯分布的随机噪声
mu=0
sigma=0.1
samplenum=16
n=np.random.normal(mu,sigma,samplenum)
plt.figure(num=1)
plt.plot(n)
plt.title("高斯分布随机噪声")
#M序列产生
L=16
#设置M序列周期
#定义初始值
y=np.zeros(L)
u=np.zeros(L)
y1=1
y2=1
y3=1
y4=0
for i in range(0,L):
x1=xor(y3,y4)
x2=y1
x3=y2
x4=y3
y[i]=y4
if y[i]>0.5:
u[i]=-1
else:
u[i]=1
y1=x1
y2=x2
y3=x3
y4=x4
plt.figure(num=2)
x=np.linspace(0,15,16)
plt.bar(x,u,width=0.1)
plt.title('输入信号M序列')
#最小二乘辨识过程
z=np.zeros(16) for k in range(2,15):
z[k]=-1.6*z[k-1]-0.7*z[k-2]+1.0*u[k-1]+0.4*u[k-2]+1.0*n[k]+1.6*n[k-1]+0.7*n[k-2] plt.figure(num=3)
plt.bar(x,z,width=0.1)
plt.title('输出观测值') H=np.array([[-z[1],-z[0],u[1],u[0]],[-z[2],-z[1],u[2],u[1]],[-z[3],-z[2],u[3],u[2]],[-z[4],-z[3],u[4],u[3]],[-z[5],-z[4],u[5],u[4]],[-z[6],-z[5],u[6],u[5]],[-z[7],-z[6],u[7],u[6]],[-z[8],-z[7],u[8],u[7]],[-z[9],-z[8],u[9],u[8]],[-z[10],-z[9],u[10],u[9]],[-z[11],-z[10],u[11],u[10]],[-z[12],-z[11],u[12],u[11]],[-z[13],-z[12],u[13],u[12]],[-z[14],-z[13],u[14],u[13]]])
Z=np.array([z[2],z[3],z[4],z[5],z[6],z[7],z[8],z[9],z[10],z[11],z[12],z[13],z[14],z[15]]) In_1=np.transpose(H)
In_2=np.dot(In_1,H)
In_3=inv(In_2)
In_4=np.dot(In_3,In_1)
c=np.dot(In_4,Z) #分离参数并显示
a1=c[0]
a2=c[1]
b1=c[2]
b2=c[3]
print("a1的值是:",a1)
print("a2的值是:",a2)
print("b1的值是:",b1)
print("b2的值是:",b2)
参考:
MATLAB版的系统辨识一般最小二乘方法:
http://blog.csdn.net/sinat_20265495/article/details/51426537
python实现一般最小二乘系统辨识方法的更多相关文章
- Python知识(7)--最小二乘求解
这里展示利用python实现的最小二乘的直接求解方法.其求解原理,请参考:最小二乘法拟合非线性函数及其Matlab/Excel 实现 1.一般曲线拟合 代码如下: # -*- coding:utf-8 ...
- 用 Python 排序数据的多种方法
用 Python 排序数据的多种方法 目录 [Python HOWTOs系列]排序 Python 列表有内置就地排序的方法 list.sort(),此外还有一个内置的 sorted() 函数将一个可迭 ...
- sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO
sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO 今天在弄一个 sqlalchemy 的数据库基类的时候,遇到了跟多继承相关的一个小问题,因此顺便看了一 ...
- python子类调用父类的方法
python子类调用父类的方法 python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法.如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问, ...
- paip.编程语言方法重载实现的原理及python,php,js中实现方法重载
paip.编程语言方法重载实现的原理及python,php,js中实现方法重载 有些语言,在方法的重载上,形式上不支持函数重载,但可以通过模拟实现.. 主要原理:根据参数个数进行重载,或者使用默认值 ...
- python常用数据类型内置方法介绍
熟练掌握python常用数据类型内置方法是每个初学者必须具备的内功. 下面介绍了python常用的集中数据类型及其方法,点开源代码,其中对主要方法都进行了中文注释. 一.整型 a = 100 a.xx ...
- Python使用MySQL数据库的方法以及一个实例
使用环境:Windows+python3.4+MySQL5.5+Navicat 一.创建连接 1.准备工作,想要使用Python操作MySQL,首先需要安装MySQL-Python的包,在Python ...
- python中List的sort方法的用法
python列表排序 简单记一下python中List的sort方法(或者sorted内建函数)的用法. 关键字: python列表排序 python字典排序 sorted List的元素可以是各种东 ...
- python字符串内容替换的方法(转载)
python字符串内容替换的方法 时间:2016-03-10 06:30:46来源:网络 导读:python字符串内容替换的方法,包括单个字符替换,使用re正则匹配进行字符串模式查找与替换的方法. ...
随机推荐
- 麻省理工18年春软件构造课程阅读02“Java基础”
本文内容来自MIT_6.031_sp18: Software Construction课程的Readings部分,采用CC BY-SA 4.0协议. 由于我们学校(哈工大)大二软件构造课程的大部分素材 ...
- RGB与HSV之间的转换公式及颜色表
RGB & HSV 英文全称 RGB - Red, Green, Blue HSV - Hue, Saturation, Value HSV --> RGB 转换公式 HSV --> ...
- Kaggle新手入门之路
学完了Coursera上Andrew Ng的Machine Learning后,迫不及待地想去参加一场Kaggle的比赛,却发现从理论到实践的转变实在是太困难了,在此记录学习过程. 一:安装Anaco ...
- Java中的自定义数组队列
在Java中,作为所有数据结构中存储和获取速度最快的一种,数组凭借其这种简单易用的优势在各个方面都能大显神威.但是数组也有自身的局限性.数组的长度必须是固定的一旦定义之后就无法动态的更改,这就会造成这 ...
- Five nines
Five nines, commonly taken to mean "99.999%", may refer to: 高可用 High availability of serv ...
- C++ 监测磁盘空间
硬盘管理器 头文件 HardDiskManager.h : #if _MSC_VER > 1000 #pragma once #endif #include <windows.h> ...
- Apple 内购
关于内购所需东西: 1.测试开发证书:需要打开in-app-purchase,绑定bundleid:com.aragon.TexasPoker 2.iTunes connect 里添加内购应用: 1& ...
- equals 与 == 区别及用法
==: 1. ==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同: 2.如果要比较两个变量是否指向同一个对象,这时候就需要用==操作符进行比较: 注意:= ...
- 重新编译Linux内核必要性及其准备工作
内核简介 内核,是一个操作系统的核心.它负责管理系统的进程.内存.设备驱动程序.文件和网络系统,决定着系统的性能和稳定性. Linux的一个重要的特点就是其源代码的公开性,所有的内核源程序都可以在/u ...
- dojo之FilteringSelect
1.保证可视框宽度与下拉框宽度一致 forceWidth:'true' 2.控制下拉框的高度 maxHeight:'120'