;; All about higher order functions =)
(ns mlpractice.lesson1)

(defn generate-data-set
  "Generates a map of :x y values for linear regression"
  [constant slope num]
  (nth (iterate
        #(let [x (Math/random)]
           (assoc %1 x (+ constant (* slope x)))) {}) num))

(defn hypothesis-fn
  "Builds the hypothesis function h(x) using th0 and th1"
  [theta0 theta1]
  (fn h
    [x]
    (+ theta0 (* theta1 x))))

(defn cost-summation
  "The function that gets applied to every entry in every data set"
  [hypothesis agg data]
  (let [x (first data)
        y (second data)]
    (+ agg (- (hypothesis x) y))))

;;Difference between inside and outside let?
(defn cost-fn
  "Builds the cost function J(th0, th1) for some amount of data"
  [data]
  (let [coefficient (->> data (count) (* 2) (/ 1))]
    (fn cost
      [th0 th1]
      (let [hypothesis (hypothesis-fn th0 th1)] 
        (* coefficient
           (reduce (partial cost-summation hypothesis) 0 data))))))

;; All about higher order functions =)
;; Linear Regression with multiple variables

(ns mlpractice.lesson1)

;innefficient because iterate holds onto old maps, should use a different function?
(defn generate-data-set
  "Generates a map of a vector x of feature values 
   to its y value for linear regression"
  [data-point-num & coefficients]
  (nth (iterate
        #(let [n (count coefficients)
               x-vec (repeatedly n (fn [] (Math/random)))]
           (assoc %1 x-vec (apply + (map * x-vec coefficients))))
        {})
       data-point-num))

(defn hypothesis-fn
  "Builds the hypothesis function h(x) using a vector theta of coefficients"
  [param-vec]
  (fn h
    [feature-vec]
    (apply + (map * param-vec feature-vec))))

(defn cost-summation
  "The function that finds the error between our hypothesis function
   and our actual y value, and adds it to an aggregate"
  [hypothesis agg data]
  (let [x (first data)
        y (second data)]
    (+ agg (- (hypothesis x) y))))

;;Difference between inside and outside let?
(defn cost-fn
  "Builds the cost function J(th0, th1) for some amount of data"
  [data]
  (let [coefficient (->> data (count) (* 2) (/ 1))]
    (fn cost
      [param-vec]
      (let [hypothesis (hypothesis-fn param-vec)]
        (-> (partial cost-summation hypothesis)
            (reduce 0 data)
            (Math/pow 2)
            (* coefficient))))))

Update lesson 1 to work for linear regression with multiple variables
Update lesson 1 to work for linear regression with multiple variables

lucasdellabella/Coursera-ML-Stuff