How to generalize this code to equations with several variables?

I am new to LISP. I am following the Andrew Ng machine learning course at Coursera (first week still). I wanted to try linear regression in LISP. I wrote code for linear regression with one variable. The code seems to be working fine. I want to generalize this to linear functions with several variables. I want to know how to start doing this. I want to get something like:

(defun run-linear-regression alpha iterations training-set number-of-variables (...))

which, in turn, would create a hypothesis generator function with an input number of variables, partial derivative functions for these hypotheses, etc.

Below is the code that I have. I don't need anyone to code this for me, but some recommendations on how to do what I want will be appreciated. In addition, any general comments on how to improve the code (performance, style, etc.), I still welcome.

(defun make-hypothesis (theta1 theta2)
  (lambda (x) 
    (+ theta1 (* x theta2))))

(defun make-cost-function (hypothesis)
  (lambda (training-data)
    (let* ((x (car training-data)) (y (cadr training-data))
       (val (- (funcall hypothesis x) y)))
      (* val val))))

(defun make-J-1 (cost-function)
  (lambda (training-set) (float 
              (/ 
               (reduce #'+ (mapcar cost-function training-set)) 
               (* 2 (length training-set))))))


(defun make-J (theta1 theta2)
  (make-J-1 (make-cost-function (make-hypothesis theta1 theta2))))

(defun make-part-deriv-1 (hypothesis)
  (lambda (test-set)
    (let ((m (length test-set)))
      (float (/
          (reduce #'+ (mapcar (lambda(elem)(- (funcall hypothesis (car elem)) (cadr elem))) test-set))
          m)))))

(defun make-part-deriv-2 (hypothesis)
  (lambda (test-set)
    (let ((m (length test-set)))
      (float (/
          (reduce #'+ (mapcar (lambda(elem)(* (- (funcall hypothesis (car elem)) (cadr elem)) (funcall hypothesis (car elem)))) test-set))
          m)))))

(defun make-learn-fn (alpha theta1 theta2 make-part-deriv)
  (lambda (test-set) 
    (let* ((hypothesis (make-hypothesis theta1 theta2)) (pdv (funcall make-part-deriv hypothesis)))
      (* alpha (funcall pdv test-set)))))

(defun make-learners (alpha)
  (list 
   (lambda (theta1 theta2 test-set) (- theta1 (funcall (make-learn-fn alpha theta1 theta2 #'make-part-deriv-1) test-set)))
   (lambda (theta1 theta2 test-set) (- theta2 (funcall (make-learn-fn alpha theta1 theta2 #'make-part-deriv-2) test-set)))))

(defun run-linear-regression (alpha iterations training-set &optional (theta1 0) (theta2 0) (printer nil))
  (let ((t1 theta1) (t2 theta2))
    (dotimes (i iterations)
      (if (not (null printer))
      (funcall printer t1 t2))
      (let* ((funcs (make-learners alpha))
         (nt1 (funcall (car funcs) t1 t2 training-set))
         (nt2 (funcall (cadr funcs) t1 t2 training-set)))
    (setq t1 nt1)
    (setq t2 nt2)))
    (list t1 t2)))

in the end, I would call it this way:

(defvar *training-set* '((15 20) (700 6) (23 15) (19 19) (204 15) (60 150) (87 98) (17 35) (523 29)))
(run-linear-regression 0.0001 1000000 *training-set*)
+4
source share
1 answer

I am not familiar with math here, but since no one else has written the best answers, here are some general tips.

You must modify RUN-LINEAR-REGRESSIONto take a list of variables as well as a list of student functions. For instance:

(defun run-linear-regression (iterations training-set
                              variables learners)
  (let ((vars variables))
    (dotimes (i iterations)
      (setf vars (mapcar (lambda (function)
                           (funcall function vars training-set))
                         learners)))
    vars))

, . , , MAKE-LEARNERS ALPHA , , .

MAKE-LEARNERS , - :

(defun make-learners (alpha)
  (list (lambda (variables test-set)
          (destructuring-bind (theta1 theta2) variables
            (- theta1 (funcall (make-learn-fn alpha theta1 theta2
                                              #'make-part-deriv-1)
                               test-set))))
        (lambda (variables test-set)
          (destructuring-bind (theta1 theta2) variables
            (- theta2 (funcall (make-learn-fn alpha theta1 theta2
                                              #'make-part-deriv-2)
                               test-set))))))

, , DESTRUCTURING-BIND THETA1 THETA2 VARIABLES. RUN-LINEAR-REGRESSION :

(run-linear-regression 1000000 *training-set* '(0 0) (make-learners 0.0001))
;=> (42.93504 2.5061023e-4)

, MAKE-LEARNERS. , .

+2

All Articles