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正则匹配进行字符串模式查找与替换的方法. ...
随机推荐
- 在Centos环境下安装兼容Apache2.4高版本SVN服务
在阿里云Centos环境下,搭建PHP运行环境,PHP选择了php7版本,Mysql选择了5.7版本,Apache选择了2.4版本,在搭建SVN版本控制服务过程中出现了不兼容问题,当前环境下Apach ...
- json字符串转换成json对象,json对象转换成字符串,值转换成字符串,字符串转成值
一.json相关概念 json,全称为javascript object notation,是一种轻量级的数据交互格式.采用完全独立于语言的文本格式,是一种理想的数据交换格式. 同时,json是jav ...
- Java中的自定义数组队列
在Java中,作为所有数据结构中存储和获取速度最快的一种,数组凭借其这种简单易用的优势在各个方面都能大显神威.但是数组也有自身的局限性.数组的长度必须是固定的一旦定义之后就无法动态的更改,这就会造成这 ...
- 利用 jQuery 来验证密码两次输入是否相同
html <div class="row"> <div class="panel panel-info"> <div class= ...
- VS2010 C++学习(5):基于DirectShow的视频预览录像程序
VS2010 C++学习(5):基于DirectShow的视频 预览录像程序 学习VC++编制的基于DirectShow视频捕获程序,主要练习基于DirectShow程序的应用. 一. ...
- oracle的下载地址以及步骤
一.下载地址 1.oracle官网:https://www.oracle.com/cn/index.html 2. 点击右上角先选择语音,然后注册一个新账户,如果有oracle直接登录就可以 3.点击 ...
- WPF自学入门(二)WPF-XAML布局控件
上一篇介绍了xaml基本知识,我们已经知道了WPF简单的语法.那么接下来,我们要认识一下WPF的布局容器.布局容器可以使控件按照分类显示,我们一起来看看WPF里面可以使用哪些布局容器用来布局. 在WP ...
- activemq的案例
- RAM
1. 前记 我们知道,不同的计算机结构对RAM 的使用方式是有区别的,典型的计算机结构有两个,冯诺依曼结构和哈佛结构,而两大阵营的领军人物就是传说中的Intel X86系列的8086和51单片 ...
- 《CLR Via C#》学习--线程开销
线程内核对象(thread kernel object) OS为系统中创建的每个线程都分配并初始化这种数据结构之一.在该数据结构中,包含一组对线程进行描述的属性. 数据结构中还包含所谓的线程上下文(t ...