<jupyter_start><jupyter_text>Table of Contents1&nbsp;&nbsp;Library import2&nbsp;&nbsp;Practical Assignment 1, Due Date: 16 April 2021 at 23:592.1&nbsp;&nbsp;Approach 12.2&nbsp;&nbsp;Aproach 2  Library import<jupyter_code>import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math<jupyter_output><empty_output><jupyter_text>Practical Assignment 1, Due Date: 16 April 2021 at 23:59Create a python class with the following objectives:- A method for creating a design matrix for a feature vector x- A method for learning the parameters of the model- A method for predicting target values given input values x using two methods:    OLS     MLE - A plotting method for a fitted line and 1 standard division for denoting uncertainties with the MLE method.- Your class should allow the user to specify a method of interest e.g. "OLS" or "MLE"  Approach 1Input: (x, y, method)<jupyter_code>class Regression():
    """ 
    A Simple Linear Regression Model Class:
    Class Attributes:
    x: Independent Variable Input
    y: Dependent Variable Input
    method: Select 'OLS' or 'MLE'
    Class Functions:
    designMatrix(): Outputs X n*2 matrix of ones and independent variable inputs
    learnParameter(): Outputs b_0 and b_1 and regression equation
    fitPlot(): Outputs the line of best fit plot 
    pred(): Takes input and outputs predicted value 
    Use Sequence:
    1:designMatrix(), 2:learnParameter(), 3:fitPlot(), 4:pred()
    """
    def __init__(self, x, y, method):
        self.x = x
        self.y = y
        self.method = method
    
    def designMatrix(self):
        if self.method == 'OLS' or self.method == 'MLE':
            global X, Y, mat_len
            mat_len = len(self.x) # matrix lenght (same as n)
            X = np.matrix([np.ones(mat_len), self.x]).T; # design matrix
            Y = np.matrix(self.y).T
            return X
        else:
            print("Please select 'OLS' or 'MLE' as the correct Method")
    
    def learnParameter(self):
        global l_par, σ_square
        if self.method == 'OLS':
            l_par = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y) # learning parameters
            print("Estimated coefficients:\nβ_0 = {}  \
              \nβ_1 = {}".format(l_par[0], l_par[1]))
            print("Equation: y_bar = {} + {}x".format(l_par[0], l_par[1]))
        elif self.method == 'MLE':
            l_par = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y) 
            # σ^2 = 1/n*(y-Xθ)^T(y-Xθ)  
            # σ_square = (1/mat_len)*((Y - X.dot(l_par)).T.dot(Y - X.dot(l_par)) : Used formula
            σ_square = np.array((1/mat_len)*((Y - X.dot(l_par)).T.dot(Y - X.dot(l_par)))).flatten() # sigma^2
            print("Estimated coefficients:\nβ_0 = {}  \
              \nβ_1 = {}".format(l_par[0], l_par[1]))
            print("σ^2 = {}".format(σ_square))
            print("Equation: y_bar ~ N({} + {}x; {})".format(l_par[0], l_par[1], σ_square))
        else:
            print("Please select 'OLS' or 'MLE' as the correct Method")
            
            
    
    def fitPlot(self):
        if self.method == 'OLS':
            y_pred = l_par[0] + l_par[1] * self.x # y_bar = b0 + b1x
            plt.plot(np.array(self.x), np.array(y_pred).flatten(), color='r',
                    label='y_bar = {} + {}x'.format(np.array(l_par[0]).flatten(), np.array(l_par[1]).flatten()));
            plt.plot(self.x, self.y, '.', color = 'b');
            plt.xlabel('x');
            plt.ylabel('y');
            plt.legend(loc = "upper left");
        elif self.method == 'MLE':
            y_pred = l_par[0] + l_par[1] * self.x
            y_pred_up = (l_par[0] + l_par[1] * self.x) + σ_square**(1/2) # Uncertainity 
            y_pred_down = (l_par[0] + l_par[1] * self.x) - σ_square**(1/2) # Uncertainity 
            plt.plot(np.array(self.x), np.array(y_pred).flatten(), color='r',
                    label='y_bar = {} + {}x'.format(np.array(l_par[0]).flatten(), np.array(l_par[1]).flatten()));
            plt.plot(self.x, self.y, '.', color = 'b');
            plt.plot(np.array(self.x), np.array(y_pred_up).flatten(), color='k',
                    label='+/- {} Std of Uncertainties'.format(σ_square**(1/2)));
            plt.plot(np.array(self.x), np.array(y_pred_down).flatten(), color='k');
            plt.xlabel('x');
            plt.ylabel('y');
            plt.legend(loc = "upper left"); 
        else:
            print("Please select 'OLS' or 'MLE' as the correct Method")
            
    
    def pred(self, val):
        """
        Input independent variables for prediction 
        Input single or multiple values for single or multiple values output
        val: Input values x
        """
        if self.method == 'OLS':
            return np.array(l_par[0] + l_par[1] * val).flatten() 
        elif self.method == 'MLE':
            return np.array(np.random.normal(l_par[0] + l_par[1] * val,σ_square**(1/2))).flatten()
        else:
            print("Please select 'OLS' or 'MLE' as the correct Method")
help(Regression)
# Test data 
x = [29, 9, 10, 38, 16, 26, 50, 10, 30, 33, 43, 2, 39, 15, 44, 29, 41, 15, 24, 50] # Study hours
y = [65, 7, 8, 76, 23, 56, 100, 3, 74, 48, 73, 0, 62, 37, 74, 40, 90, 42, 58, 100] # Test results
#x = np.random.random((100))
#y = np.random.random((100))
r_ols = Regression(x, y, 'OLS')
r_mle = Regression(x,y, 'MLE')
r_ols.designMatrix()
r_mle.designMatrix()
r_ols.learnParameter()
r_mle.learnParameter()
r_ols.fitPlot()
r_mle.fitPlot()
# Outputs from original data
# [2, 30, 50, 60]
# [0, 74, 100, ?]
r_ols.pred([2,30,50,60])
r_mle.pred([2,30,50,60])<jupyter_output><empty_output><jupyter_text>Aproach 2Input: (sample, β_0, β_1, mu, sigma, method, min_v, max_v)<jupyter_code>class lregression():
    """
    Attributes 
    sample: Data size
    β_0: Set intercept based on world belief
    β_1: Set slope based on world belief
    mu: Set desired mean
    sigma: set desired standard deviation
    min_v: minimum data value 
    max_v: maximum data value
    """
    def __init__(self, sample, β_0, β_1, mu, sigma, method, min_v, max_v):
        self.sample = sample
        self.β_0 = β_0
        self.β_1 = β_1
        self.mu = mu
        self.sigma = sigma
        self.method = method
        self.min_v = min_v
        self.max_v = max_v
        
    def designMatrix(self):
        global X, Y, y_tru, y_obs, x            
        x = np.random.uniform(self.max_v ,self.min_v ,self.sample)
        y_tru = self.β_0 + self.β_1 * x
        ϵ = np.random.normal(self.mu ,self.sigma ,self.sample)
        y_obs = y_tru + ϵ
        mat_len = len(x)
        X = np.matrix([np.ones(mat_len), x]).T 
        Y = np.matrix(y_obs).T
        return X
    
    def learnParameters(self):
        global x_var, y_var, l_par, σ_square
        if self.method == 'OLS':
            l_par = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y)
            print("Estimated coefficients:\nβ_0 = {}  \
              \nβ_1 = {}".format(l_par[0], l_par[1]))
            print("Equation: y_bar = {} + {}x".format(l_par[0], l_par[1]))
        else:
            l_par = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y)
            σ_square = np.array((1/mat_len)*((Y - X.dot(l_par)).T.dot(Y - X.dot(l_par)))).flatten()
            print("Estimated coefficients:\nβ_0 = {}  \
              \nβ_1 = {}".format(l_par[0], l_par[1]))
            print("σ^2 = {}".format(σ_square))
            print("Equation: y_bar ~ N({} + {}x; {})".format(l_par[0], l_par[1], σ_square))
    
    def dataPlot(self):
        # Plot linear model with Noise 
        plt.plot(x,y_tru,'r-',label='y_true = {} + {}x'.format(self.β_0,self.β_1));
        plt.plot(x,y_obs,'.',label='y_obs = y + ϵ, mean = {}, sd = {}'.format(self.mu, self.sigma));
        plt.xlabel('x');
        plt.ylabel('y');
        plt.title('Linear Model with Noise')
        plt.legend(loc = "upper left");
    
    def fitPlot(self):
        if self.method == 'OLS':
            y_est = l_par[0] + l_par[1] * x
            plt.plot(np.array(x), np.array(y_est).flatten(), color='g', 
                     label = 'y_est = {} + {}x'.format(np.array(l_par[0]).flatten(), np.array(l_par[1]).flatten()));
            plt.plot(x,y_tru,'r-',label='y_true = {} + {}x'.format(self.β_0,self.β_1));
            plt.plot(x, y_obs,'.',label='y_obs = y_true + ϵ, mean = {}, sd = {}'.format(self.mu, self.sigma));
            plt.legend();
        else:
            y_est = l_par[0] + l_par[1] * x
            y_est2 = (l_par[0] + l_par[1] * x) + σ_square**(1/2) # Uncertainty region 
            y_est3 = (l_par[0] + l_par[1] * x) - σ_square**(1/2) # Uncertainty region 
            plt.plot(np.array(x), np.array(y_est).flatten(), color='g', 
                     label = 'y_est = {} + {}x'.format(np.array(l_par[0]).flatten(), np.array(l_par[1]).flatten()));
            plt.plot(np.array(x), np.array(y_est2).flatten(), color='k');
            plt.plot(np.array(x), np.array(y_est3).flatten(), color='k');
            plt.plot(x,y_tru,'r-',label='y_true = {} + {}x'.format(self.β_0,self.β_1));
            plt.plot(x, y_obs,'.',label='y_obs = y_true + ϵ, mean = {}, sd = {}'.format(self.mu, self.sigma));
            plt.legend(loc = "upper left");
            
    def pred(self,val):
        if self.method == 'OLS':
            return np.array(l_par[0] + l_par[1] * val).flatten() 
        else:
            return np.array(np.random.normal(l_par[0] + l_par[1] * val,σ_square**(1/2))).flatten()  
help(lregression)
r_class_ols = lregression(51, 5.67, 2.18, 0, 5,'OLS', 0, 51)
r_class_ols.designMatrix()
r_class_ols.learnParameters()
r_class_ols.dataPlot()
r_class_ols.fitPlot()
r_class_ols.pred([1,22,3])
r_class_mle = lregression(51, 5.67, 2.18, 0, 5,'MLE', 0, 51)
r_class_mle.designMatrix()
r_class_mle.learnParameters()
r_class_mle.dataPlot()
r_class_mle.fitPlot()
r_class_mle.pred([1,22,3])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16928217069960513, 'fraction_numerical': 0.028854915460159967, 'mean_word_length': 2.4514325646401116, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '375582', 'license': 'MIT', 'n_tokens_mistral': 3836, 'n_tokens_neox': 3601, 'n_words': 787, 'path': 'Practical_Assignment_1.ipynb', 'repo_name': 'Ellie190/Advanced-Machine-Learning', 'size': '9877'}