AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

现在公司是做通信工程的,积累了很多工程数据,这里尝试用线性回归找出数据间规律。

比如,通过项目的一些特性得出项目预算。

选取了4个特征:合同工期,设备用量,线材用量,施工面积

假设函数:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

成本函数:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

期望:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

优化方法-梯度下降:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

随机初始化参数,然后选择0.1作为学习效率,带入数据循环计算,求得成本函数最小;

如果发现成本函数来回震荡,一直不收敛,可以尝试缩小学习效率为原来的1/3,直到收敛;

到这里模型建立好了,现在用Octave来实现模型,看看效果:

1. 编写成本函数

function J = costFunction1(X, y, theta)

%X ia the "input matrix" containing our training examples.
% y is the class labels

m = size(X, 1);
predictions = X * theta;
sqrErrors = (predictions-y).^2;

J = 1/(2*m)*sum(sqrErrors);

检验一下:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

跟直接计算结果一致:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

2. 方法一:编写梯度下降函数

function [theta, J_history] = gradientDescent1(X,y,theta,alpha, num_iters)

m = length(y);
j_history = zeros(num_iters, 1);

for iter = 1:num_iters
 
 partial1 = 0;
 partial2 = 0;
 partial3 = 0;
 partial4 = 0;
 partial5 = 0;
 
 for i=1:m
  xsub = X(i,:);
  ysub = y(i,:);
  partial1 += (dot(transpose(theta), xsub, 2) - ysub)*X(i,1);
  partial2 += (dot(transpose(theta), xsub, 2) - ysub)*X(i,2);
  partial3 += (dot(transpose(theta), xsub, 2) - ysub)*X(i,3);
  partial4 += (dot(transpose(theta), xsub, 2) - ysub)*X(i,4);
  partial5 += (dot(transpose(theta), xsub, 2) - ysub)*X(i,5);
 endfor
 
 theta(1,:) = theta(1,:) - alpha * partial1/m;
 theta(2,:) = theta(2,:) - alpha * partial2/m;
 theta(3,:) = theta(3,:) - alpha * partial3/m;
 theta(4,:) = theta(4,:) - alpha * partial4/m;
 theta(5,:) = theta(5,:) - alpha * partial5/m;
 
 J_history(iter) = costFunction1(X, y, theta);
 
endfor

end

生成些随机数据求解测试:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

查看结果:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

100次迭代后偏差0.046,此时的theta:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

从这个结果看,如果第三特征是『线材用量』,那么可以得出结论:项目预算与线材用量关系最紧密:

项目预算 = 0.378 + 0.096 * 合同工期 + 0.044 * 设备用量 + 0.304 * 线材用量 + 0.020 * 施工面积;

3. 方法二:使用Octave提供的梯度下降函数

首先需要修改成本函数,新的成本函数要返回预测偏差及梯度:

function [J, grad] = costFunction2(theta, X, y)

%X ia the "input matrix" containing our training examples.
% y is the class labels

m = size(X, 1);
predictions = X * theta;
sqrErrors = (predictions-y).^2;

J = 1/(2*m)*sum(sqrErrors);

grad = zeros(5,1);

for i=1:m
 xsub = X(i,:);
 ysub = y(i,:);
 grad(1) += (dot(transpose(theta), xsub, 2) - ysub)*X(i,1);
 grad(2) += (dot(transpose(theta), xsub, 2) - ysub)*X(i,2);
 grad(3) += (dot(transpose(theta), xsub, 2) - ysub)*X(i,3);
 grad(4) += (dot(transpose(theta), xsub, 2) - ysub)*X(i,4);
 grad(5) += (dot(transpose(theta), xsub, 2) - ysub)*X(i,5);
endfor

end

然后设置options,初始化theta,调用fmnunc函数:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

4. 来做下两种方式的效率对比:

首先,初始化相同的theta

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

然后先使用fminunc:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

100次迭代后达到0.20734的偏差;

用自己写的函数:

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

981次迭代后达到0.20734的偏差;

还是内嵌的函数更高效:)fminunc函数比自己写的函数几乎快了10倍。

5.最终结果

AI-011: 练习:用线性回归解决实际问题,Octave建模及求解

项目预算 = -2.022 + 0.616 * 合同工期 + 0.540 * 设备用量 + 1.736 * 线材用量 + 2.179 * 施工面积;