机器学习 1 - Linear regression with multiple variables

简述

最近在coursera上看Stanford的经典机器学习课程,总体上感觉跟国内某大学的研究生课程内容其实差不多。先从经典的线性回归模型开始写起吧。本文的模型实例来自于课程练习——根据房屋大小和房屋数量的统计数据来预估某房产的售价,多元线性回归的数据集在ex1data2文件中可以找到,一元数据集在ex1data1中。

PS:由于一元线性回归也属于一种特殊的多元线性回归,我决定偷懒直接上多元线性回归。

算法过程

主要包括几个方面:

  • 数据清理(本例中主要是feature normalize)
  • 算法
  • gradient descent(梯度下降)
  • normal equation(正规方程)

数据清理

主要是让数据集处于一种“密集稳定”的状态,否则不经过整理的数据集会让你在选择学习率的时候异常尴尬。(我亲自试过,你也可以试试不清理数据直接用梯度下降,看看会发生什么)不整理数据,有时候你可能会只能选用非常小的学习率,才能保证梯度下降的时候不会“跑飞”。(迭代到不收敛)然而这个学习率可能会非常的小,导致你在训练的时候,可能要迭代几千万次才能训练一点点,甚至根本无法训练。

一般来说,我们选择将数据“正态化”.根据统计学基础知识,算出均值和标准差,使得数据呈标准正态分布即可。在matlab中,均值函数为mean(),标准差函数为std()

梯度下降

想要使用一个线性方程来拟合数据集,当数据集是N元的时候,则需要选择N个变量来与这些未知数组成线性方程,这N个变量记作theta。在迭代的首次,当然可以随意选择一组未知数开始。
接下来,就是选择一个代价函数cost(),注意此函数的自变量当然是N个theta,使得代价函数最小(与实际情况拟合的最好)。一般来说,我们选择最小二乘法来判断代价的大小。

接下来,为了判断N元函数cost()的最小值点,就是一个求导的过程了。这里要插一句题外话,线性回归代价函数的最小值就是极小值,因此不存在迭代到某个极小值之后卡死在某点而不能继续寻找最小值的情况,具体的可以自己证明。

梯度下降算法采用了梯度的概念,在某点沿着梯度的方向移动一小段距离,然后重复迭代这个过程,直到完成收敛。

正规方程

正规方程前面与梯度下降一样,只不过最小二乘拟合的答案直接通过数学方法由线性代数方程解出来。优点是:不需要迭代,不需要清理数据(因为不需要调整学习率,所以自然不需要整理数据呀),程序写起来非常简单。缺点是:当参数过多的时候,逆矩阵运算量太大;当参数存在线性关系的时候,逆矩阵当然是不存在的~这个时候你没法求逆矩阵了(当然可以用伪逆矩阵来求,但是不推荐)。不过就我个人经验而言,一般来说参数不太可能会出现线性相关的情况。如果出现了,可能会存在意义有重复参数,这个时候就要清理一下数据集,把不必要的参数项给去掉,就不会求解的时候出现矩阵不可逆的尴尬情况了。

程序

程序使用matlab写的,coursera是可以提交答案的~具体的提交方法可以参考pdf说明。

多元线性回归的主函数:


%% Initialization

%% ================ Part 1: Feature Normalization ================

%% Clear and Close Figures
clear ; close all; clc

fprintf('Loading data ...\n');

%% Load Data
data = load('ex1data2.txt');
X = data(:, 1:2);
y = data(:, 3);
m = length(y);

% Print out some data points
fprintf('First 10 examples from the dataset: \n');
fprintf(' x = [%.0f %.0f], y = %.0f \n', [X(1:10,:) y(1:10,:)]');

fprintf('Program paused. Press enter to continue.\n');
pause;

% Scale features and set them to zero mean
fprintf('Normalizing Features ...\n');

[X, mu, sigma] = featureNormalize(X);
% Add intercept term to X
X = [ones(m, 1) X];
std(X(:,2))
std(X(:,2))
X(:,2)

%% ================ Part 2: Gradient Descent ================

fprintf('Running gradient descent ...\n');

% Choose some alpha value
alpha = 0.01;
num_iters = 400;

% Init Theta and Run Gradient Descent 
theta = zeros(3, 1);
computeCostMulti(X,y,theta)
[theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters);

% Plot the convergence graph
figure;
plot(1:numel(J_history), J_history, '-b', 'LineWidth', 2);
xlabel('Number of iterations');
ylabel('Cost J');

% Display gradient descent's result
fprintf('Theta computed from gradient descent: \n');
fprintf(' %f \n', theta);
fprintf('\n');

% Estimate the price of a 1650 sq-ft, 3 br house
% Recall that the first column of X is all-ones. Thus, it does
% not need to be normalized.
price = 0; % You should change this
parameter = [1650,3];
parameter = (parameter-mu)./sigma;
parameter = [1,parameter];
price = theta'*parameter';

fprintf(['Predicted price of a 1650 sq-ft, 3 br house ' ...
         '(using gradient descent):\n $%f\n'], price);

fprintf('Program paused. Press enter to continue.\n');
pause;

%% ================ Part 3: Normal Equations ================

fprintf('Solving with normal equations...\n');

%% Load Data
data = csvread('ex1data2.txt');
X = data(:, 1:2);
y = data(:, 3);
m = length(y);

% Add intercept term to X
X = [ones(m, 1) X];

% Calculate the parameters from the normal equation
theta = normalEqn(X, y);

% Display normal equation's result
fprintf('Theta computed from the normal equations: \n');
fprintf(' %f \n', theta);
fprintf('\n');


% Estimate the price of a 1650 sq-ft, 3 br house

price = 0; % You should change this
parameter = [1,1650,3];
price = theta'*parameter';


fprintf(['Predicted price of a 1650 sq-ft, 3 br house ' ...
         '(using normal equations):\n $%f\n'], price);


多元线性回归的梯度下降函数:

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

% Initialize some useful values
m = length(y); % number of training examples
J_history = zeros(num_iters, 1);

for iter = 1:num_iters
    delta = zeros(size(X,2),1);
    for i=1:size(X,2)
        delta(i,1)=sum((theta'*X'-y').*(X(:,i))')*alpha/m;
    end
    theta = theta - delta;

    % Save the cost J in every iteration    
    J_history(iter) = computeCostMulti(X, y, theta);

end

end

数据正态化整理:

function [X_norm, mu, sigma] = featureNormalize(X)
X_norm = X;
mu = zeros(1, size(X, 2));
sigma = zeros(1, size(X, 2));
for i=1:size(X,2)
    mu(1,i)=mean(X(:,i));
    sigma(1,i)=std(X(:,i));
end

for i=1:size(X,2)
    X_norm(:,i)= (X_norm(:,i)-mu(1,i))/sigma(1,i);
end    

end

正规方程函数:

function [theta] = normalEqn(X, y)
theta = zeros(size(X, 2), 1);

theta = (X'*X)^(-1)*X'*y;

end

总结

总体来说,是一个比较简单的算法,高等数学和线性代数基础扎实的同学理解起来应该非常容易。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容