chatgpt is bit worse today. We dont know what it went through. We can only hope for the best.
This commit is contained in:
1 parent
f744957373
commit
c70a62fd69
8 files changed
+641
-9
No files matched your search
@@ -0,0 +1,73 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
|
||||
def plot_cost_function(costs, iterations):
|
||||
"""Plot the cost function over iterations."""
|
||||
plt.figure(figsize=(8, 6))
|
||||
plt.plot(range(iterations), costs, label="Cost Function")
|
||||
plt.xlabel("Iterations")
|
||||
plt.ylabel("Cost")
|
||||
plt.title("Cost Function over Iterations")
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_data_with_regression_line(X, y, theta):
|
||||
"""Plot the data points and the regression line."""
|
||||
plt.figure(figsize=(8, 6))
|
||||
plt.scatter(X[:, 1], y, color="blue", label="Data Points")
|
||||
regression_line = np.dot(X, theta)
|
||||
plt.plot(X[:, 1], regression_line, color="red", label="Regression Line")
|
||||
plt.xlabel("Feature")
|
||||
plt.ylabel("Target")
|
||||
plt.title("Data and Regression Line")
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_predictions_vs_actual(y_actual, y_predicted):
|
||||
"""Plot predicted values against actual values."""
|
||||
plt.figure(figsize=(8, 6))
|
||||
plt.scatter(y_actual, y_predicted, color="green", label="Predictions vs Actual")
|
||||
plt.plot(
|
||||
[min(y_actual), max(y_actual)],
|
||||
[min(y_actual), max(y_actual)],
|
||||
color="red",
|
||||
label="Ideal Fit",
|
||||
)
|
||||
plt.xlabel("Actual Values")
|
||||
plt.ylabel("Predicted Values")
|
||||
plt.title("Predictions vs Actual Values")
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_residuals(y_actual, y_predicted):
|
||||
"""Plot residuals (errors) to evaluate model fit."""
|
||||
residuals = y_actual - y_predicted
|
||||
plt.figure(figsize=(8, 6))
|
||||
plt.scatter(y_predicted, residuals, color="purple", label="Residuals")
|
||||
plt.axhline(0, color="red", linestyle="--", label="Zero Error Line")
|
||||
plt.xlabel("Predicted Values")
|
||||
plt.ylabel("Residuals")
|
||||
plt.title("Residual Plot")
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_cost_comparison(costs_dict, iterations):
|
||||
"""Plot cost functions for multiple methods on the same graph."""
|
||||
plt.figure(figsize=(8, 6))
|
||||
for method, costs in costs_dict.items():
|
||||
plt.plot(range(iterations), costs, label=f"{method} Cost")
|
||||
plt.xlabel("Iterations")
|
||||
plt.ylabel("Cost")
|
||||
plt.title("Cost Function Comparison")
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
plt.show()
|
||||
@@ -0,0 +1,36 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
|
||||
def load_data(filename, verbose=False, drop_unnamed=True):
|
||||
try:
|
||||
# Load the dataset
|
||||
df = pd.read_csv(
|
||||
filename, dtype=np.float64
|
||||
) # Force float64 for higher precision
|
||||
if verbose:
|
||||
print("Data loaded successfully.")
|
||||
print("Data types:\n", df.dtypes)
|
||||
|
||||
# Drop unnamed/index columns if specified
|
||||
if drop_unnamed:
|
||||
df = df.loc[:, ~df.columns.str.contains("^Unnamed")]
|
||||
if verbose:
|
||||
print("Dropped unnamed columns.")
|
||||
|
||||
# Features (X) = all but last column, Target (y) = last column
|
||||
X = df.iloc[:, :-1].values
|
||||
y = df.iloc[:, -1].values
|
||||
|
||||
if verbose:
|
||||
print("Shape of X:", X.shape)
|
||||
print("Shape of y:", y.shape)
|
||||
|
||||
return X, y
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f"Error: File '{filename}' not found.")
|
||||
raise
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
raise
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
import numpy as np
|
||||
|
||||
|
||||
# Hypothesis function
|
||||
def hypothesis(X, theta):
|
||||
"""
|
||||
Compute the hypothesis (predictions) for the given input and parameters.
|
||||
"""
|
||||
|
||||
result = np.dot(X, theta).reshape(-1, 1)
|
||||
# print("Shape of X:", X.shape)
|
||||
# print("Shape of theta:", theta.shape)
|
||||
# print("Shape of hypothesis output:", result.shape)
|
||||
return result
|
||||
|
||||
|
||||
# Cost function (Mean Squared Error)
|
||||
def compute_cost(X, y, theta):
|
||||
"""
|
||||
Compute the cost (Mean Squared Error) for the given input, target, and parameters.
|
||||
"""
|
||||
m = len(y)
|
||||
predictions = hypothesis(X, theta)
|
||||
errors = predictions - y
|
||||
cost = (1 / (2 * m)) * np.sum(errors**2)
|
||||
# # print(f"Max error: {np.max(errors):.4f}, Cost: {cost:.4f}") # Debugging
|
||||
return cost
|
||||
|
||||
|
||||
# Compute gradients
|
||||
def compute_gradients(theta, X, y):
|
||||
"""
|
||||
Compute gradients for gradient descent.
|
||||
|
||||
Parameters:
|
||||
theta (numpy.ndarray): Model parameters (n,).
|
||||
X (numpy.ndarray): Feature matrix (m, n).
|
||||
y (numpy.ndarray): Target values (m, 1).
|
||||
|
||||
Returns:
|
||||
numpy.ndarray: Gradients (n,).
|
||||
"""
|
||||
|
||||
# print("Shape of theta, X, y:", theta.shape, X.shape, y.shape)
|
||||
m = len(y)
|
||||
errors = hypothesis(X, theta) - y # Compute prediction errors
|
||||
# print("Shape of errors:", errors.shape) # Debugging
|
||||
gradients = (1 / m) * np.dot(X.T, errors) # Compute gradients
|
||||
# print("Shape of gradients:", gradients.shape) # Debugging
|
||||
return gradients.flatten()
|
||||
|
||||
|
||||
# Gradient Descent function (Batch)
|
||||
def gradient_descent(X, y, theta, learning_rate, iterations, return_cost: bool = False):
|
||||
"""
|
||||
Perform batch gradient descent to optimize theta.
|
||||
"""
|
||||
if return_cost:
|
||||
costs = []
|
||||
for _i in range(iterations):
|
||||
# print("Shape of X:", X.shape) # Should be (200, 4)
|
||||
# print("Shape of y:", y.shape) # Should be (200, 1)
|
||||
# print("Shape of theta:", theta.shape) # Should be (4,)
|
||||
gradients = compute_gradients(theta, X, y) # Compute gradients
|
||||
# print(f"Iteration {i + 1}:")
|
||||
# print(f" Shape of theta: {theta.shape}")
|
||||
# print(f" Shape of gradients: {gradients.shape}")
|
||||
theta -= learning_rate * gradients # Update theta
|
||||
if return_cost:
|
||||
cost = compute_cost(X, y, theta)
|
||||
costs.append(cost) # Track cost
|
||||
# print(f" Cost: {cost:.4f}")
|
||||
return (theta, costs) if return_cost else theta
|
||||
|
||||
|
||||
# Mini-batch Gradient Descent function
|
||||
def mini_batch_gradient_descent(
|
||||
X, y, theta, learning_rate, iterations, batch_size, return_cost: bool = False
|
||||
):
|
||||
"""
|
||||
Perform mini-batch gradient descent to optimize theta.
|
||||
"""
|
||||
m = len(y)
|
||||
if return_cost:
|
||||
costs = []
|
||||
for _i in range(iterations):
|
||||
shuffle_indices = np.random.permutation(m)
|
||||
X_shuffled = X[shuffle_indices]
|
||||
y_shuffled = y[shuffle_indices]
|
||||
|
||||
for j in range(0, m, batch_size):
|
||||
X_batch = X_shuffled[j : j + batch_size]
|
||||
y_batch = y_shuffled[j : j + batch_size]
|
||||
gradients = compute_gradients(theta, X_batch, y_batch) # Compute gradients
|
||||
theta -= learning_rate * gradients # Update theta
|
||||
if return_cost:
|
||||
cost = compute_cost(X, y, theta)
|
||||
costs.append(cost) # Track cost
|
||||
# print(f"Iteration {i + 1}/{iterations}, Cost: {cost:.4f}") # Debugging
|
||||
return (theta, costs) if return_cost else theta
|
||||
|
||||
|
||||
# Stochastic Gradient Descent function
|
||||
def stochastic_gradient_descent(
|
||||
X, y, theta, learning_rate, iterations, return_cost: bool = False
|
||||
):
|
||||
"""
|
||||
Perform stochastic gradient descent to optimize theta.
|
||||
"""
|
||||
m = len(y)
|
||||
if return_cost:
|
||||
costs = []
|
||||
for _i in range(iterations):
|
||||
for j in range(m):
|
||||
X_sample = X[j : j + 1]
|
||||
y_sample = y[j : j + 1]
|
||||
gradients = compute_gradients(
|
||||
theta, X_sample, y_sample
|
||||
) # Compute gradients
|
||||
theta -= learning_rate * gradients # Update theta
|
||||
if return_cost:
|
||||
cost = compute_cost(X, y, theta)
|
||||
costs.append(cost) # Track cost
|
||||
# print(f"Iteration {i + 1}/{iterations}, Cost: {cost:.4f}") # Debugging
|
||||
return (theta, costs) if return_cost else theta
|
||||
+299
@@ -0,0 +1,299 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ee8e9389",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# no way\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "fa275d88",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import warnings\n",
|
||||
"\n",
|
||||
"warnings.filterwarnings(\"error\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0d63f004",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Data loaded successfully.\n",
|
||||
"Data types:\n",
|
||||
" Unnamed: 0 float64\n",
|
||||
"TV float64\n",
|
||||
"radio float64\n",
|
||||
"newspaper float64\n",
|
||||
"sales float64\n",
|
||||
"dtype: object\n",
|
||||
"Dropped unnamed columns.\n",
|
||||
"Shape of X: (200, 3)\n",
|
||||
"Shape of y: (200,)\n",
|
||||
"Shape of y before reshaping: (200,)\n",
|
||||
"Shape of y after reshaping: (200, 1)\n",
|
||||
"Shape of X after adding bias term: (200, 4)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Load the data\n",
|
||||
"import file_reader\n",
|
||||
"\n",
|
||||
"filename = \"Advertising.csv\"\n",
|
||||
"X, y = file_reader.load_data(filename, verbose=True)\n",
|
||||
"\n",
|
||||
"# print(\"Shape of X:\", X.shape)\n",
|
||||
"# print(\"Shape of y:\", y.shape)\n",
|
||||
"\n",
|
||||
"print(\"Shape of y before reshaping:\", y.shape)\n",
|
||||
"y = y.reshape(-1, 1)\n",
|
||||
"print(\"Shape of y after reshaping:\", y.shape)\n",
|
||||
"# Add a bias term to X (for the intercept)\n",
|
||||
"import numpy as np\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"import regulations\n",
|
||||
"\n",
|
||||
"X_scaled = regulations.standardize(X)\n",
|
||||
"## Add bias term (column of 1s)\n",
|
||||
"# X = np.hstack([np.ones((X_scaled.shape[0], 1)), X_scaled])\n",
|
||||
"X = np.c_[np.ones(X_scaled.shape[0]), X_scaled]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"print(\"Shape of X after adding bias term:\", X.shape)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "0fa06674",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Shape of theta: (4,)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Initialize parameters\n",
|
||||
"theta = np.zeros(X.shape[1]) # Initialize theta with zeros\n",
|
||||
"# Reshape theta to ensure proper alignment\n",
|
||||
"# theta = theta.reshape(-1, 1)\n",
|
||||
"print(\"Shape of theta:\", theta.shape)\n",
|
||||
"\n",
|
||||
"learning_rate = 0.001\n",
|
||||
"iterations = 1000\n",
|
||||
"batch_size = 32 # For mini-batch gradient descent"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "8d5bf6a6",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Theta batch: [ 1.40204919e+01 3.91562216e+00 2.79885945e+00 -1.09326135e-02]\n",
|
||||
"Theta (mini_batch): [ 1.40204919e+01 3.91562216e+00 2.79885945e+00 -1.09326135e-02]\n",
|
||||
"Theta (stochastic): [ 1.40204919e+01 3.91562216e+00 2.79885945e+00 -1.09326135e-02]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Import gradient functions\n",
|
||||
"import gradient\n",
|
||||
"\n",
|
||||
"# Run batch gradient descent and track costs\n",
|
||||
"theta_batch, costs_batch = gradient.gradient_descent(\n",
|
||||
" X, y, theta, learning_rate, iterations, return_cost=True\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Run mini-batch gradient descent and track costs\n",
|
||||
"theta_mini_batch, costs_mini_batch = gradient.mini_batch_gradient_descent(\n",
|
||||
" X, y, theta, learning_rate, iterations, batch_size, return_cost=True\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Run stochastic gradient descent and track costs\n",
|
||||
"theta_stochastic, costs_stochastic = gradient.stochastic_gradient_descent(\n",
|
||||
" X, y, theta, learning_rate, iterations, return_cost=True\n",
|
||||
")\n",
|
||||
"print(\"Theta batch:\", theta_batch)\n",
|
||||
"print(\"Theta (mini_batch):\", theta_mini_batch)\n",
|
||||
"print(\"Theta (stochastic):\", theta_stochastic)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "f9d6d9bf",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Theta (Normal Equation): [[14.0225 ]\n",
|
||||
" [ 3.91925365]\n",
|
||||
" [ 2.79206274]\n",
|
||||
" [-0.02253861]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Solve using the improved normal equation\n",
|
||||
"import normal\n",
|
||||
"\n",
|
||||
"theta_normal = normal.normal_equation(X, y)\n",
|
||||
"print(\"Theta (Normal Equation):\", theta_normal)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "5becf82a",
|
||||
"metadata": {
|
||||
"id": "7cf220ac",
|
||||
"language": "python"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 800x600 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAq8AAAIhCAYAAABg21M1AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAYttJREFUeJzt3Xd4VGXe//HPmclk0hMgJCGQQOi9CeICCkhxAVHWtSuibrFgQV0L6iq4q6jPrg+ujdVV8NFF/a2FVddFogI2pDcBKUqHEGoKaZPM/fsjZCSkkMAkZyZ5v64rF8k9Z+Z8M99EP9zc5z6WMcYIAAAACAIOuwsAAAAAaorwCgAAgKBBeAUAAEDQILwCAAAgaBBeAQAAEDQIrwAAAAgahFcAAAAEDcIrAAAAggbhFQAAAEGD8Ao0AmvXrtUNN9ygtLQ0hYWFKSoqSn379tXTTz+tw4cP18k5n3jiCc2dO7fGx1uWVelHfHx8ndRXUxs2bNDUqVO1ffv2Co9df/31atOmTb3XFEyuv/56RUVFlRt78cUXNXv2bHsKqkEd27dvl2VZAVEjgIosbg8LNGyvvPKKbr31VnXq1Em33nqrunbtKo/Ho+XLl+uVV15Rr1699MEHH/j9vFFRUbr00ktrHAAsy9Kll16qe+65p9y4y+XSWWed5ff6aurdd9/VZZddpgULFmjo0KHlHvvxxx+VnZ2tPn362FNcELj++uv17rvvKjc31zfWvXt3xcfHa+HChfYVVk0dhYWFWrVqldq1a6fmzZvbUxyAKoXYXQCAurN48WLdcsstGjlypObOnSu32+17bOTIkbrnnns0b948GyssLzExUeecc47dZdRYu3bt7C4hIOTn5ys8PNzWGowxKigo8Esdbrc7qH4OgcaGZQNAA/bEE0/Isiy9/PLL5YJrmdDQUF100UW+r71er55++ml17txZbrdbCQkJuu6667R79+5yz1u1apUuvPBCJSQkyO12Kzk5WWPHjvUdZ1mWjh07ptdff933z/8nz1rWVlX/RD916lRZllVuzLIs3XbbbXrjjTfUpUsXRUREqFevXvr4448rPP+HH37QVVddpcTERLndbqWmpuq6665TYWGhZs+ercsuu0ySNGzYMN/3UjabXFlNBQUFmjJlitLS0hQaGqqWLVtq0qRJOnr0aLnj2rRpowsvvFDz5s1T3759FR4ers6dO+u1116r0ftx+PBh3XrrrWrZsqVCQ0PVtm1bPfTQQyosLPQd06dPH5177rkVnltSUqKWLVvqkksu8Y0VFRXpz3/+s6/3zZs31w033KADBw5UWvf777+vPn36KCwsTNOmTatRzWXPX79+vRYtWuR7P098D7Ozs/WHP/yh3Ps3efJkHTt2rNzrlPV45syZ6tKli9xut15//XVJ0rRp0zRgwAA1bdpUMTEx6tu3r1599VWd+A+N1dVR1bKBr7/+WsOHD1d0dLQiIiI0cOBA/ec//yl3zOzZs2VZlhYsWKBbbrlF8fHxatasmS655BLt3bu33LFffPGFhg4dqmbNmik8PFypqan69a9/rby8vBq/n0BjxMwr0ECVlJToiy++0FlnnaWUlJQaPeeWW27Ryy+/rNtuu00XXnihtm/frj/+8Y9auHChVq5cqfj4eB07dkwjR45UWlqaXnjhBSUmJiojI0MLFixQTk6OpNIZ3/PPP1/Dhg3TH//4R0lSTEzMKc9vjFFxcXG5MafTWSGc1sR//vMfLVu2TI899piioqL09NNP61e/+pU2bdqktm3bSpLWrFmjwYMHKz4+Xo899pg6dOigffv26cMPP1RRUZHGjh2rJ554Qg8++KBeeOEF9e3bV1LVM67GGI0fP16ff/65pkyZonPPPVdr167Vo48+qsWLF2vx4sXl/hKxZs0a3XPPPXrggQeUmJiof/zjH/rNb36j9u3b67zzzqvyeysoKNCwYcP0448/atq0aerZs6e++uorTZ8+XatXr/YFqhtuuEF33nmntmzZog4dOvieP3/+fO3du1c33HCDpNK/tFx88cX66quvdN9992ngwIHasWOHHn30UQ0dOlTLly8vN6O5cuVKbdy4UQ8//LDS0tIUGRlZ47588MEHuvTSSxUbG6sXX3xRknzvSV5enoYMGaLdu3frwQcfVM+ePbV+/Xo98sgjWrdunT777LNyPwtz587VV199pUceeURJSUlKSEiQVBo+b7rpJqWmpkqSvvvuO91+++3as2ePHnnkkVPWUZlFixZp5MiR6tmzp1599VW53W69+OKLGjdunN566y1dccUV5Y7/7W9/q7Fjx2rOnDnatWuX7r33Xl177bX64osvfDWOHTtW5557rl577TXFxcVpz549mjdvnoqKihQREVHj9xRodAyABikjI8NIMldeeWWNjt+4caORZG699dZy40uWLDGSzIMPPmiMMWb58uVGkpk7d261rxcZGWkmTpxY43olVfrxyiuvGGOMmThxomndunWF5z366KPm5P+USTKJiYkmOzvbN5aRkWEcDoeZPn26b+z88883cXFxJjMzs8q6/vWvfxlJZsGCBRUeO7mmefPmGUnm6aefLnfcO++8YySZl19+2TfWunVrExYWZnbs2OEby8/PN02bNjU33XRTlfUYY8zMmTONJPP//t//Kzf+1FNPGUlm/vz5xhhjDh48aEJDQ329K3P55ZebxMRE4/F4jDHGvPXWW0aSee+998odt2zZMiPJvPjii+XqdjqdZtOmTdXWWGbixIkmMjKy3Fi3bt3MkCFDKhw7ffp043A4zLJly8qNv/vuu0aS+eSTT3xjkkxsbKw5fPhwtecvKSkxHo/HPPbYY6ZZs2bG6/Weso5t27YZSWbWrFm+sXPOOcckJCSYnJwc31hxcbHp3r27adWqle91Z82aVenv0dNPP20kmX379pX7nlavXl1t/QAqYtkAAEnSggULJJX+U/iJzj77bHXp0kWff/65JKl9+/Zq0qSJ7r//fs2cOVMbNmzwWw2XX365li1bVu5j/Pjxp/Vaw4YNU3R0tO/rxMREJSQkaMeOHZJKZ/kWLVqkyy+/3G8X5ZTNqp38Hl522WWKjIz0vYdlevfu7ZsdlKSwsDB17NjRV2N154mMjNSll15abrzsvGXnadasmcaNG6fXX39dXq9XknTkyBH9+9//1nXXXaeQkNJ/fPv4448VFxencePGqbi42PfRu3dvJSUlVbigqWfPnurYseOp35Ba+vjjj9W9e3f17t27XB0XXHCBLMuqUMf555+vJk2aVHidL774QiNGjFBsbKycTqdcLpceeeQRHTp0SJmZmbWu69ixY1qyZIkuvfTScjsnOJ1OTZgwQbt379amTZvKPefE5ThS6Xsmydfb3r17KzQ0VL///e/1+uuv66effqp1XUBjRXgFGqj4+HhFRERo27ZtNTr+0KFDkqQWLVpUeCw5Odn3eGxsrBYtWqTevXvrwQcfVLdu3ZScnKxHH31UHo/njGpu3ry5+vXrV+7jdLfKatasWYUxt9ut/Px8SaUhrqSkRK1atTqjmk906NAhhYSEVAjDlmUpKSnJ9x7WtMbqzpOUlFRhOUVCQoJCQkLKnefGG2/Unj17lJ6eLkl66623VFhYWC5g79+/X0ePHlVoaKhcLle5j4yMDB08eLDceSr7GfGH/fv3a+3atRVqiI6OljGmRnUsXbpUo0aNklS608Y333yjZcuW6aGHHpKkU763lTly5IiMMVX+bkg6ZW/LliSUnb9du3b67LPPlJCQoEmTJqldu3Zq166dnn322VrXBzQ2rHkFGiin06nhw4frv//9r3bv3n3KkFb2P9t9+/ZVOHbv3r3lQmSPHj309ttvyxijtWvXavbs2XrssccUHh6uBx54wP/fjEpnJU+8GKnMyYGmppo2bSqn01nhYrQz0axZMxUXF+vAgQPlAqwxRhkZGerfv7/fzrNkyRIZY8oF2MzMTBUXF5fr1QUXXKDk5GTNmjVLF1xwgWbNmqUBAwaoa9euvmPKLiqqaueJE2ewJZ3WGuSaiI+PV3h4eJUXrZ38F5nK6nj77bflcrn08ccfKywszDdemz2HT9akSRM5HA7t27evwmNlF2Gdzl+yzj33XJ177rkqKSnR8uXL9dxzz2ny5MlKTEzUlVdeedr1Ag0dM69AAzZlyhQZY/S73/1ORUVFFR73eDz66KOPJJX+E6wkvfnmm+WOWbZsmTZu3Kjhw4dXeL5lWerVq5f+93//V3FxcVq5cqXvsZrMINZGmzZtlJmZqf379/vGioqK9Omnn57W64WHh2vIkCH617/+VW0APnnGrDpl79HJ7+F7772nY8eOVfoeno7hw4crNze3QiD7v//7v3J1SD//03bZxU3Lly/XjTfeWO55F154oQ4dOqSSkpIKM9/9+vVTp06d/FJ3map+Ni688EL9+OOPatasWaV11OSGEJZlKSQkRE6n0zeWn5+vN954o8Z1nCwyMlIDBgzQ+++/X+54r9erN998U61atTqjZRROp1MDBgzQCy+8IEnlfo8AVMTMK9CA/eIXv9BLL72kW2+9VWeddZZuueUWdevWTR6PR6tWrdLLL7+s7t27a9y4cerUqZN+//vf67nnnpPD4dDo0aN9uw2kpKTorrvuklS6LvHFF1/U+PHj1bZtWxlj9P777+vo0aMaOXKk79w9evTQwoUL9dFHH6lFixaKjo4+oxB0xRVX6JFHHtGVV16pe++9VwUFBfrb3/6mkpKS037NZ555RoMHD9aAAQP0wAMPqH379tq/f78+/PBD/f3vf1d0dLS6d+8uSXr55ZcVHR2tsLAwpaWlVfpP/iNHjtQFF1yg+++/X9nZ2Ro0aJBvt4E+ffpowoQJp13ria677jq98MILmjhxorZv364ePXro66+/1hNPPKExY8ZoxIgR5Y6/8cYb9dRTT+nqq69WeHh4hSvjr7zySv3zn//UmDFjdOedd+rss8+Line truncated
|
||||
"text/plain": [
|
||||
"<Figure size 800x600 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtYAAAIhCAYAAABqh/1nAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAYR1JREFUeJzt3Xl8VNX9//H3ZE8gCXtCNEBYFMIiGARBWRQIAlqsIrg04loQFxZbZFOBFlB+llILSPWL4lKFKoLWL19KEKEoEdlFwA0jKCQgi0nYkknm/P6Ic2VIAiG5ZBju6/l45IG5c+aeM/MZ8J2Tc891GWOMAAAAAFRKkL8HAAAAAFwMCNYAAACADQjWAAAAgA0I1gAAAIANCNYAAACADQjWAAAAgA0I1gAAAIANCNYAAACADQjWAAAAgA0I1gD87vPPP9e9996rpKQkRUREqHr16rryyis1ffp0HT58+Lz0OXXqVC1ZsqTc7V0uV6lfderUOS/jK68dO3Zo4sSJ+v7770s8ds8996hRo0ZVPqZAcs8996h69eo+x+bMmaP58+f7Z0DlGMf3338vl8t1QYwRgC8XtzQH4E8vvfSShg0bpssvv1zDhg1TcnKy3G63NmzYoJdeeklXXHGFFi9ebHu/1atX14ABA8odTlwulwYMGKDHH3/c53hoaKhSUlJsH195vfPOO7rtttv00UcfqXv37j6P7dq1S7m5uWrXrp1/BhcA7rnnHr3zzjs6evSodaxVq1aqU6eOVq1a5b+BnWEc+fn52rx5s5o0aaK6dev6Z3AAShXi7wEAcK6MjAw99NBD6tWrl5YsWaLw8HDrsV69eunxxx/XsmXL/DhCX3Fxcbr66qv9PYxya9Kkib+HcEE4ceKEIiMj/ToGY4xOnjxpyzjCw8MD6nMIOAlLQQD4zdSpU+VyufTiiy/6hGqvsLAw/eY3v7G+93g8mj59upo3b67w8HDVq1dPd999t3788Uef523evFk33nij6tWrp/DwcCUkJKhfv35WO5fLpWPHjunVV1+1lnScPtt7rspadjFx4kS5XC6fYy6XS4888ohef/11tWjRQlFRUbriiiv0wQcflHj+l19+qTvuuENxcXEKDw9XgwYNdPfddys/P1/z58/XbbfdJkm67rrrrNfinYUvbUwnT57U2LFjlZSUpLCwMF1yySV6+OGH9fPPP/u0a9SokW688UYtW7ZMV155pSIjI9W8eXO9/PLL5Xo/Dh8+rGHDhumSSy5RWFiYGjdurPHjxys/P99q065dO3Xp0qXEc4uKinTJJZfolltusY4VFBToz3/+s1X7unXr6t5779VPP/1U6rjfffddtWvXThEREZo0aVK5xux9/vbt27V69Wrr/Tz1PczNzdUf/vAHn/dvxIgROnbsmM95vDWeO3euWrRoofDwcL366quSpEmTJqljx46qVauWYmJidOWVV2revHk69RfIZxpHWUtBPv74Y/Xo0UPR0dGKiopS586d9b//+78+bebPny+Xy6WPPvpIDz30kOrUqaPatWvrlltu0b59+3zarly5Ut27d1ft2rUVGRmpBg0a6NZbb9Xx48fL/X4CTsOMNQC/KCoq0sqVK5WSkqLExMRyPeehhx7Siy++qEceeUQ33nijvv/+ez355JNatWqVNm3apDp16ujYsWPq1auXkpKSNHv2bMXFxSk7O1sfffSR8vLyJBXPlF9//fW67rrr9OSTT0qSYmJiztq/MUaFhYU+x4KDg0sE5/L43//9X61fv16TJ09W9erVNX36dP32t7/VV199pcaNG0uStm7dqmuvvVZ16tTR5MmT1axZM2VlZen9999XQUGB+vXrp6lTp2rcuHGaPXu2rrzySkllz1QbY3TzzTfrww8/1NixY9WlSxd9/vnnevrpp5WRkaGMjAyfH3C2bt2qxx9/XGPGjFFcXJz+53/+R/fff7+aNm2qrl27lvnaTp48qeuuu067du3SpEmT1KZNG61Zs0bTpk3Tli1brLB37733avjw4frmm2/UrFkz6/nLly/Xvn37dO+990oq/oGqf//+WrNmjUaPHq3OnTtr9+7devrpp9W9e3dt2LDBZyZ406ZN2rlzpyZMmKCkpCRVq1at3HVZvHixBgwYoNjYWM2ZM0eSrPfk+PHj6tatm3788UeNGzdObdq00fbt2/XUU09p27ZtWrFihc9nYcmSJVqzZo2eeuopxcfHq169epKKg/GQIUPUoEEDSdKnn36qRx99VHv37tVTTz111nGUZvXq1erVq5fatGmjefPmKTw8XHPmzNFNN92kt956S4MGDfJp/8ADD6hfv35688039cMPP+iPf/yjfve732nlypXWGPv166cuXbro5ZdfVo0aNbR3714tW7ZMBQUFioqKKvd7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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 800x600 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAArcAAAIhCAYAAABUopIpAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAiwZJREFUeJzs3XdcleX/x/HX4bA3iIDIUsGtuM2tKW7LLLWs1IZZtszKMhvar7S0zG+ZmVZqw+xbaeXInZoj98yVCxeIAwXZ4/79QZ5vhAMVOBx4Px+P85Bzz88510HfXue6r9tkGIaBiIiIiEgpYGftAkRERERECovCrYiIiIiUGgq3IiIiIlJqKNyKiIiISKmhcCsiIiIipYbCrYiIiIiUGgq3IiIiIlJqKNyKiIiISKmhcCsiIiIipYbCrYjcsJ07d/LQQw9RqVIlnJ2dcXd3p0GDBowbN47z588XyTnHjBnDTz/9VODtTSbTFR9+fn5FUl9B7dmzh1GjRnH06NF86wYOHEh4eHix13RZYmIib7/9No0aNcLT0xMnJyfCw8N5+OGH2bp1q9XqKi4rV67EZDKxcuVKa5ciIrfApNvvisiNmDZtGkOGDKFatWoMGTKEmjVrkpmZyebNm5k2bRpRUVHMnTu30M/r7u7OPffcw4wZMwq0vclk4p577uH555/Ps9zBwYGGDRsWen0F9cMPP9C7d29+++032rZtm2fdoUOHSExMpH79+sVe16FDh+jYsSPx8fE8/vjjtG3bFnd3d44ePcp///tfFi5cyIULF/Dy8ir22opLYmIie/bsoWbNmnh6elq7HBG5SfbWLkBEbMf69et54okniI6O5qeffsLJycmyLjo6mueff55FixZZscK8AgICuO2226xdRoFVqVLFKufNzs7mrrvu4uzZs6xfv57atWtb1rVp04YBAwbw66+/4uDgYJX6ilpmZiYmkwlPT0+b+ryIyJVpWIKIFNiYMWMwmUxMnTo1T7C9zNHRkTvuuMPyPCcnh3HjxlG9enWcnJzw9/enf//+nDhxIs9+27Zto3v37vj7++Pk5ERQUBDdunWzbGcymUhOTmbmzJmW4QX/7vW8UVcbAjBq1ChMJlOeZSaTiaeeeoqvvvqKGjVq4OrqSlRUFPPnz8+3/759+7jvvvsICAjAycmJ0NBQ+vfvT3p6OjNmzKB3794AtGvXzvJaLvdGX6mmtLQ0RowYQaVKlXB0dKRixYo8+eSTXLhwIc924eHhdO/enUWLFtGgQQNcXFyoXr06X3zxxXXfi59++oldu3YxYsSIPMH2n7p06YKrq6vl+Zo1a2jfvj0eHh64urrSvHlzFixYkGefGTNmYDKZWLFiBYMGDaJcuXJ4enrSv39/kpOTiYuLo0+fPnh7e1OhQgVeeOEFMjMzLfsfPXoUk8nEuHHjePvttwkNDcXZ2ZlGjRqxfPnyPOc6ePAgDz30EJGRkbi6ulKxYkV69OjBrl278mx3eejBV199xfPPP0/FihVxcnLi4MGDVxyWcPjwYe69916CgoJwcnIiICCA9u3bs337dss2Bf2ct23bltq1a7Np0yZatWqFq6srlStX5p133iEnJ+e67SQiBaOeWxEpkOzsbFasWEHDhg0JCQkp0D5PPPEEU6dO5amnnqJ79+4cPXqU1157jZUrV7J161b8/PxITk4mOjqaSpUq8fHHHxMQEEBcXBy//fYbSUlJQG6P8e233067du147bXXAAr0tbFhGGRlZeVZZjab84XXgliwYAGbNm3izTffxN3dnXHjxnHXXXexf/9+KleuDMCOHTto2bIlfn5+vPnmm0RGRhIbG8svv/xCRkYG3bp1Y8yYMbzyyit8/PHHNGjQALh6j61hGPTs2ZPly5czYsQIWrVqxc6dO3njjTdYv34969evz/OfjB07dvD888/z8ssvExAQwGeffcYjjzxCREQErVu3vuprW7JkCQA9e/Ys0HuxatUqoqOjqVu3Lp9//jlOTk5MnjyZHj168O2339K3b9882z/66KP06tWL2bNns23bNl555RWysrLYv38/vXr14rHHHmPZsmW8++67BAUFMWzYsDz7T5o0ibCwMCZOnGgJkl26dGHVqlU0a9YMgFOnTlGuXDneeecdypcvz/nz55k5cyZNmzZl27ZtVKtWLc8xR4wYQbNmzZgyZQp2dnb4+/sTFxeX77V27dqV7Oxsxo0bR2hoKGfPnmXdunV5/nNRkM/5ZXFxcdx///08//zzvPHGG8ydO5cRI0YQFBRE//79C/T+i8h1GCIiBRAXF2cAxr333lug7ffu3WsAxpAhQ/Is37BhgwEYr7zyimEYhrF582YDMH766adrHs/Nzc0YMGBAgesFrviYNm2aYRiGMWDAACMsLCzffm+88Ybx778aASMgIMBITEy0LIuLizPs7OyMsWPHWpbdfvvthre3txEfH3/Vur7//nsDMH777bd86/5d06JFiwzAGDduXJ7tvvvuOwMwpk6dalkWFhZmODs7GzExMZZlqamphq+vrzF48OCr1mMYhtG5c2cDMNLS0q653WW33Xab4e/vbyQlJVmWZWVlGbVr1zaCg4ONnJwcwzAMY/r06QZgPP3003n279mzpwEYEyZMyLO8Xr16RoMGDSzPjxw5YgBGUFCQkZqaalmemJho+Pr6Gh06dLhqjVlZWUZGRoYRGRlpPPfcc5blv/32mwEYrVu3zrfP5XWX2+bs2bMGYEycOPGq5yno59wwDKNNmzYGYGzYsCHPtjVr1jQ6dep01XOIyI3RsAQRKRK//fYbkPtV+z81adKEGjVqWL5WjoiIwMfHh5deeokpU6awZ8+eQquhT58+bNq0Kc+joL2T/9auXTs8PDwszwMCAvD39ycmJgaAlJQUVq1aRZ8+fShfvnxhlM+KFSuA/O9h7969cXNzy/fVfL169QgNDbU8d3Z2pmrVqpYaC0NycjIbNmzgnnvuwd3d3bLcbDbz4IMPcuLECfbv359nn+7du+d5XqNGDQC6deuWb/mVau3VqxfOzs6W5x4eHvTo0YPVq1eTnZ0NQFZWFmPGjKFmzZo4Ojpib2+Po6Mjf/31F3v37s13zLvvvvu6r9XX15cqVaowfvx4JkyYwLZt2/INHyjo5/yywMBAmjRpkmdZ3bp1C7WNRMo6hVsRKRA/Pz9cXV05cuRIgbY/d+4cABUqVMi3LigoyLLey8uLVatWUa9ePV555RVq1apFUFAQb7zxRp7xlzejfPnyNGrUKM/jZqcCK1euXL5lTk5OpKamApCQkEB2djbBwcG3VPM/nTt3Dnt7+3xh2WQyERgYaHkPC1rj1VwOxAVp24SEBAzDuGq7Xq77n3x9ffM8d3R0vOrytLS0fMcNDAy84rKMjAwuXboEwLBhw3jttdfo2bMn8+bNY8OGDWzatImoqKgrvv4r1f9vJpOJ5cuX06lTJ8aNG0eDBg0oX748zzzzjGXITEE/55fdbBuJSMEp3IpIgZjNZtq3b8+WLVvyXShzJZf/EY+Njc237tSpU3lCZp06dZg9ezbnzp1j+/bt9O3blzfffJP333+/8F7Avzg7O5Oenp5v+dmzZ2/qeL6+vpjN5gK9NwVVrlw5srKyOHPmTJ7lhmEQFxdXaHP2durUCaBA8wj7+PhgZ2d31XYFCn0u4SuNhY2Li8PR0dHSe/z111/Tv39/xowZQ6dOnWjSpAmNGjW6ansWdNx1WFgYn3/+OXFxcezfv5/nnnuOyZMn8+KLLwI39jkXkeKhcCsiBTZixAgMw2DQoEFkZGTkW5+Zmcm8efMAuP3224Hc0PFPmzZtYu/evbRv3z7f/iaTiaioKD744AO8vb3z3DigsHu3wsPDiY+P5/Tp05ZlGRkZLF68+KaO5+LiQps2bfj++++vGZAvXwBWkNdy+T3693v4448/kpycfMX38Gbceeed1KlTh7Fjx7J79+4rbrN48WJSUlJwc3OjadOmzJkzJ89ryMnJ4euvvyY4OJiqVasWSl2XzZkzJ0+PblJSEvPmzaNVq1aYzWYg97Pz7xk8FixYwMmTJwutjqpVq/Lqq69Sp04dy2fzZj7nIlK0NFuCiBRYs2bN+OSTTxgyZAgNGzbkiSeeoFatWmRmZrJt2zamTp1K7dq16dGjB9WqVeOxxx7jo48+ws7Oji5duliuIg8JCeG5554DYP78+UyePJmePXtSuXJlDMNgzpw5XLhwgejoaMu569Spw8qVK5k3bx4VKlTAw8Mj3xXwN6Jv3768/vrr3Hvvvbz44oukpaXx4YcfWsZw3owJEybQsmVLmjZtyssvv0xERASnT5/ml19+4dNPP8XDw8My1dbUqVPx8PDA2dmZSpUqXfHr6ujoaDp16sRLL71EYmIiLVq0sMyWUL9+fR588MGbrvWfzGYzc+fOpWPHjjRr1ownnniCdu3a4ebmRkxMDD/88APz5s0jISEBgLFjxxIdHU27du144YUXcHR0ZPLkyezevZtvv/32pmajuF590dHRDBs2jJycHN59910SExMZPXq0ZZvu3bszY8YMqlevTt26ddmyZQvjx4+/pWEiO3fu5KmnnqJ3795ERkbi6OjIihUr2LlzJy+//DJAgT/nIlKMrHs9m4jYou3btxsDBgwwQkNDDUdHR8PNzc2oX7++8frrr+eZKSA7O9t49913japVqxoODg6Gn5+f8cADDxjHjx+3bLNv3z7jvvvuM6pUqWK4uLgYXl5eRpMmTYwZM2bkO2eLFi0MV1dXAzDatGlzzRoB48knn7zmNgsXLjTq1atnuLi4GJUrVzYmTZp01dkSrnSssLCwfDM47Nmzx+jdu7dRrlw5w9HR0QgNDTUGDhyYZyaCiRMnGpUqVTLMZrMBGNOnTzcM48ozOKSmphovvfSSERYWZjg4OBgVKlQwnnjiCSMhISFfLd26dctXY5s2ba77Xl124cIF4//+7/+MBg0aGO7u7oaDg4MRGhpLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 800x600 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 800x600 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAq8AAAIhCAYAAABg21M1AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAokNJREFUeJzs3Xd4FGXXx/HvJoQUSEBqgIReBEUQG51EioBiNCAlgDQFO0VEfRABX7ALxI5KUwFBCHYpAhEQVKqgILZQJdIJNWV33j/WjSm7yWyyIdnk93kurouZnZ25d4c8ntxz7nMshmEYiIiIiIh4AZ/CHoCIiIiIiFkKXkVERETEayh4FRERERGvoeBVRERERLyGglcRERER8RoKXkVERETEayh4FRERERGvoeBVRERERLyGglcRERER8RoKXkVKiLlz52KxWNL/lCpVirCwMIYMGcLhw4cvyxhq167N4MGD07fj4+OxWCzEx8e7dZ6NGzcyadIkTp8+ne21iIgIIiIi8jXO4mDMmDFYLBZuu+22PJ9j9+7dTJo0iX379nluYDnI+u8jq59++gmLxcITTzzh8pjff/8di8XCI488Yvq6kyZNwmKxuDNUESlECl5FSpg5c+awadMmVq1axb333svChQtp164d58+fv+xjadGiBZs2baJFixZuvW/jxo1MnjzZafD65ptv8uabb3pohN4pNTWVDz/8EIDly5fn+ZeT3bt3M3ny5MsWvOamWbNmXHfddbz//vtYrVanx8yZMweAYcOGXc6hichlpOBVpIS5+uqradmyJZGRkUycOJFx48aRkJDAJ5984vI9Fy5cKJCxhISE0LJlS0JCQjx2ziZNmtCkSROPnc8bffrppxw7doxbb70Vq9XKvHnzCntIHjNs2DCOHDnC119/ne01q9XK+++/z3XXXUezZs0KYXQicjkoeBUp4Vq2bAnA/v37ARg8eDBly5Zl165ddOnSheDgYDp27AhASkoKU6ZM4corr8Tf35/KlSszZMgQjh07lumcqampjBs3jtDQUIKCgmjbti0//vhjtmu7Shv44Ycf6NGjBxUrViQgIIB69eoxatQowP6I97HHHgOgTp066WkQjnM4Sxs4efIkDzzwADVq1KB06dLUrVuX8ePHk5ycnOk4i8XCQw89xAcffEDjxo0JCgqiWbNmfPHFF5mOO3bsGMOHDyc8PDz9e2jTpg3ffPONy+/5k08+wWKxsHr16myvvfXWW1gsFnbu3AnAX3/9Rd++falevTr+/v5UrVqVjh07smPHDpfnz2jWrFmULl2aOXPmEB4ezpw5czAMI9txv/76K/369aNq1ar4+/tTs2ZN7r77bpKTk5k7dy533XUXAJGRkenf89y5cwHXj/izfv+XLl3i0UcfpXnz5pQrV44KFSrQqlUrPv30U1OfJauYmBgCAwPTZ1gzWrlyJYcPH2bo0KEALFq0iC5dulCtWjUCAwNp3LgxTzzxhKmnDBaLhUmTJmXb7+xzJyYmMmLECMLCwihdujR16tRh8uTJpKWlZTrurbfeolmzZpQtW5bg4GCuvPJK/ve//5n/8CICQKnCHoCIFK4//vgDgMqVK6fvS0lJ4fbbb2fEiBE88cQTpKWlYbPZiIqKYv369YwbN47WrVuzf/9+Jk6cSEREBFu2bCEwMBCAe++9l/fff5+xY8fSuXNnfv75Z6Kjozl79myu41mxYgU9evSgcePGTJs2jZo1a7Jv3z5WrlwJwD333MPJkyd57bXXiIuLo1q1agAuZ1svXbpEZGQkf/75J5MnT+aaa65h/fr1PPfcc+zYsYMvv/wy0/Fffvklmzdv5plnnqFs2bK8+OKL3Hnnnezdu5e6desCMHDgQLZt28bUqVNp2LAhp0+fZtu2bZw4ccLl57rtttuoUqUKc+bMSf9lwGHu3Lm0aNGCa665BoDu3btjtVp58cUXqVmzJsePH2fjxo1O0ySyOnToECtXrqRnz55UrlyZQYMGMWXKFNatW0eHDh3Sj/vpp59o27YtlSpV4plnnqFBgwYcOXKEzz77jJSUFG699VaeffZZ/ve///HGG2+kp3bUq1cv1zFklJyczMmTJxk7diw1atQgJSWFb775hujoaObMmcPdd9/t1vnKlStHz549WbRoEceOHcv073bOnDkEBAQQExMD2PNfu3fvzqhRoyhTpgy//vorL7zwAj/++CNr1qxx67quJCYmcuONN+Lj48PTTz9NvXr12LRpE1OmTGHfvn3pQfZHH33EAw88wMMPP8zLL7+Mj48Pf/zxB7t37/bIOERKFENESoQ5c+YYgPH9998bqampxtmzZ40vvvjCqFy5shEcHGwkJiYahmEYgwYNMgBj9uzZmd6/cOFCAzCWLl2aaf/mzZsNwHjzzTcNwzCMPXv2GIAxevToTMfNnz/fAIxBgwal71u7dq0BGGvXrk3fV69ePaNevXrGxYsXXX6Wl156yQCMhISEbK916NDB6NChQ/r222+/bQDG4sWLMx33wgsvGICxcuXK9H2AUbVqVSMpKSl9X2JiouHj42M899xz6fvKli1rjBo1yuX4XBkzZowRGBhonD59On3f7t27DcB47bXXDMMwjOPHjxuAMWPGDLfPbxiG8cwzzxiAsXz5csMwDOOvv/4yLBaLMXDgwEzH3XzzzUb58uWNo0ePujzXxx9/nO3+ONSqVSvTvXTI+v1nlZaWZqSmphrDhg0zrr32WlPnzMrx72batGnp+06cOGH4+/sb/fv3d/oem81mpKamGt9++60BGD/99FP6axMnTjSy/ucQMCZOnJjtPFnHOGLECKNs2bLG/v37Mx338ssvG4Dxyy+/GIZhGA899JBRvnz5XD+biOROaQMiJUzLli3x8/MjODiY2267jdDQUL7++muqVq2a6biePXtm2v7iiy8oX748PXr0IC0tLf1P8+bNCQ0NTX9sv3btWgD69++f6f29e/emVKmcH/b89ttv/PnnnwwbNoyAgIB8flK7NWvWUKZMGXr16pVpv+PRb9bH+JGRkQQHB6dvV61alSpVqqSnVQDceOONzJ07lylTpvD999+TmppqaixDhw7l4sWLLFq0KH3fnDlz8Pf3T58trFChAvXq1eOll15i2rRpbN++HZvNZur8hmGkpwp07twZsKdWREREsHTpUpKSkgB7DvO3335L7969M81cFpSPP/6YNm3aULZsWUqVKoWfnx+zZs1iz549eTpfhw4dqFevXqbUgfnz55OcnJyeMgD29IuYmBhCQ0Px9fXFz88vffY5r9fO6osvviAyMpLq1atn+rno1q0bAN9++y1g/zdz+vRp+vXrx6effsrx48c9cn2RkkjBq0gJ8/7777N582a2b9/O33//zc6dO2nTpk2mY4KCgrItovrnn384ffo0pUuXxs/PL9OfxMTE9P8YOx6dh4aGZnp/qVKlqFixYo5jc+TOhoWF5eszZnTixAlCQ0OzlUKqUqUKpUqVyvao39kY/f39uXjxYvr2okWLGDRoEO+99x6tWrWiQoUK3H333SQmJuY4lquuuoobbrghPeiyWq18+OGHREVFUaFCBYD0vNhbbrmFF198kRYtWlC5cmUeeeSRXNMu1qxZQ0JCAnfddRdJSUmcPn2a06dP07t3by5cuMDChQsBOHXqFFar1aPfsytxcXH07t2bGjVq8OGHH7Jp0yY2b97M0KFDuXTpUp7OabFYGDp0KLt27WLLli2A/ZeAOnXqEBkZCcC5c+do164dP/zwA1OmTCE+Pp7NmzcTFxcHkOl+5sc///zD559/nu1n4qqrrgJI/7kYOHAgs2fPZv/+/fTs2ZMqVapw0003sWrVKo+MQ6QkUc6rSAnTuHFjrr/++hyPcVbzslKlSlSsWJHly5c7fY9jttIR/CUmJlKjRo3019PS0nLMCYX/8m4PHTqU43HuqFixIj/88AOGYWT6XEePHiUtLY1KlSq5fc5KlSoxY8YMZsyYwYEDB/jss8944oknOHr0qMvvx2HIkCE88MAD7Nmzh7/++osjR44wZMiQTMfUqlWLWbNmAfbZ6MWLFzNp0iRSUlJ4++23XZ7b8Z5p06Yxbdo0p6+PGDGCChUq4Ovrm6/vOSAgINuCN7AHaxm/0w8//JA6deqwaNGiTN+/s/e6Y/DgwTz99NPMnj0bPz8/tm/fzv/93/+lX2PNmjX8/fffxMfHZ8r1NZM3DPZfWJyNMeu/4UqVKnHNNdcwdepUp+epXr16+t+HDBnCkCFDOH/+POvWrWPixIncdttt/Pbbb9SqVcvUuEREwauImHTbbbfx0UcfYbVauemmm1we51hpPn/+fK677rr0/YsXL862+jqrhg0bUq9ePWbPns2YMWPw9/d3epxjv5nZs44dO7J48WI++eQT7rzzzvT977//fvrr+VGzZk0eeughVq9ezXfffZfr8f369WPMmDHMnTuXv/76ixo1atClSxeXxzds2JCnnnqKpUuXsm3bNpfHnTp1imXLltGmTRumTJmS7fX33nuP+fPn8/PPP3P11VfToUMHPv74Y6ZOneoygM/pe65du3Z6dQSH3377jb1792Y6n8VioXTp0pkC18TExDxXG3CoXr06Xbt2ZeHChaSlpeHj48OgQYMyXTfjZ3CYOXOmqfM7+3xr1qzh3LlzmfbddtttfPXVV9SrV48rrrjC1LnLlClDt27dSElJ4Y477uCXX35R8CriBgWvImJK3759mT9/Pt27d2fkyJHceOON+Pn5cejQIdauXUtUVBR33nknjRs3ZsCAAcyYMQM/Pz86derEzz//zMsvv2yqnusbb7xBjx49aNmyJaNHj6ZmzZocOHCAFStWMH/+fACaNm0KQGxsLIMGDcLPz49GjRplylV1uPvuu3njjTcYNGgQ+/bto2nTpmzYsIFnn32W7t2706lTJ7e+hzNnzhAZGUlMTAxXXnklwcHBbN68meXLlxMdHZ3r+8uXL8+Line truncated
|
||||
"text/plain": [
|
||||
"<Figure size 800x600 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAArEAAAIhCAYAAABZvOJuAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAehNJREFUeJzt3Xt4E2X6N/Bv0paeA5RCW2hLi0AtUFDABUROylkRrAiC+oIiux5QEM+iS0HERVFBd0F+qIAHWLpQFQQLRaiigAgCopSqQGw5ydGm9ESbzPtHSWjSJJ0kk8xM8v1cF5c2eTJ5MpmZ3HPPPc+jEQRBABERERGRimjl7gARERERkasYxBIRERGR6jCIJSIiIiLVYRBLRERERKrDIJaIiIiIVIdBLBERERGpDoNYIiIiIlIdBrFEREREpDoMYomIiIhIdRjEElFAWb58OTQajeVfcHAwEhIScPfdd+O3337z2vtmZWVBo9GIapuSkoKJEyd6rS+u9MfczvyvUaNGSE1NxdSpU/HXX39Z2pnXq16vd7kvGzduRFZWlsuvI6LAxiCWiALSsmXLsHPnTmzZsgVTpkzBunXrcNNNN+HixYteeb8HH3wQO3fu9MqyfSE3Nxc7d+7Ehg0bMGrUKLzzzjsYNmwYpJi5fOPGjZg1a5YEvSSiQBIsdweIiOTQqVMndO/eHQDQv39/GI1GzJw5E5999hnuv/9+yd8vMTERiYmJki/XV7p164bY2FgAwKBBg3D+/Hl89NFH2LFjB3r37i1z74goEDETS0QEWALaP//80+rxPXv24Pbbb0dMTAzCwsJw/fXXIzs726pNeXk5nnrqKaSmpiIsLAwxMTHo3r07Vq1aZWlj7/J9dXU1nnnmGcTHxyMiIgI33XQTdu/eXa9vji7927uEv3r1agwePBgJCQkIDw9Heno6nnvuOZSVlbm8Tpzp2bMnAOCPP/5w2u6DDz5Aly5dLOvljjvuQEFBgeX5iRMn4j//+Q8AWJUtuFOWQESBhZlYIiIAx44dAwC0b9/e8ti2bdswdOhQ9OjRA++++y4aN26M//73vxg7dizKy8stdavTp0/HRx99hDlz5uD6669HWVkZfv75Z5w/f97pe06ePBkffvghnnrqKQwaNAg///wzMjMzUVpa6vbn+O233zB8+HBMmzYNkZGROHz4MObNm4fdu3dj69atbi/X1u+//w4AaN68ucM2r776Kl544QWMGzcOr776Ks6fP4+srCz06tULP/zwA9q1a4eXXnoJZWVlWLNmjVW5RUJCgmR9JSL/xCCWiAKS0WhETU0NKisr8d1332HOnDno27cvbr/9dkubRx55BB07dsTWrVsRHFx7uBwyZAjOnTuHF154Af/v//0/aLVafPfddxg8eDCeeOIJy2tvvfVWp+9/+PBhrFixAk888QRee+01ALWX6ePi4nDPPfe4/blefPFFy/8LgoDevXsjPT0d/fr1w08//YTOnTu7tVzz+rp06RI2bNiAd999F0lJSejTp4/d9n/99RdefvllDB8+HCtXrrQ83r9/f7Rr1w5ZWVn45JNPcM011yAuLg7A1ewuEZEYLCcgooDUs2dPhISEIDo6GkOHDkXTpk3x+eefW4LV33//HYcPH7YElDU1NZZ/w4cPx6lTp1BYWAgA+Nvf/oYvv/wSzz33HPLz81FRUdHg+2/btg0A6gWsY8aMsfTBHUePHsX48eMRHx+PoKAghISEoF+/fgBgdRnfVfHx8QgJCUHTpk1x7733omvXrsjNzUVYWJjd9jt37kRFRUW9URaSkpJw880346uvvnK7L0READOxRBSgPvzwQ6Snp6O0tBSrV6/GkiVLMG7cOHz55ZcArtbGPvXUU3jqqafsLuPcuXMAgLfffhuJiYlYvXo15s2bh7CwMAwZMgSvv/462rVrZ/e15lKD+Ph4q8eDg4PRrFkztz7TpUuX0KdPH4SFhWHOnDlo3749IiIiUFxcjMzMTFHBtSNbtmxB48aNERISgsTExAb7aP589soCWrZsiby8PLf7QkQEMIglogCVnp5uuZlrwIABMBqNeO+997BmzRqMHj3acif+888/j8zMTLvLSEtLAwBERkZi1qxZmDVrFv78809LVnbEiBE4fPiw3deag8DTp0+jVatWlsdramrq1dKas51VVVUIDQ21PG4Oos22bt2KkydPIj8/35J9BWA1nqu7unTpYlknYpg/36lTp+o9d/LkSZeWRURkD8sJiIgAvPbaa2jatCn++c9/wmQyIS0tDe3atcOBAwfQvXt3u/+io6PrLScuLg4TJ07EuHHjUFhYiPLycrvv179/fwDAJ598YvV4dnY2ampqrB5LSUkBAPz0009Wj69fv97qb/MIBnUDXQBYsmSJ8w/vBb16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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 800x600 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Import display functions\n",
|
||||
"import display\n",
|
||||
"%matplotlib inline\n",
|
||||
"\n",
|
||||
"# Plot cost functions for each gradient descent method\n",
|
||||
"display.plot_cost_function(costs_batch, iterations)\n",
|
||||
"display.plot_cost_function(costs_mini_batch, iterations)\n",
|
||||
"display.plot_cost_function(costs_stochastic, iterations)\n",
|
||||
"\n",
|
||||
"# Compare cost functions across methods\n",
|
||||
"costs_dict = {\n",
|
||||
" 'Batch': costs_batch,\n",
|
||||
" 'Mini-batch': costs_mini_batch,\n",
|
||||
" 'Stochastic': costs_stochastic\n",
|
||||
"}\n",
|
||||
"display.plot_cost_comparison(costs_dict, iterations)\n",
|
||||
"\n",
|
||||
"# Plot data with regression line (Batch Gradient Descent)\n",
|
||||
"display.plot_data_with_regression_line(X, y, theta_batch)\n",
|
||||
"\n",
|
||||
"# Compare predictions vs actual values (Batch Gradient Descent)\n",
|
||||
"y_pred_batch = np.dot(X, theta_batch).reshape(-1, 1)\n",
|
||||
"display.plot_predictions_vs_actual(y, y_pred_batch)\n",
|
||||
"\n",
|
||||
"# Plot residuals (Batch Gradient Descent)\n",
|
||||
"display.plot_residuals(y, y_pred_batch)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "base",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import numpy as np
|
||||
|
||||
|
||||
def normal_equation(X, y):
|
||||
"""
|
||||
Solve linear regression using the normal equation:
|
||||
θ = (X^T X)^(-1) X^T y
|
||||
Efficiently implemented using np.linalg.solve to avoid explicit matrix inversion.
|
||||
"""
|
||||
X_transpose = np.transpose(X)
|
||||
theta = np.linalg.solve(X_transpose @ X, X_transpose @ y)
|
||||
return theta
|
||||
+67
-8
@@ -13,29 +13,35 @@
|
||||
3. Redo exercise 1 with regularization
|
||||
4. Redo exercise 2 with regularization
|
||||
|
||||
## plan
|
||||
## plan for 1
|
||||
|
||||
what the fuck is a Linear regression?
|
||||
|
||||
it is to my knowledge: fit a thing to a linear equation, with the Minimal Error.
|
||||
|
||||
### the data
|
||||
|
||||
lets say the data has m rows. and its linear regression. pretty cool how you can train on all the data at the same time.
|
||||
|
||||
this is still basic ml after all
|
||||
|
||||
### error function, cost function: the thig we want reduced
|
||||
|
||||
this is the cost function, also loss function:
|
||||
|
||||
$$
|
||||
E = \frac{1}{2m} \sum^m_{i = 1}\left(h(x_{(i)})- y_{(i)}\right)^2
|
||||
E = \frac{1}{2m} \sum^m_{i = 1}\left(h(x^{(i)})- y^{(i)}\right)^2
|
||||
$$
|
||||
|
||||
with $h(x)$ being our model (we are trying to find a and b and make our guess $h(x)$ as close to $y$ as possible)
|
||||
|
||||
this comes from the error function here:
|
||||
|
||||
$$e = \frac{1}{2}\left(h(x_{(i)})-y_{(i)}\right)^2$$
|
||||
$$e = \frac{1}{2}\left(h(x^{(i)})-y^{(i)}\right)^2$$
|
||||
|
||||
and the cost function from the error function:
|
||||
|
||||
$$E = \frac{1}{m}\sum^m_{i=1}e_{(i)}$$
|
||||
$$E = \frac{1}{m}\sum^m_{i=1}e^{(i)}$$
|
||||
|
||||
as were dealing with linear fitting ($h(x) = ax + b$) the thing turns to this:
|
||||
|
||||
@@ -64,13 +70,66 @@ however they did the calculations:
|
||||
for our case $h(x) = ax + b$ we have
|
||||
|
||||
$$
|
||||
\frac{\partial}{\partial a}{E(a, b)}
|
||||
\text{ or } \\
|
||||
\frac{\partial E}{\partial a} = \frac{1}{m}\sum^m_{i=1}(ax_{(i)}+b - y_{(i)})\cdot x_{(i)}
|
||||
\begin{align*}
|
||||
&\frac{\partial}{\partial a}{E(a, b)} &&= \\
|
||||
&\frac{\partial E}{\partial a} &&= \frac{1}{m}\sum^m_{i=1}(ax^{(i)}+b - y^{(i)})\cdot x^{(i)}
|
||||
\end{align*}
|
||||
$$
|
||||
|
||||
yeah also for the case of b:
|
||||
|
||||
$$b:= b - \alpha \frac{\partial E}{\partial b}$$
|
||||
|
||||
$$\frac{\partial E}{\partial b} = \frac{1}{m}\sum^m_{i=1}(ax_{(i)}+b - y_{(i)})$$
|
||||
$$\frac{\partial E}{\partial b} = \frac{1}{m}\sum^m_{i=1}(ax^{(i)}+b - y^{(i)})$$
|
||||
|
||||
note that that $\alpha$ is important. its called learning rate.
|
||||
|
||||
### matrix rep. we go big
|
||||
|
||||
but now when the columns are many and the rows are also many, what do we do?
|
||||
|
||||
it is very convenient that the linear can be represented by a vector of x times a vector of coefficients (weights):
|
||||
|
||||
$$
|
||||
\theta = \begin{vmatrix}\theta_0 \\ \theta_1 \\ \cdots \\ \theta_n \end{vmatrix} \text{ and }x = \begin{vmatrix}1 \\ x_1 \\ \cdots \\ x_n \end{vmatrix}\\
|
||||
\implies h(x) = \theta^Tx
|
||||
$$
|
||||
|
||||
cost fucntion here:
|
||||
|
||||
$$
|
||||
E = \frac{1}{2m} \sum^m_{i = 1}\left(\theta^Tx^{(i)}- y^{(i)}\right)^2
|
||||
$$
|
||||
|
||||
and a very generalized gradient descent!!!
|
||||
|
||||
$$
|
||||
\theta_j:= \theta_j - \alpha \frac{\partial E}{\partial \theta_j}\\
|
||||
\frac{\partial E}{\partial \theta_j} = \frac{1}{m}\sum^m_{i=1}(\theta^Tx^{(i)} - y^{(i)})\cdot x^{(i)}_j
|
||||
$$
|
||||
|
||||
thats insane! also very codable! we already has dot product of 2 vectors `np.dot`, and that is for $\theta^Tx^{(i)}$. the entire table of x across m versions is just a 2d table.
|
||||
|
||||
so we could plug this into a
|
||||
|
||||
into a chatgpt LMAO aint no way doing this by hand
|
||||
|
||||
### ok when are we done?
|
||||
|
||||
so its an iterative method where you find a and b and all the other things at the same time using that. and again. and again.
|
||||
|
||||
the way we could turn off is jus check if E or e is small enough or we are looping too much
|
||||
|
||||
### any way to not ruin our computers?
|
||||
|
||||
this does NOT harm your computers. it requires NOTHING to run.
|
||||
|
||||
but see this. the m can be anything. it can be one. 64. the whole table.
|
||||
|
||||
that is Stochastic, Mini-batch and Batch. crazy. think about it.
|
||||
|
||||
## plan for 2
|
||||
|
||||
when i calculate $\frac{\partial E}{\partial \theta} = 0$ directly
|
||||
$$ \theta = (X^T X)^{-1} X^T Y$$
|
||||
???
|
||||
@@ -0,0 +1,29 @@
|
||||
def standardize_df(df):
|
||||
"""
|
||||
Standardize the input DataFrame.
|
||||
|
||||
Parameters:
|
||||
df (pandas.DataFrame): The input data.
|
||||
|
||||
Returns:
|
||||
pandas.DataFrame: The standardized data.
|
||||
"""
|
||||
return (df - df.mean()) / df.std()
|
||||
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
def standardize(X):
|
||||
"""
|
||||
Standardize the input features.
|
||||
|
||||
Parameters:
|
||||
X (numpy.ndarray): The input data matrix (m x n).
|
||||
|
||||
Returns:
|
||||
numpy.ndarray: The standardized data matrix.
|
||||
"""
|
||||
mean = np.mean(X, axis=0)
|
||||
std = np.std(X, axis=0)
|
||||
return (X - mean) / std
|
||||
Reference in new issue
Block a user