Description

This is an instance of Bayesian inference. Explicitly, we try to do a linear fitting by means of Bayesian inferenace.

This instance is a reduced version of the instance in section 1.2.5 in Bayesian Learning for Neural Networks.

Basics

Bayes Rule

prob(new_event | old_events) = sum([prob(new_event | parameters) * prob(paramters | old_events)
                                    for parameters in all_possible_parameters
                                    ])

where

prob(paramters | old_events) = prob(old_events | paramters) * prob(parameters) / prob(old_events)


Terminality

Prior:

prob(parameters)

Posterior:

prob(paramters | old_events)

Likelihood:

prob(old_events | parameters)


Gaussian Instance

If, for any event, there exists some f: (float -> float) and some sigma: float, s.t.

prob(element | parameters) = gauss(f(parameters), sigma, element)

then,

expect(new_event) = sum([f(parameters) * prob(paramters | old_events)
                         for parameters in all_possible_parameters
                         ])

In [1]:
import numpy as np
import random
import matplotlib.pyplot as plt

In [2]:
a = 0.5
b = -1
target = lambda x: a * x + b


xs = np.arange(0, 10, 1)
ys = [target(x) + random.gauss(0, 0.3) for x in xs]

plt.plot(xs, ys, '.')
plt.plot(xs, [target(x) for x in xs])
plt.show()



In [3]:
def f(parameters, x):
    """ 
    Args:
        parameters: [a: float, b: float]
        x: float
        
    Returns:
        float
    """
    a = parameters[0]
    b = parameters[1]

    return a * x + b


def gauss(mu, sigma, x):
    """
    Args:
        mu: float
        sigma: float
        x: float
        
    Returns:
        float
    """
    return np.sqrt(2 * np.pi * sigma) * np.exp((-1/2) * ((x - mu) / sigma) ** 2)


def likelihood(ys, parameters, xs, sigma=0.1):
    """
    Args:
        ys: [y: float]
        parameters: [a: float, b: float]
        xs: [x: float]
        
    Returns: float
    """
    
    def single_prob(y, parameters, x):
        """
        Args:
            y: float
            parameters: [a: float, b: float]
            x: float

        Returns: float
        """
        return gauss(f(parameters, x), sigma, y)

    return np.prod([single_prob(ys[i], parameters, xs[i])
                    for i in range(len(xs))
                   ])


def prior(parameters):
    """
    Args:
        parameters: [a: float, b: float]
        
    Returns:
        float
    """
    return 1




def normalize_factor(parameters, ys, xs):
    """
    Args:
        paramters: [a: float, b: float]
        ys: [y: float]
        xs[x: float]
        
    Returns:
        float
    """
    normalize_factor = sum([unnormalized_posterior(parameters, ys, xs)
                            for parameters in all_possible_parameters
                            ])
    

def posterior(parameters, ys, xs):
    """
    Args:
        paramters: [a: float, b: float]
        ys: [y: float]
        xs[x: float]
        
    Returns:
        float
    """
    
    def unnormalized_posterior(parameters):
        return likelihood(ys, parameters, xs) * prior(parameters)
    
    N = sum([unnormalized_posterior(parameters)
            for parameters in all_possible_parameters
            ])
    normalize_factor = 1 / N
    
    return normalize_factor * unnormalized_posterior(parameters)


def expect(new_x, all_possible_parameters, ys, xs):
    """
    Args:
        new_x: float
        all_possible_parameters: [parameters: [a: float, b: float]]
        ys: [y: float]
        xs: [x: float]
        
    Returns:
        float
    """
    
    return sum([f(parameters, new_x) * posterior(parameters, ys, xs)
                for parameters in all_possible_parameters
               ])

In [4]:
all_possible_parameters = [[a, b] for a in np.arange(-1, 1, 0.1) for b in np.arange(-1, 1, 0.1)]

In [5]:
new_x = 12
expect_y = expect(new_x, all_possible_parameters, ys, xs)


plt.plot(xs, ys, '.')
plt.plot(np.arange(0, new_x + 1),
         [target(x) for x in np.arange(0, new_x + 1)]
        )
plt.plot([new_x], [expect_y], 'ro')
plt.show()


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-5-b588c2739b2c> in <module>()
      1 new_x = 12
----> 2 expect_y = expect(new_x, all_possible_parameters, ys, xs)
      3 
      4 
      5 plt.plot(xs, ys, '.')

<ipython-input-3-b5d3c72ca4a5> in expect(new_x, all_possible_parameters, ys, xs)
    116 
    117     return sum([f(parameters, new_x) * posterior(parameters, ys, xs)
--> 118                 for parameters in all_possible_parameters
    119                ])

<ipython-input-3-b5d3c72ca4a5> in <listcomp>(.0)
    116 
    117     return sum([f(parameters, new_x) * posterior(parameters, ys, xs)
--> 118                 for parameters in all_possible_parameters
    119                ])

<ipython-input-3-b5d3c72ca4a5> in posterior(parameters, ys, xs)
     96 
     97     N = sum([unnormalized_posterior(parameters)
---> 98             for parameters in all_possible_parameters
     99             ])
    100     normalize_factor = 1 / N

<ipython-input-3-b5d3c72ca4a5> in <listcomp>(.0)
     96 
     97     N = sum([unnormalized_posterior(parameters)
---> 98             for parameters in all_possible_parameters
     99             ])
    100     normalize_factor = 1 / N

<ipython-input-3-b5d3c72ca4a5> in unnormalized_posterior(parameters)
     93 
     94     def unnormalized_posterior(parameters):
---> 95         return likelihood(ys, parameters, xs) * prior(parameters)
     96 
     97     N = sum([unnormalized_posterior(parameters)

<ipython-input-3-b5d3c72ca4a5> in likelihood(ys, parameters, xs, sigma)
     49 
     50     return np.prod([single_prob(y[i], parameters, x[i])
---> 51                     for i in range(len(xs))
     52                    ])
     53 

<ipython-input-3-b5d3c72ca4a5> in <listcomp>(.0)
     49 
     50     return np.prod([single_prob(y[i], parameters, x[i])
---> 51                     for i in range(len(xs))
     52                    ])
     53 

NameError: name 'y' is not defined