view tvii/linear_regression.py @ 91:d603ee579c3e

add linear regression
author Jeff Hammel <k0scist@gmail.com>
date Sun, 17 Dec 2017 14:25:13 -0800
parents
children
line wrap: on
line source

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Linear regression using tensorflow:

W * x + b = y

Yields `W` and `b`

Ref:
https://www.tensorflow.org/get_started/get_started
"""

# minimize:
# (h(x) - y)**2
# =>
# (1./(2*m))*sum_i={i..m} (h(x_i) - y_i)**2
# m -- number of training examples
# =>
# (1./(2*m))*sum_i={i..m} ((b + W*x_i) - y_i)**2
# : cost function; in this case, the squared error function

import csv
import json
import os
import sys
import tensorflow as tf
from .cli import CLIParser as Parser
from .read import read
from .transpose import transpose

class LinearRegression(object):
    """class-based approach to linear regression"""

    def __init__(self, W_guess=0., b_guess=0.):
        # model parameters: guesses
        self.W = tf.Variable([W_guess], tf.float32)
        self.b = tf.Variable([b_guess], tf.float32)
        raise NotImplementedError('TODO')

    def __call__(self, x_train, y_train, max_iterations=1000):
        # Model input and output
        x = tf.placeholder(tf.float32)
        linear_model = W * x + b
        y = tf.placeholder(tf.float32)

        # loss
        loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares



def linear_regression(x_train,
                      y_train,
                      W_guess=0.,
                      b_guess=0.,
                      max_iterations=1000):
    """
    perform a linear regression:

    W*x + b

    Returns:
    (W_trained, b_trained, loss)
    """

    # model parameters: guesses
    W = tf.Variable([W_guess], tf.float32)
    b = tf.Variable([b_guess], tf.float32)

    # Model input and output
    x = tf.placeholder(tf.float32)
    linear_model = W * x + b
    y = tf.placeholder(tf.float32)

    # loss
    loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares

    # optimizer
    optimizer = tf.train.GradientDescentOptimizer(0.01)
    train = optimizer.minimize(loss)

    # training loop
    init = tf.global_variables_initializer()
    sess = tf.Session()
    sess.run(init) # reset values to wrong
    for i in range(max_iterations):
        sess.run(train, {x:x_train, y:y_train})

    # evaluate training accuracy
    curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x:x_train, y:y_train})
    return (curr_W[0], curr_b[0], curr_loss)


def main(args=sys.argv[1:]):
    """CLI"""

    # parse command line
    parser = Parser(description=__doc__)
    parser.add_argument('data', type=read,
                        help="(x,y) data to read")
    parser.add_argument('--W', dest='W_guess',
                        type=float, default=0.3,
                        help="best guess for `W` [DEFAULT: %(default)s]")
    parser.add_argument('--b', dest='b_guess',
                        type=float, default=-0.3,
                        help="best guess for `b` [DEFAULT: %(default)s]")
    parser.add_argument('--iterations', '--max-iterations', dest='max_iterations',
                        type=int, default=1000,
                        help="maximum number of iterations [DEFAULT: %(default)s]")
    options = parser.parse_args(args)

    # training data
    x_train, y_train = transpose(options.data)

    # learn!
    W, b, loss = linear_regression(x_train,
                                   y_train,
                                   options.W_guess,
                                   options.b_guess,
                                   max_iterations=options.max_iterations)

    # recite your lesson
    print (json.dumps(dict(W=float(W),
                           b=float(b),
                           loss=float(loss))))


if __name__ == '__main__':
    main()