MATLAB 在数据可视化、数据分析以及数值计算方面的巨大优势,使其在高校科学研究以及企业产品研发中具有不可或缺的作用。相比之下,伴随人工智能的发展,Python因更易学、拥有众多开源科学计算库等特点成为语言学习者的新宠。那么,如何在MATLAB中调用Python命令或文件,如何综合利用MATLAB和Python更加轻易地完成各种高级任务呢?
目前,MATLAB支持2.7、3.6和3.7版本Python的调用,MATLAB官方参考文件中分别给出MATLAB和Python相互调用的方法:Call Python from MATLAB,Call MATLAB from Python。以下笔者将通过几个的案例,详细说明如何在MATLAB中调用Python。
案例一:elastic net 回归算法应用
1、首先在MATLAB中构造所需要的数据:
Coef_def = [0.1,0.5,-0.6,0.3,0.5]; %定义模型参数矩阵
x = 0.1:0.05:10;
len = length(x);
[var1, var2, var3, var4,var5] =deal(zeros(len,1));
for i =1:len
var1(i) = 1/x(i);
var2(i) = x(i);
var3(i) = sqrt(x(i));
var4(i) = sin(x(i));
var5(i) = 1;
end
var_def = [var1,var2,var3,var4,var5];
y_def = var_def*Coef_def' + randn(len,1)*0.1;
构造数据如下图所示:
2、Python模块的调用
MATLAB支持Python开源模块和用户自定义模块的调用,调用方法为:
output = py.Module_Name.Function_Name(input)
以上方法同样适用于.py文件的调用、文件内变量的查看等。本文elastic net 应用模my_module.py块定义为:
from sklearn import linear_model #导入sklearn的线性模型模块
def elastic_net(alpha,tolerance):
train_data = Matdata['data']
X_train = train_data[:,0:-1]
y_train = train_data[:,-1]
Model = linear_model.ElasticNet(alpha=alpha, tol=tolerance)
Model.fit(X_train, y_train)
result = dict()
result['y_test'] = Model.predict(X_train)
result['coef'] = Model.coef_
return result
以上程序片段中,alpha、tolerance为两个需要调试的传递参数,并调用了sklearn中的elastic net模块对数据进行拟合,最后以dictionary的形式返回了对数据的拟合结果和线性拟合系数。
需要注意的是,要确保模块位于Python搜索路径上,可以通过insert函数将文件路径添加到Python搜索路径,只需添加一次,MATLAB重启后添加的路径会自动清除。
insert(py.sys.path,int32(0),'C:\python36\matlab');
3、数据传递方法
若所调用模块的函数中包括输入参数和返回,则需要进行MATLAB与Python之间数据的传递。
(1)MATLAB向Python传递数据
目前py仅能够向Python传递一维数据,官方数据转换参考文件为数据转换。
笔者了解的一种比较曲折的方法是将多维数组拼接成一个一维数组传递给Python,然后利用循环、Reshape方法恢复,或者将每个变量依次作为dictionary的value传入,例如:
data = py.dict(pyargs('var1',data(:,1)','var2',data(:,2)','var3',data(:,3)'))
另外一种方法是,将数据保存为.mat格式,Python利用scipy科学计算模块读取,方法如下:
import scipy.io as scio
dataFilepath = 'E:\study\JS_project\Call python from matlab\data.mat'
Matdata = scio.loadmat(dataFilepath)
读取出来的Matdata是dictionary格式,它的Key就是保存变量的名称,可以通过Matdata.keys()查看:
dict_keys(['__header__', '__version__', '__globals__', 'data'])
这个案例的.mat中只有一个名为data的多维数组,Matdata['data']则为numpy中的矩阵格式。
(2)Python向MATLAB返回数据
Python可以通过函数向MATLAB任意形式的数据变量,可用的类型转换包括:
py.dict 可以通过struc()函数转为结构体,也可以直接利用 变量名{‘key’} 查看;
py.list可以通过cellfun(@double,cell(变量名))转化为一维变量;
py.ndarray可以通过 变量名.tolist转为list,进一步转化为可用变量。
本文返回变量为包含{‘y_test’,‘coef’}两个key的py.list,同时每个key的值为py.ndarray格式,因此模块调用和数据转换方式为:
alpha = 1e-5;
tolerance =1e-6;
result = py.my_module.elastic_net(alpha, tolerance);
coef = cellfun(@double,cell(result{'coef'}.tolist));
y_test = cellfun(@double,cell(result{'y_test'}.tolist));
同样,可以采用scipy将Python模块计算结果保存为.mat文件,然后在MATLAB用load()函数读取,保存方法为:
dataNew = 'E:\study\JS_project\Call python from matlab\dataNew.mat'
scio.savemat(dataNew, {'A':data['A']})
(总感觉以上数据传递方法有所欠缺,有个更好的方法请务必告诉我)
4、模型精度分析
但参数alpha=1e-5时,模型拟合曲线为:
可以看出,模型能够很好的对原始数据进行拟合,与去除噪音的原始曲线重合度极高。
模型估计参数为:
[0.104641509955188 0.502653801169063 -0.623194396529333 0.296323266615267 0]
这与最初定义模型参数[0.1,0.5,-0.6,0.3,0.5]的前4个参数非常接近,而常数项的参数为0。
同时当选取参数alpha=0时,模型精度最高,此时elastic net模型的惩罚项为0,相当于基本最小二乘优化方法。这些都与线性拟合方法的原理相关,其中的原因将在下一篇:《机器学习之线性模型原理》进行介绍。
(未完待续.......)