# -*- coding: utf-8 -*- """ Created on Fri Jan 14 08:25:06 2022 @author: Sahil """ import numpy as np from sklearn.linear_model import LinearRegression from scipy.optimize import minimize, Bounds #1) # Setting the transition matrix P = np.array([ [0.75, 0.15, 0.1], [0.45, 0.45, 0.1], [0.3, 0.1, 0.6] ]) # Finding the right side eigen vectors of the transition matrix lhs, rhs = np.linalg.eig(P) # Checking which eigen value is close to 1 that will give us pi * p = pi rhs1 = rhs[:, np.isclose(lhs, 1)][:, 0] # Getting the final stationary distribution stationary = rhs1 / rhs1.sum() print(f"Stationary Distribution is: {stationary}") # Using loop i = 1 while i <= 1000: print(i) this = np.linalg.matrix_power(P, i) prev = np.linalg.matrix_power(P, i-1) if np.array_equal(prev, this): print(f"Stationary Distribution is: {np.diag(this)}\n Found on iteration {i}") print(this) break else: i+=1 continue #2) # Defining the data x = np.array([3.44, 3.44, 4.07, 3.73, 3.78, 5.25, 5.424, 5.345, 2.20]) y = np.array([19.2, 17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4]) # Getting s_xx, s_yy, s_xy values s_xx = sum(x**2) - (len(x) * np.mean(x)**2) s_yy = sum(y**2) - (len(x) * np.mean(y)**2) s_xy = sum(x * y) - (len(x) * np.mean(x) * np.mean(y)) # Calculation of B0 and B1 values B1 = s_xy / s_xx B0 = np.mean(y) - (B1 * np.mean(x)) # Checking if answer is correct reg = LinearRegression() reg.fit(x.reshape((-1, 1)), y) round(reg.coef_[0], 2) == round(B1, 2) round(reg.intercept_, 2) == round(B0, 2) # Both sanity checks return true. #3) # Defining the variables x3 = np.array([2.76, 1.80, 2.50, 10.64, 12.01]) y3 = np.array([7.40, 4.81, 6.69, 28.52, 32.18]) np.std(x3) np.std(y3) # Checking the effect scaling has on the standard deviation for i in [2, 5, 7.5, 10, 50, 100]: print(f"Scaling value: {i}") print(f"x: {np.std(x3 * i)}; Divisor: {np.std(x3 * i) / np.std(x3)}") print(f"x: {np.std(y3 * i)}; Divisor: {np.std(y3 * i) / np.std(y3)}") print("\n") # The standard deviation changes in respect to the scaling factor with the relationship # new_sd = scaling_factor * old_sd # Calculation of semi-variance np.var(np.array([x for x in x3 if x <= np.mean(x3)])) np.var(np.array([x for x in y3 if x <= np.mean(y3)])) # We see that the difference between the semi-variance and variance in y is greater # than the same difference in x. #4) # Initialising a list to check for max values of Likelihood function checker = [] X = np.array([2.29, 19.98, 0.06, 12.01, 7.04, 2.44]) # Running loop over guesses and appending the Likelihood function to the checking list for i in np.arange(0.34, 0.36, 0.0001): checker.append(np.prod(i * np.exp(-i * X))) # Checking which value is maximum. np.arange(0.34, 0.36, 0.0001)[checker.index(max(checker))] # MLE approach using Scipy # This uses the Likelihood function directly and maximises it. def objective(x): return -1 * np.prod(x * np.exp(-x * X)) bounds = Bounds(0.34, 0.36) minimize(objective, np.array([0.30]), bounds=bounds)