Записки программиста, обо всем и ни о чем. Но, наверное, больше профессионального.

2014-05-05

Unit Tests

Я нынче университет посещаю, учусь, пока время есть:
Stanford Machine Learning https://www.coursera.org/course/ml
Каждую неделю надо сдавать зачет, заполнять опросный лист и выполнять практические задачи.

Практические задачи представляют собой код Matlab, который мы сочиняем и выполняем в Octave, поскольку Матлаб покупать для учебных задач — не вариант.
Задачки дают на реализацию разных алгоритмов. На этой неделе были среднеквадратичная Cost Function и Gradient Descent для нее. Да, это для линейной регрессии, что немаловажно.

Так вот, ближе к телу. Чтобы в этих практических задачах не мучаться с ручным вычислением всяких матриц, векторов и прочих мудрых формул, пытаясь понять, правильно ты алгоритм написал или нет, мы сочинили UnitTest-ы для наших упражнений.

%% UnitTest for Machine Learning Online Class - Exercise 1: Linear Regression
% Instructions
% ------------
%
% To test your code just type test_ex1 in command line
%% Initialization
clear ; close all; clc
function res = isDoubleEQ(d1, d2, frmt)
% frmt is sprintf placeholder like '%0.4f'
x = sprintf(frmt, d1);
a = sprintf(frmt, d2);
%~ res = abs(d1 - d2) <= eps(d2);
res = eq(x, a);
if res
fprintf("OK \n");
else
fprintf("Error \n");
end
end
function res = isMatEQ(M1, M2, prec)
res = mat2str(M1, prec) == mat2str(M2, prec);
if res
fprintf("OK \n");
else
fprintf("Error \n");
end
end
%% ==================== Part 1: Basic Function ====================
% Complete warmUpExercise.m
fprintf('Running warmUpExercise ... \n');
X = warmUpExercise()
A = eye(5)
isMatEQ(X, A, 4);
fprintf('Program paused. Press enter to continue.\n');
pause;
%% =================== Part 2, 3: Compute cost, Gradient descent ===================
% Complete computeCost.m
fprintf('Running computeCost ...\n')
x = computeCost([1 2 3; 1 3 4; 1 4 5; 1 5 6], [7;6;5;4], [0.1;0.2;0.3])
a = 7.0175
isDoubleEQ(x, a , '%0.4f');
fprintf('Program paused. Press enter to continue.\n');
pause;
% Complete gradientDescent.m
fprintf('Running gradientDescent ...\n')
x = gradientDescent([1 5; 1 2; 1 4; 1 5],[1 6 4 2]',[0 0]',0.01,1000)
a = [5.2148; -0.5733]
isMatEQ(x, a, 4);
x = gradientDescent([3 5; 1 2; 9 4; 1 5],[1 6 4 2]',[0 0]',0.01,1000)
a = [0.2588; 0.3999]
isMatEQ(x, a, 4);
fprintf('Program paused. Press enter to continue.\n');
pause;
%% =================== Part 4: Feature Normalization ===================
% Complete featureNormalize.m
fprintf('Running featureNormalize ...\n')
x = featureNormalize([1 2 3]')
a = [-1; 0; 1]
isMatEQ(x, a, 4);
x = featureNormalize([1 2 3;6 4 2]')
a = [-1 1; 0 0; 1 -1]
isMatEQ(x, a, 4);
x = featureNormalize( [ 8 1 6; 3 5 7; 4 9 2 ] )
a = [1.1339 -1.0000 0.3780; -0.7559 0 0.7559; -0.3780 1.0000 -1.1339]
isMatEQ(x, a, 4);
x = featureNormalize([1 2 3 1;6 4 2 0;11 3 3 9;4 9 8 8]')
a = [
-0.78335 1.16190 1.09141 -1.46571;
0.26112 0.38730 -0.84887 0.78923;
1.30558 -0.38730 -0.84887 0.33824;
-0.78335 -1.16190 0.60634 0.33824]
isMatEQ(x, a, 4);
fprintf('Program paused. Press enter to continue.\n');
pause;
%% ==== Part 5, 6: Cost function, Gradient descent for Multiple Variables ==============
% Complete computeCostMulti.m
fprintf('Running computeCostMulti ...\n')
x = computeCostMulti( [ 2 1 3; 7 1 9; 1 8 1; 3 7 4 ], [ 2; 5; 5; 6 ], [ 0.3816; 0.7655; 0.7952 ] )
a = 6.7273
isDoubleEQ(x, a , '%0.4f');
fprintf('Program paused. Press enter to continue.\n');
pause;
% Complete gradientDescentMulti.m
fprintf('Running gradientDescentMulti ...\n')
x = gradientDescentMulti([3 5 6; 1 2 3; 9 4 2],[1 6 4]',[0 0 0]',0.01,1000)
a = [
1.2123;
-2.9458;
2.3219]
isMatEQ(x, a, 4);
fprintf('Program paused. Press enter to continue.\n');
pause;
%% =================== Part 7: Normal Equations ===================
% Complete normalEqn.m
fprintf('Running normalEqn ...\n')
x = normalEqn([1 0; 0 2],[1 1]')
a = [
1.00000;
0.50000]
isMatEQ(x, a, 4);
fprintf('Program paused. Press enter to continue.\n');
pause;
view raw test_ex1.m hosted with ❤ by GitHub


Очень удобно. Написал тесты, это быстро, особенно если с нашего курсового форума копипастить. Потом пишешь реализацию алгоритмов. Написал, прогнал тесты, поправил, … пока не заработает.
Правильный подход к делу — лучше час потерять на написание тестов и потом за час долететь до финиша, чем весь день гадать, правильно ли ты формулу записал в векторизованном виде.

О, векторизация циклов... это, пожалуй, самое трудное пока.

UPDATE:
Вместе с Эриком мы сделали правильные unit tests для нашего класса:
https://github.com/vasnake/coursera-ml005-unittests



original post http://vasnake.blogspot.com/2014/05/unit-tests.html

Комментариев нет:

Отправить комментарий

Архив блога

Ярлыки

linux (241) python (191) citation (186) web-develop (170) gov.ru (159) video (124) бытовуха (115) sysadm (100) GIS (97) Zope(Plone) (88) бурчалки (84) Book (83) programming (82) грабли (77) Fun (76) development (73) windsurfing (72) Microsoft (64) hiload (62) internet provider (57) opensource (57) security (57) опыт (55) movie (52) Wisdom (51) ML (47) driving (45) hardware (45) language (45) money (42) JS (41) curse (40) bigdata (39) DBMS (38) ArcGIS (34) history (31) PDA (30) howto (30) holyday (29) Google (27) Oracle (27) tourism (27) virtbox (27) health (26) vacation (24) AI (23) Autodesk (23) SQL (23) humor (23) Java (22) knowledge (22) translate (20) CSS (19) cheatsheet (19) hack (19) Apache (16) Klaipeda (15) Manager (15) web-browser (15) Никонов (15) functional programming (14) happiness (14) music (14) todo (14) PHP (13) course (13) scala (13) weapon (13) HTTP. Apache (12) SSH (12) frameworks (12) hero (12) im (12) settings (12) HTML (11) SciTE (11) USA (11) crypto (11) game (11) map (11) HTTPD (9) ODF (9) Photo (9) купи/продай (9) benchmark (8) documentation (8) 3D (7) CS (7) DNS (7) NoSQL (7) cloud (7) django (7) gun (7) matroska (7) telephony (7) Microsoft Office (6) VCS (6) bluetooth (6) pidgin (6) proxy (6) Donald Knuth (5) ETL (5) NVIDIA (5) Palanga (5) REST (5) bash (5) flash (5) keyboard (5) price (5) samba (5) CGI (4) LISP (4) RoR (4) cache (4) car (4) display (4) holywar (4) nginx (4) pistol (4) spark (4) xml (4) Лебедев (4) IDE (3) IE8 (3) J2EE (3) NTFS (3) RDP (3) holiday (3) mount (3) Гоблин (3) кухня (3) урюк (3) AMQP (2) ERP (2) IE7 (2) NAS (2) Naudoc (2) PDF (2) address (2) air (2) british (2) coffee (2) fitness (2) font (2) ftp (2) fuckup (2) messaging (2) notify (2) sharepoint (2) ssl/tls (2) stardict (2) tests (2) tunnel (2) udev (2) APT (1) Baltic (1) CRUD (1) Canyonlands (1) Cyprus (1) DVDShrink (1) Jabber (1) K9Copy (1) Matlab (1) Portugal (1) VBA (1) WD My Book (1) autoit (1) bike (1) cannabis (1) chat (1) concurrent (1) dbf (1) ext4 (1) idioten (1) join (1) krusader (1) license (1) life (1) migration (1) mindmap (1) navitel (1) pneumatic weapon (1) quiz (1) regexp (1) robot (1) science (1) seaside (1) serialization (1) shore (1) spatial (1) tie (1) vim (1) Науру (1) крысы (1) налоги (1) пианино (1)