Files
UNI-PROG3-CW2-MLWP/Q1.ipynb
T
2026-04-25 16:25:54 +01:00

2962 lines
152 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "",
"id": "8a77807f92f26ee"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T10:00:23.434531Z",
"start_time": "2026-04-25T10:00:23.381273Z"
}
},
"cell_type": "markdown",
"source": [
"## This is the Q1 Notebook!\n",
"\n",
"It's tracked via GitHub! hence the need for this line for the init commit"
],
"id": "193cc36275a60171"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.236470700Z",
"start_time": "2026-04-25T14:53:58.228674500Z"
}
},
"cell_type": "code",
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns"
],
"id": "edaea0c939a83b79",
"outputs": [],
"execution_count": 371
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.254179900Z",
"start_time": "2026-04-25T14:53:58.237468900Z"
}
},
"cell_type": "code",
"source": "df = pd.read_csv('data/googleplaystore_new.csv')",
"id": "e657e9baacc13e6b",
"outputs": [],
"execution_count": 372
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Part A\n",
"id": "751a6161e8e12bdd"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.271506100Z",
"start_time": "2026-04-25T14:53:58.256180900Z"
}
},
"cell_type": "code",
"source": [
"df = df.dropna()\n",
"df = df.drop_duplicates()"
],
"id": "756c92821453bbb3",
"outputs": [],
"execution_count": 373
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.305298200Z",
"start_time": "2026-04-25T14:53:58.272504Z"
}
},
"cell_type": "code",
"source": "df.head(10)",
"id": "4e1be303d63f47a4",
"outputs": [
{
"data": {
"text/plain": [
" App Category Rating Reviews Size \\\n",
"0 Market Update Helper LIBRARIES_AND_DEMO 4.1 20145 11k \n",
"1 SuperLivePro BUSINESS 4.3 46353 21M \n",
"2 Wifi Connect Library LIBRARIES_AND_DEMO 3.9 58055 41k \n",
"3 Apk Installer LIBRARIES_AND_DEMO 3.8 7750 292k \n",
"4 English speaking texts EDUCATION 4.4 1619 3.0M \n",
"5 Eternal life LIBRARIES_AND_DEMO 5.0 26 2.5M \n",
"6 Dresses Ideas & Fashions +3000 BEAUTY 4.5 473 8.2M \n",
"7 GO Notifier COMMUNICATION 4.2 124346 695k \n",
"8 Prosperity EVENTS 5.0 16 2.3M \n",
"9 NSE Mobile Trading FINANCE 4.1 13868 1.4M \n",
"\n",
" Installs Type Price Content Rating Genres Android Ver \n",
"0 1,000,000+ Free 0 Everyone Libraries & Demo 1.5 and up \n",
"1 1,000,000+ Free 0 Everyone Business 1.5 and up \n",
"2 5,000,000+ Free 0 Everyone Libraries & Demo 1.5 and up \n",
"3 1,000,000+ Free 0 Everyone Libraries & Demo 1.6 and up \n",
"4 1,000,000+ Free 0 Everyone Education 1.6 and up \n",
"5 1,000+ Free 0 Everyone Libraries & Demo 1.6 and up \n",
"6 100,000+ Free 0 Mature 17+ Beauty 1.6 and up \n",
"7 10,000,000+ Free 0 Everyone Communication 2.0 and up \n",
"8 100+ Free 0 Everyone Events 2.0 and up \n",
"9 1,000,000+ Free 0 Everyone Finance 2.1 and up "
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>App</th>\n",
" <th>Category</th>\n",
" <th>Rating</th>\n",
" <th>Reviews</th>\n",
" <th>Size</th>\n",
" <th>Installs</th>\n",
" <th>Type</th>\n",
" <th>Price</th>\n",
" <th>Content Rating</th>\n",
" <th>Genres</th>\n",
" <th>Android Ver</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Market Update Helper</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>4.1</td>\n",
" <td>20145</td>\n",
" <td>11k</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.5 and up</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>SuperLivePro</td>\n",
" <td>BUSINESS</td>\n",
" <td>4.3</td>\n",
" <td>46353</td>\n",
" <td>21M</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Business</td>\n",
" <td>1.5 and up</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Wifi Connect Library</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>3.9</td>\n",
" <td>58055</td>\n",
" <td>41k</td>\n",
" <td>5,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.5 and up</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Apk Installer</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>3.8</td>\n",
" <td>7750</td>\n",
" <td>292k</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.6 and up</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>English speaking texts</td>\n",
" <td>EDUCATION</td>\n",
" <td>4.4</td>\n",
" <td>1619</td>\n",
" <td>3.0M</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Education</td>\n",
" <td>1.6 and up</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Eternal life</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>5.0</td>\n",
" <td>26</td>\n",
" <td>2.5M</td>\n",
" <td>1,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.6 and up</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>Dresses Ideas &amp; Fashions +3000</td>\n",
" <td>BEAUTY</td>\n",
" <td>4.5</td>\n",
" <td>473</td>\n",
" <td>8.2M</td>\n",
" <td>100,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Mature 17+</td>\n",
" <td>Beauty</td>\n",
" <td>1.6 and up</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>GO Notifier</td>\n",
" <td>COMMUNICATION</td>\n",
" <td>4.2</td>\n",
" <td>124346</td>\n",
" <td>695k</td>\n",
" <td>10,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Communication</td>\n",
" <td>2.0 and up</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>Prosperity</td>\n",
" <td>EVENTS</td>\n",
" <td>5.0</td>\n",
" <td>16</td>\n",
" <td>2.3M</td>\n",
" <td>100+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Events</td>\n",
" <td>2.0 and up</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>NSE Mobile Trading</td>\n",
" <td>FINANCE</td>\n",
" <td>4.1</td>\n",
" <td>13868</td>\n",
" <td>1.4M</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Finance</td>\n",
" <td>2.1 and up</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
]
},
"execution_count": 374,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 374
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T13:14:34.819448Z",
"start_time": "2026-04-25T13:14:34.807334900Z"
}
},
"cell_type": "markdown",
"source": "## Part B",
"id": "5e0e0e76635904b6"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.318866300Z",
"start_time": "2026-04-25T14:53:58.306302Z"
}
},
"cell_type": "code",
"source": [
"# Getting the column for size, checking if it's ending with an M or a k and converting the Mb to kb with 1024* and then again from kb to just b by another 1024*\n",
"def parse_size(size_str):\n",
" if isinstance(size_str, str):\n",
" if size_str.endswith('M'):\n",
" return float(size_str[:-1]) * 1024 * 1024\n",
" elif size_str.endswith('k'):\n",
" return float(size_str[:-1]) * 1024\n",
" return size_str"
],
"id": "c15cb7f9831e0f81",
"outputs": [],
"execution_count": 375
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.334856400Z",
"start_time": "2026-04-25T14:53:58.320864Z"
}
},
"cell_type": "code",
"source": "df['Size in bytes'] = df['Size'].apply(parse_size)",
"id": "c76da70de24ddc72",
"outputs": [],
"execution_count": 376
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.352396100Z",
"start_time": "2026-04-25T14:53:58.335858Z"
}
},
"cell_type": "code",
"source": "df[['Size', 'Size in bytes']].head(10)",
"id": "73784ad66975e81f",
"outputs": [
{
"data": {
"text/plain": [
" Size Size in bytes\n",
"0 11k 11264.0\n",
"1 21M 22020096.0\n",
"2 41k 41984.0\n",
"3 292k 299008.0\n",
"4 3.0M 3145728.0\n",
"5 2.5M 2621440.0\n",
"6 8.2M 8598323.2\n",
"7 695k 711680.0\n",
"8 2.3M 2411724.8\n",
"9 1.4M 1468006.4"
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Size</th>\n",
" <th>Size in bytes</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>11k</td>\n",
" <td>11264.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>21M</td>\n",
" <td>22020096.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>41k</td>\n",
" <td>41984.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>292k</td>\n",
" <td>299008.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>3.0M</td>\n",
" <td>3145728.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>2.5M</td>\n",
" <td>2621440.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>8.2M</td>\n",
" <td>8598323.2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>695k</td>\n",
" <td>711680.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>2.3M</td>\n",
" <td>2411724.8</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>1.4M</td>\n",
" <td>1468006.4</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
]
},
"execution_count": 377,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 377
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.384474Z",
"start_time": "2026-04-25T14:53:58.367405200Z"
}
},
"cell_type": "code",
"source": "print(11*1024) # Just checking the kb and mb conversion happened properly, by checking 2 of the values manually.",
"id": "7ac34d8bc88327a1",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"11264\n"
]
}
],
"execution_count": 378
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.423348900Z",
"start_time": "2026-04-25T14:53:58.385473600Z"
}
},
"cell_type": "code",
"source": "print((21*1024)*1024) # Ideally this is the same as doing the calculation without the ( ) but just incase!",
"id": "f72b05042c5a16fa",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"22020096\n"
]
}
],
"execution_count": 379
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.445406400Z",
"start_time": "2026-04-25T14:53:58.423348900Z"
}
},
"cell_type": "code",
"source": "print(1.4*1024*1024) # This one seemed odd... Checked on an online converted to double-check but turns out the 0.4 bytes shows up there too.",
"id": "dcaf54123ea0d75d",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1468006.4\n"
]
}
],
"execution_count": 380
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.464146900Z",
"start_time": "2026-04-25T14:53:58.446404300Z"
}
},
"cell_type": "code",
"source": "df.head(10)",
"id": "3e1112ae100d010c",
"outputs": [
{
"data": {
"text/plain": [
" App Category Rating Reviews Size \\\n",
"0 Market Update Helper LIBRARIES_AND_DEMO 4.1 20145 11k \n",
"1 SuperLivePro BUSINESS 4.3 46353 21M \n",
"2 Wifi Connect Library LIBRARIES_AND_DEMO 3.9 58055 41k \n",
"3 Apk Installer LIBRARIES_AND_DEMO 3.8 7750 292k \n",
"4 English speaking texts EDUCATION 4.4 1619 3.0M \n",
"5 Eternal life LIBRARIES_AND_DEMO 5.0 26 2.5M \n",
"6 Dresses Ideas & Fashions +3000 BEAUTY 4.5 473 8.2M \n",
"7 GO Notifier COMMUNICATION 4.2 124346 695k \n",
"8 Prosperity EVENTS 5.0 16 2.3M \n",
"9 NSE Mobile Trading FINANCE 4.1 13868 1.4M \n",
"\n",
" Installs Type Price Content Rating Genres Android Ver \\\n",
"0 1,000,000+ Free 0 Everyone Libraries & Demo 1.5 and up \n",
"1 1,000,000+ Free 0 Everyone Business 1.5 and up \n",
"2 5,000,000+ Free 0 Everyone Libraries & Demo 1.5 and up \n",
"3 1,000,000+ Free 0 Everyone Libraries & Demo 1.6 and up \n",
"4 1,000,000+ Free 0 Everyone Education 1.6 and up \n",
"5 1,000+ Free 0 Everyone Libraries & Demo 1.6 and up \n",
"6 100,000+ Free 0 Mature 17+ Beauty 1.6 and up \n",
"7 10,000,000+ Free 0 Everyone Communication 2.0 and up \n",
"8 100+ Free 0 Everyone Events 2.0 and up \n",
"9 1,000,000+ Free 0 Everyone Finance 2.1 and up \n",
"\n",
" Size in bytes \n",
"0 11264.0 \n",
"1 22020096.0 \n",
"2 41984.0 \n",
"3 299008.0 \n",
"4 3145728.0 \n",
"5 2621440.0 \n",
"6 8598323.2 \n",
"7 711680.0 \n",
"8 2411724.8 \n",
"9 1468006.4 "
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>App</th>\n",
" <th>Category</th>\n",
" <th>Rating</th>\n",
" <th>Reviews</th>\n",
" <th>Size</th>\n",
" <th>Installs</th>\n",
" <th>Type</th>\n",
" <th>Price</th>\n",
" <th>Content Rating</th>\n",
" <th>Genres</th>\n",
" <th>Android Ver</th>\n",
" <th>Size in bytes</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Market Update Helper</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>4.1</td>\n",
" <td>20145</td>\n",
" <td>11k</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.5 and up</td>\n",
" <td>11264.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>SuperLivePro</td>\n",
" <td>BUSINESS</td>\n",
" <td>4.3</td>\n",
" <td>46353</td>\n",
" <td>21M</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Business</td>\n",
" <td>1.5 and up</td>\n",
" <td>22020096.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Wifi Connect Library</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>3.9</td>\n",
" <td>58055</td>\n",
" <td>41k</td>\n",
" <td>5,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.5 and up</td>\n",
" <td>41984.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Apk Installer</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>3.8</td>\n",
" <td>7750</td>\n",
" <td>292k</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.6 and up</td>\n",
" <td>299008.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>English speaking texts</td>\n",
" <td>EDUCATION</td>\n",
" <td>4.4</td>\n",
" <td>1619</td>\n",
" <td>3.0M</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Education</td>\n",
" <td>1.6 and up</td>\n",
" <td>3145728.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Eternal life</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>5.0</td>\n",
" <td>26</td>\n",
" <td>2.5M</td>\n",
" <td>1,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.6 and up</td>\n",
" <td>2621440.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>Dresses Ideas &amp; Fashions +3000</td>\n",
" <td>BEAUTY</td>\n",
" <td>4.5</td>\n",
" <td>473</td>\n",
" <td>8.2M</td>\n",
" <td>100,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Mature 17+</td>\n",
" <td>Beauty</td>\n",
" <td>1.6 and up</td>\n",
" <td>8598323.2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>GO Notifier</td>\n",
" <td>COMMUNICATION</td>\n",
" <td>4.2</td>\n",
" <td>124346</td>\n",
" <td>695k</td>\n",
" <td>10,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Communication</td>\n",
" <td>2.0 and up</td>\n",
" <td>711680.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>Prosperity</td>\n",
" <td>EVENTS</td>\n",
" <td>5.0</td>\n",
" <td>16</td>\n",
" <td>2.3M</td>\n",
" <td>100+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Events</td>\n",
" <td>2.0 and up</td>\n",
" <td>2411724.8</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>NSE Mobile Trading</td>\n",
" <td>FINANCE</td>\n",
" <td>4.1</td>\n",
" <td>13868</td>\n",
" <td>1.4M</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Finance</td>\n",
" <td>2.1 and up</td>\n",
" <td>1468006.4</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
]
},
"execution_count": 381,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 381
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T13:28:40.682532800Z",
"start_time": "2026-04-25T13:28:40.678521Z"
}
},
"cell_type": "markdown",
"source": "# Part C",
"id": "9883e69704d0a69e"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.503091400Z",
"start_time": "2026-04-25T14:53:58.483650900Z"
}
},
"cell_type": "code",
"source": "df['Numeric Installs'] = df['Installs'].str.replace('+', '').str.replace(',', '').astype(int)",
"id": "c8d4f46526918c20",
"outputs": [],
"execution_count": 382
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.525317500Z",
"start_time": "2026-04-25T14:53:58.504718Z"
}
},
"cell_type": "code",
"source": "df.head(10)",
"id": "cffd24a82d242352",
"outputs": [
{
"data": {
"text/plain": [
" App Category Rating Reviews Size \\\n",
"0 Market Update Helper LIBRARIES_AND_DEMO 4.1 20145 11k \n",
"1 SuperLivePro BUSINESS 4.3 46353 21M \n",
"2 Wifi Connect Library LIBRARIES_AND_DEMO 3.9 58055 41k \n",
"3 Apk Installer LIBRARIES_AND_DEMO 3.8 7750 292k \n",
"4 English speaking texts EDUCATION 4.4 1619 3.0M \n",
"5 Eternal life LIBRARIES_AND_DEMO 5.0 26 2.5M \n",
"6 Dresses Ideas & Fashions +3000 BEAUTY 4.5 473 8.2M \n",
"7 GO Notifier COMMUNICATION 4.2 124346 695k \n",
"8 Prosperity EVENTS 5.0 16 2.3M \n",
"9 NSE Mobile Trading FINANCE 4.1 13868 1.4M \n",
"\n",
" Installs Type Price Content Rating Genres Android Ver \\\n",
"0 1,000,000+ Free 0 Everyone Libraries & Demo 1.5 and up \n",
"1 1,000,000+ Free 0 Everyone Business 1.5 and up \n",
"2 5,000,000+ Free 0 Everyone Libraries & Demo 1.5 and up \n",
"3 1,000,000+ Free 0 Everyone Libraries & Demo 1.6 and up \n",
"4 1,000,000+ Free 0 Everyone Education 1.6 and up \n",
"5 1,000+ Free 0 Everyone Libraries & Demo 1.6 and up \n",
"6 100,000+ Free 0 Mature 17+ Beauty 1.6 and up \n",
"7 10,000,000+ Free 0 Everyone Communication 2.0 and up \n",
"8 100+ Free 0 Everyone Events 2.0 and up \n",
"9 1,000,000+ Free 0 Everyone Finance 2.1 and up \n",
"\n",
" Size in bytes Numeric Installs \n",
"0 11264.0 1000000 \n",
"1 22020096.0 1000000 \n",
"2 41984.0 5000000 \n",
"3 299008.0 1000000 \n",
"4 3145728.0 1000000 \n",
"5 2621440.0 1000 \n",
"6 8598323.2 100000 \n",
"7 711680.0 10000000 \n",
"8 2411724.8 100 \n",
"9 1468006.4 1000000 "
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>App</th>\n",
" <th>Category</th>\n",
" <th>Rating</th>\n",
" <th>Reviews</th>\n",
" <th>Size</th>\n",
" <th>Installs</th>\n",
" <th>Type</th>\n",
" <th>Price</th>\n",
" <th>Content Rating</th>\n",
" <th>Genres</th>\n",
" <th>Android Ver</th>\n",
" <th>Size in bytes</th>\n",
" <th>Numeric Installs</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Market Update Helper</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>4.1</td>\n",
" <td>20145</td>\n",
" <td>11k</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.5 and up</td>\n",
" <td>11264.0</td>\n",
" <td>1000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>SuperLivePro</td>\n",
" <td>BUSINESS</td>\n",
" <td>4.3</td>\n",
" <td>46353</td>\n",
" <td>21M</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Business</td>\n",
" <td>1.5 and up</td>\n",
" <td>22020096.0</td>\n",
" <td>1000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Wifi Connect Library</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>3.9</td>\n",
" <td>58055</td>\n",
" <td>41k</td>\n",
" <td>5,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.5 and up</td>\n",
" <td>41984.0</td>\n",
" <td>5000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Apk Installer</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>3.8</td>\n",
" <td>7750</td>\n",
" <td>292k</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.6 and up</td>\n",
" <td>299008.0</td>\n",
" <td>1000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>English speaking texts</td>\n",
" <td>EDUCATION</td>\n",
" <td>4.4</td>\n",
" <td>1619</td>\n",
" <td>3.0M</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Education</td>\n",
" <td>1.6 and up</td>\n",
" <td>3145728.0</td>\n",
" <td>1000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Eternal life</td>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>5.0</td>\n",
" <td>26</td>\n",
" <td>2.5M</td>\n",
" <td>1,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Libraries &amp; Demo</td>\n",
" <td>1.6 and up</td>\n",
" <td>2621440.0</td>\n",
" <td>1000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>Dresses Ideas &amp; Fashions +3000</td>\n",
" <td>BEAUTY</td>\n",
" <td>4.5</td>\n",
" <td>473</td>\n",
" <td>8.2M</td>\n",
" <td>100,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Mature 17+</td>\n",
" <td>Beauty</td>\n",
" <td>1.6 and up</td>\n",
" <td>8598323.2</td>\n",
" <td>100000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>GO Notifier</td>\n",
" <td>COMMUNICATION</td>\n",
" <td>4.2</td>\n",
" <td>124346</td>\n",
" <td>695k</td>\n",
" <td>10,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Communication</td>\n",
" <td>2.0 and up</td>\n",
" <td>711680.0</td>\n",
" <td>10000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>Prosperity</td>\n",
" <td>EVENTS</td>\n",
" <td>5.0</td>\n",
" <td>16</td>\n",
" <td>2.3M</td>\n",
" <td>100+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Events</td>\n",
" <td>2.0 and up</td>\n",
" <td>2411724.8</td>\n",
" <td>100</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>NSE Mobile Trading</td>\n",
" <td>FINANCE</td>\n",
" <td>4.1</td>\n",
" <td>13868</td>\n",
" <td>1.4M</td>\n",
" <td>1,000,000+</td>\n",
" <td>Free</td>\n",
" <td>0</td>\n",
" <td>Everyone</td>\n",
" <td>Finance</td>\n",
" <td>2.1 and up</td>\n",
" <td>1468006.4</td>\n",
" <td>1000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
]
},
"execution_count": 383,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 383
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Part D",
"id": "1818d3183dae5398"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.573387900Z",
"start_time": "2026-04-25T14:53:58.546001500Z"
}
},
"cell_type": "code",
"source": "df.to_csv('data/googleplaystore_new_new.csv', index=False)",
"id": "5a99edb9f8b29b12",
"outputs": [],
"execution_count": 384
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# Part E",
"id": "5372c799c0b2662"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.580316100Z",
"start_time": "2026-04-25T14:53:58.575389500Z"
}
},
"cell_type": "code",
"source": [
"from sklearn.model_selection import train_test_split\n",
"from sklearn.linear_model import LinearRegression, Ridge\n",
"from sklearn.preprocessing import PolynomialFeatures\n",
"from sklearn.metrics import mean_absolute_error, mean_squared_error"
],
"id": "8cc741d5b19eaa62",
"outputs": [],
"execution_count": 385
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.591629700Z",
"start_time": "2026-04-25T14:53:58.583316400Z"
}
},
"cell_type": "code",
"source": "df_new = pd.read_csv('data/googleplaystore_new_new.csv')",
"id": "bc158bb312aa3cd7",
"outputs": [],
"execution_count": 386
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.607120700Z",
"start_time": "2026-04-25T14:53:58.591629700Z"
}
},
"cell_type": "code",
"source": [
"columns_to_keep = ['Category', 'Reviews', 'Content Rating', 'Size in bytes', 'Numeric Installs', 'Rating']\n",
"df_min = df_new[columns_to_keep]"
],
"id": "585677f9cc3efc16",
"outputs": [],
"execution_count": 387
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.628153200Z",
"start_time": "2026-04-25T14:53:58.608117200Z"
}
},
"cell_type": "code",
"source": "df_min.head(20)",
"id": "76760facf2a6e8cb",
"outputs": [
{
"data": {
"text/plain": [
" Category Reviews Content Rating Size in bytes \\\n",
"0 LIBRARIES_AND_DEMO 20145 Everyone 11264.0 \n",
"1 BUSINESS 46353 Everyone 22020096.0 \n",
"2 LIBRARIES_AND_DEMO 58055 Everyone 41984.0 \n",
"3 LIBRARIES_AND_DEMO 7750 Everyone 299008.0 \n",
"4 EDUCATION 1619 Everyone 3145728.0 \n",
"5 LIBRARIES_AND_DEMO 26 Everyone 2621440.0 \n",
"6 BEAUTY 473 Mature 17+ 8598323.2 \n",
"7 COMMUNICATION 124346 Everyone 711680.0 \n",
"8 EVENTS 16 Everyone 2411724.8 \n",
"9 FINANCE 13868 Everyone 1468006.4 \n",
"10 COMMUNICATION 32254 Everyone 5767168.0 \n",
"11 COMMUNICATION 125232 Everyone 2831155.2 \n",
"12 EDUCATION 430 Everyone 538624.0 \n",
"13 EDUCATION 275 Everyone 2411724.8 \n",
"14 BOOKS_AND_REFERENCE 1778 Mature 17+ 5138022.4 \n",
"15 BUSINESS 2287 Everyone 1572864.0 \n",
"16 LIBRARIES_AND_DEMO 126862 Everyone 638976.0 \n",
"17 COMMUNICATION 255 Everyone 1677721.6 \n",
"18 LIFESTYLE 360 Everyone 4823449.6 \n",
"19 EDUCATION 656 Everyone 569344.0 \n",
"\n",
" Numeric Installs Rating \n",
"0 1000000 4.1 \n",
"1 1000000 4.3 \n",
"2 5000000 3.9 \n",
"3 1000000 3.8 \n",
"4 1000000 4.4 \n",
"5 1000 5.0 \n",
"6 100000 4.5 \n",
"7 10000000 4.2 \n",
"8 100 5.0 \n",
"9 1000000 4.1 \n",
"10 1000000 4.4 \n",
"11 10000000 4.2 \n",
"12 10000 4.0 \n",
"13 50000 4.0 \n",
"14 500000 3.9 \n",
"15 1000000 4.4 \n",
"16 10000000 3.5 \n",
"17 10000 4.1 \n",
"18 10000 4.1 \n",
"19 10000 4.3 "
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Category</th>\n",
" <th>Reviews</th>\n",
" <th>Content Rating</th>\n",
" <th>Size in bytes</th>\n",
" <th>Numeric Installs</th>\n",
" <th>Rating</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>20145</td>\n",
" <td>Everyone</td>\n",
" <td>11264.0</td>\n",
" <td>1000000</td>\n",
" <td>4.1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>BUSINESS</td>\n",
" <td>46353</td>\n",
" <td>Everyone</td>\n",
" <td>22020096.0</td>\n",
" <td>1000000</td>\n",
" <td>4.3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>58055</td>\n",
" <td>Everyone</td>\n",
" <td>41984.0</td>\n",
" <td>5000000</td>\n",
" <td>3.9</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>7750</td>\n",
" <td>Everyone</td>\n",
" <td>299008.0</td>\n",
" <td>1000000</td>\n",
" <td>3.8</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>EDUCATION</td>\n",
" <td>1619</td>\n",
" <td>Everyone</td>\n",
" <td>3145728.0</td>\n",
" <td>1000000</td>\n",
" <td>4.4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>26</td>\n",
" <td>Everyone</td>\n",
" <td>2621440.0</td>\n",
" <td>1000</td>\n",
" <td>5.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>BEAUTY</td>\n",
" <td>473</td>\n",
" <td>Mature 17+</td>\n",
" <td>8598323.2</td>\n",
" <td>100000</td>\n",
" <td>4.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>COMMUNICATION</td>\n",
" <td>124346</td>\n",
" <td>Everyone</td>\n",
" <td>711680.0</td>\n",
" <td>10000000</td>\n",
" <td>4.2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>EVENTS</td>\n",
" <td>16</td>\n",
" <td>Everyone</td>\n",
" <td>2411724.8</td>\n",
" <td>100</td>\n",
" <td>5.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>FINANCE</td>\n",
" <td>13868</td>\n",
" <td>Everyone</td>\n",
" <td>1468006.4</td>\n",
" <td>1000000</td>\n",
" <td>4.1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>COMMUNICATION</td>\n",
" <td>32254</td>\n",
" <td>Everyone</td>\n",
" <td>5767168.0</td>\n",
" <td>1000000</td>\n",
" <td>4.4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>COMMUNICATION</td>\n",
" <td>125232</td>\n",
" <td>Everyone</td>\n",
" <td>2831155.2</td>\n",
" <td>10000000</td>\n",
" <td>4.2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>EDUCATION</td>\n",
" <td>430</td>\n",
" <td>Everyone</td>\n",
" <td>538624.0</td>\n",
" <td>10000</td>\n",
" <td>4.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>EDUCATION</td>\n",
" <td>275</td>\n",
" <td>Everyone</td>\n",
" <td>2411724.8</td>\n",
" <td>50000</td>\n",
" <td>4.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>BOOKS_AND_REFERENCE</td>\n",
" <td>1778</td>\n",
" <td>Mature 17+</td>\n",
" <td>5138022.4</td>\n",
" <td>500000</td>\n",
" <td>3.9</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>BUSINESS</td>\n",
" <td>2287</td>\n",
" <td>Everyone</td>\n",
" <td>1572864.0</td>\n",
" <td>1000000</td>\n",
" <td>4.4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>LIBRARIES_AND_DEMO</td>\n",
" <td>126862</td>\n",
" <td>Everyone</td>\n",
" <td>638976.0</td>\n",
" <td>10000000</td>\n",
" <td>3.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>COMMUNICATION</td>\n",
" <td>255</td>\n",
" <td>Everyone</td>\n",
" <td>1677721.6</td>\n",
" <td>10000</td>\n",
" <td>4.1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>LIFESTYLE</td>\n",
" <td>360</td>\n",
" <td>Everyone</td>\n",
" <td>4823449.6</td>\n",
" <td>10000</td>\n",
" <td>4.1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>EDUCATION</td>\n",
" <td>656</td>\n",
" <td>Everyone</td>\n",
" <td>569344.0</td>\n",
" <td>10000</td>\n",
" <td>4.3</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
]
},
"execution_count": 388,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 388
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.644258400Z",
"start_time": "2026-04-25T14:53:58.629151300Z"
}
},
"cell_type": "code",
"source": "df_encoded = pd.get_dummies(df_min, columns=['Category', 'Content Rating'])",
"id": "8c4742ab98b8b6ca",
"outputs": [],
"execution_count": 389
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.650381200Z",
"start_time": "2026-04-25T14:53:58.645767200Z"
}
},
"cell_type": "code",
"source": [
"X = df_encoded.drop('Rating', axis=1)\n",
"y = df_encoded['Rating']"
],
"id": "7faed3f843076351",
"outputs": [],
"execution_count": 390
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.668155500Z",
"start_time": "2026-04-25T14:53:58.652896500Z"
}
},
"cell_type": "code",
"source": "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=101)",
"id": "8646df724923b0f5",
"outputs": [],
"execution_count": 391
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Trying Linear Regression",
"id": "e52a65f09530a141"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.677596300Z",
"start_time": "2026-04-25T14:53:58.670162100Z"
}
},
"cell_type": "code",
"source": [
"linear_model = LinearRegression()\n",
"linear_model.fit(X_train, y_train)\n",
"y_hat_linear = linear_model.predict(X_test)"
],
"id": "db88942671bdf26a",
"outputs": [],
"execution_count": 392
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:57:40.714273700Z",
"start_time": "2026-04-25T14:57:40.674040700Z"
}
},
"cell_type": "code",
"source": "X_test",
"id": "32a5d474cc8ed681",
"outputs": [
{
"data": {
"text/plain": [
" Reviews Size in bytes Numeric Installs Category_ART_AND_DESIGN \\\n",
"303 70782 52428800.0 1000000 False \n",
"805 132014 26214400.0 10000000 False \n",
"352 58 15728640.0 10000 False \n",
"952 1658 10171187.2 100000 False \n",
"514 10852 18874368.0 1000000 False \n",
"... ... ... ... ... \n",
"1096 120 10485760.0 500 False \n",
"551 27396 61865984.0 1000000 False \n",
"660 11506 15728640.0 100000 False \n",
"655 1015 11534336.0 100000 True \n",
"473 7976 46137344.0 500000 False \n",
"\n",
" Category_AUTO_AND_VEHICLES Category_BEAUTY \\\n",
"303 False False \n",
"805 False False \n",
"352 False False \n",
"952 False False \n",
"514 False False \n",
"... ... ... \n",
"1096 False False \n",
"551 False False \n",
"660 False False \n",
"655 False False \n",
"473 False False \n",
"\n",
" Category_BOOKS_AND_REFERENCE Category_BUSINESS Category_COMICS \\\n",
"303 False False False \n",
"805 False False False \n",
"352 False False False \n",
"952 False False False \n",
"514 False False False \n",
"... ... ... ... \n",
"1096 False False False \n",
"551 False False False \n",
"660 False False False \n",
"655 False False False \n",
"473 False False False \n",
"\n",
" Category_COMMUNICATION ... Category_GAME Category_HEALTH_AND_FITNESS \\\n",
"303 False ... False False \n",
"805 True ... False False \n",
"352 False ... False False \n",
"952 False ... False False \n",
"514 False ... False False \n",
"... ... ... ... ... \n",
"1096 False ... False False \n",
"551 False ... False True \n",
"660 False ... False True \n",
"655 False ... False False \n",
"473 False ... False True \n",
"\n",
" Category_HOUSE_AND_HOME Category_LIBRARIES_AND_DEMO \\\n",
"303 False False \n",
"805 False False \n",
"352 False True \n",
"952 False False \n",
"514 False False \n",
"... ... ... \n",
"1096 False False \n",
"551 False False \n",
"660 False False \n",
"655 False False \n",
"473 False False \n",
"\n",
" Category_LIFESTYLE Content Rating_Adults only 18+ \\\n",
"303 False False \n",
"805 False False \n",
"352 False False \n",
"952 True False \n",
"514 False False \n",
"... ... ... \n",
"1096 False False \n",
"551 False False \n",
"660 False False \n",
"655 False False \n",
"473 False False \n",
"\n",
" Content Rating_Everyone Content Rating_Everyone 10+ \\\n",
"303 True False \n",
"805 True False \n",
"352 True False \n",
"952 True False \n",
"514 True False \n",
"... ... ... \n",
"1096 False False \n",
"551 False False \n",
"660 True False \n",
"655 True False \n",
"473 True False \n",
"\n",
" Content Rating_Mature 17+ Content Rating_Teen \n",
"303 False False \n",
"805 False False \n",
"352 False False \n",
"952 False False \n",
"514 False False \n",
"... ... ... \n",
"1096 True False \n",
"551 True False \n",
"660 False False \n",
"655 False False \n",
"473 False False \n",
"\n",
"[333 rows x 26 columns]"
],
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Reviews</th>\n",
" <th>Size in bytes</th>\n",
" <th>Numeric Installs</th>\n",
" <th>Category_ART_AND_DESIGN</th>\n",
" <th>Category_AUTO_AND_VEHICLES</th>\n",
" <th>Category_BEAUTY</th>\n",
" <th>Category_BOOKS_AND_REFERENCE</th>\n",
" <th>Category_BUSINESS</th>\n",
" <th>Category_COMICS</th>\n",
" <th>Category_COMMUNICATION</th>\n",
" <th>...</th>\n",
" <th>Category_GAME</th>\n",
" <th>Category_HEALTH_AND_FITNESS</th>\n",
" <th>Category_HOUSE_AND_HOME</th>\n",
" <th>Category_LIBRARIES_AND_DEMO</th>\n",
" <th>Category_LIFESTYLE</th>\n",
" <th>Content Rating_Adults only 18+</th>\n",
" <th>Content Rating_Everyone</th>\n",
" <th>Content Rating_Everyone 10+</th>\n",
" <th>Content Rating_Mature 17+</th>\n",
" <th>Content Rating_Teen</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>303</th>\n",
" <td>70782</td>\n",
" <td>52428800.0</td>\n",
" <td>1000000</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" </tr>\n",
" <tr>\n",
" <th>805</th>\n",
" <td>132014</td>\n",
" <td>26214400.0</td>\n",
" <td>10000000</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" </tr>\n",
" <tr>\n",
" <th>352</th>\n",
" <td>58</td>\n",
" <td>15728640.0</td>\n",
" <td>10000</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" </tr>\n",
" <tr>\n",
" <th>952</th>\n",
" <td>1658</td>\n",
" <td>10171187.2</td>\n",
" <td>100000</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" </tr>\n",
" <tr>\n",
" <th>514</th>\n",
" <td>10852</td>\n",
" <td>18874368.0</td>\n",
" <td>1000000</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1096</th>\n",
" <td>120</td>\n",
" <td>10485760.0</td>\n",
" <td>500</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" </tr>\n",
" <tr>\n",
" <th>551</th>\n",
" <td>27396</td>\n",
" <td>61865984.0</td>\n",
" <td>1000000</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" </tr>\n",
" <tr>\n",
" <th>660</th>\n",
" <td>11506</td>\n",
" <td>15728640.0</td>\n",
" <td>100000</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" </tr>\n",
" <tr>\n",
" <th>655</th>\n",
" <td>1015</td>\n",
" <td>11534336.0</td>\n",
" <td>100000</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" </tr>\n",
" <tr>\n",
" <th>473</th>\n",
" <td>7976</td>\n",
" <td>46137344.0</td>\n",
" <td>500000</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>...</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>333 rows × 26 columns</p>\n",
"</div>"
]
},
"execution_count": 401,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 401
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.695046Z",
"start_time": "2026-04-25T14:53:58.677596300Z"
}
},
"cell_type": "code",
"source": [
"print(f\"Mean absolute error = {mean_absolute_error(y_test, y_hat_linear)}\")\n",
"print(f\"Root mean squared error = {np.sqrt(mean_squared_error(y_test, y_hat_linear))}\")"
],
"id": "12af54f4b3a1a88d",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Mean absolute error = 0.28061256731153783\n",
"Root mean squared error = 0.38671187333256235\n"
]
}
],
"execution_count": 393
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.773436200Z",
"start_time": "2026-04-25T14:53:58.696048500Z"
}
},
"cell_type": "code",
"source": [
"residual_error = y_test - y_hat_linear\n",
"\n",
"plt.figure(figsize=(8,5))\n",
"plt.scatter(y_test, residual_error, alpha=0.5)\n",
"plt.axhline(y=0, color='r', linestyle='--') # Adds a red line at 0 error for reference\n",
"plt.title(\"Residual Error Plot (Linear Regression)\")\n",
"plt.xlabel(\"True Rating Values (y)\")\n",
"plt.ylabel(\"Residual Error (y - y_hat)\")\n",
"plt.show()"
],
"id": "8c3be82a8033d876",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 800x500 with 1 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAr8AAAHWCAYAAAB+CuHhAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjksIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvJkbTWQAAAAlwSFlzAAAPYQAAD2EBqD+naQAAietJREFUeJzt3Ql4VOXVB/Aza5bJnpCEJSwBZMcFFUEtqAgu1dpa61IruH1Va+tWK9qqxVbR1qqt+1Jxq11sq221ioiiVRFXVEB2kLAkgZB9mf17/ifMMEkmMzdhMplk/r/nGYZ7552Zm5tJcubMec9r8vv9fiEiIiIiSgLm3j4AIiIiIqJ4YfBLREREREmDwS8RERERJQ0Gv0RERESUNBj8EhEREVHSYPBLREREREmDwS8RERERJQ0Gv0RERESUNBj8EhEREVHSYPBLlKR++ctfislkMjQW4zC+J82cOVMvyS4e5zrUFVdcISeeeGKX7zd8+HCZN29ejxwTxcdTTz2lr7etW7f22HOsWbNGrFarrFq1qseeg6irGPwSJcgfoMAFfygGDx6sgcWOHTt6+/ASDoKu0PMVejnppJMkESG4CD1Oi8UiQ4cOlW9/+9uycuXKmAUZCJq7Eshs2bJFnnjiCbnppps6HOvdd98t/dWyZcs6fD8KCwvlu9/9rnz11Ve9fXj9yvjx4+XUU0+VW265pbcPhSjIuv+/RNSbbrvtNhkxYoS0tLTIBx98oEHxu+++qxmT1NTUmD/fL37xC5k/f770RYcccohcd911HfYPGjRIEtm5554rp5xyini9Xg2yHn74YXn11Vf1+42v6UCD3wULFmj2HG8QjPj973+vr7njjjuuy8+3bt06MZv7dv7kJz/5iRxxxBHidrvliy++kEceeUQDY/zMFRcXS3/3gx/8QM455xxJSUnp0ee57LLL9HW/adMmGTlyZI8+F5ERDH6JEsTJJ58shx9+uP7/kksukYKCArnrrrvk3//+t3zve9+L+fMhw4xLX4TM+Pnnn9/l+zU2NorD4eiw3+fzicvlOqA3GZ09dqjDDjuszXEfffTRcvrpp2sQ/Oijj0o8IeD705/+pIFJd/R0wHSgjHw/jj32WM32BowZM0Yuv/xyeeaZZ+RnP/uZxFNTU5Okp6fH9TmR8calp82aNUtyc3Pl6aef1jf5RL2tb79tJ+rH8IcZkC0JtXbtWv2DnZeXp8EaAmYEyO0DG2QBR48erWPy8/PlmGOOkSVLlkSs+XU6nXLNNdfIgAEDJDMzUwOz7du3dzg2lGSEyy6Ge8xFixbJ8ccfrx8rI2DCx6AI9noajjEjI0PPH7JO+Hq+//3v6204xiuvvFKDvwkTJuhxvfbaa3rbZ599pm9EsrKy9P4nnHCCZmbDlaq8/fbbWjOLr23IkCFdPkacl0D5QSTRjgnHc9ZZZ+n/kcUNfJyPLGZn8KnCnj17NDDpjvY1v4Fz8t5778m1116rryEEnyjt2L17d4f7I+ON1zjG4HuDj8ZXr17dZgyysXiO0tJSfR0jG3vRRRdJVVVV2Ncdst/nnXeeBlp4vcfqZw7lR3jeoqIifa3gNfPkk092uP/XX3+tPzP4mvCawM/S4sWLO3wvkJ2fOHGifPLJJ/KNb3xDg95A6Ql+Bm+99VYZNWqUPldJSYkG4tgfCj/L+BpzcnL0NYHAPbR8Be6//349Vjw+zgl+Vzz//PNRa34feuih4M8FPk350Y9+JDU1NW3GBL4GnHO85vAceFP6m9/8psN5sdlsOv5f//qXoe8DUU/rm2kfoiQQ+IOEP1oBCA6QLcQfGZQs4I/s3/72NznjjDPkH//4hwYagWBg4cKFmkE+8sgjpa6uTj7++GP59NNPI05uwvjnnntOA4jp06fLm2++qUHJgUCgiz+kCAqQaf7Pf/6jASOyrfij2h0I7hG4tYfzkZaWFtz2eDwyZ84cDRJQwxqaWcPXhnOHIBhZdgRzOL8IgBBkIuDAH21kZPGHG4Hu1KlT2zwfvg4EeahnRKaxqwJBFt6cdMbIMSGAwkf4f/jDHzQAGjdunN43cB3O+++/r4HPoYceKrH04x//WF+zCODwGr7vvvv0HP/1r38Njnn22Wdl7ty5+r3BpxvIeuJ1gu8TAv3AGysEeJs3b5YLL7xQA1+ci8cee0yvEfy3f6OFNwB4w3fHHXeI3++Pyc9cRUWFHHXUUcE3TPh+I3C/+OKL9efq6quv1nH4/uPNzK5du+Sqq67S40Wg+dZbb4V9LgTweEODsgN8GoDAGj8T+DnBG5P/+7//0+/fl19+Kffee6+sX79eXnrpJb0vvv5vfvObMnnyZM2kIkjduHGjvvEIePzxx/U1gTfKOB6UU+HNxIoVK/TnuzP43YE3znhThCw4ylvwvfnoo4/08fH6C6iurtY6++985zv66dTf//53ueGGG2TSpEn6tYWaMmWKBr84Z3gtE/UqPxH1qkWLFuGvtP+NN97w7969219WVub/+9//7h8wYIA/JSVFtwNOOOEE/6RJk/wtLS3BfT6fzz99+nT/6NGjg/sOPvhg/6mnnhrxeW+99VZ93oCVK1fq9hVXXNFm3Hnnnaf7MT5g7ty5/mHDhkV9TGhqauowbs6cOf7S0tI2+2bMmKGXaPC8eI5wl4ULF7Y5RuybP39+h8fAfrPZ7F+9enWb/WeccYbfbrf7N23aFNy3c+dOf2Zmpv8b3/hGh+/ZMccc4/d4PFGPecuWLTp+wYIF+j0uLy/3L1u2zH/ooYfq/n/84x9tji30XBs9phdeeEHv+9Zbb/mNOP/88/35+fmdHutvf/vbqN8HnOP252TWrFn6mgy45ppr/BaLxV9TU6Pb9fX1/pycHP+ll17a5vFwTrKzs9vsD/fa+fOf/6zP884773R43Z177rmGvnacI4x/8skn9fuB8/naa6/5R40a5TeZTP4PP/wwOPbiiy/2Dxw40L9nz542j3HOOefo8QaO8Xe/+50+5ksvvRQc09zc7B87dmyH7wte59j3yCOPtHnMZ599Vl+X//vf/9rsxziMf++993T73nvv1W0ce2e+9a1v+SdMmBDxPAS+Z/ieQ2Vlpb7WZs+e7fd6vcFxDzzwQPB8tf8annnmmeA+p9PpLy4u9p955pkdnuv555/X8StWrIh4TETxwLIHogSBTAuySviYE9kaZDFRzhD4OH3v3r2arUSGpb6+XjOfuCCDhAzahg0bgt0h8FEoskPYZ9R///tfvUa2KFQgs9VdoZnY2tpaPeYZM2ZoRg/b3YFsJ7KC7S+YUNYeslfh4BhQghGASWivv/66ZtHxMXvAwIEDNVOGbByyVqEuvfTSLtVMIhuK7zGygsjcIvOLzCcyZ+F055iMwusmNMMZK8hYhmZkkbXG14GSAMD3CR+h43sVeA3jgvOI72topjT0tYPMJcYhCwv4FKO9rtYvo5QB3w98tI8MJl6PyEpjEhzgvQg+UTnttNP0/6HHi585jA8cB8pm8IkMMrcBKNXAayQcZGuR0Q71wgsvaLZ37NixbZ4rUB4TODf4+QZkUpEtDgdjULKEjK1Rb7zxhta+42c+dDIjvgZka1955ZU241FuEVrDbrfb9ZMm/Gy3F3ithfvEhijeWPZAlCAefPBBOeigg/QPKuoJ33nnnTaTivCxJv4A33zzzXoJp7KyUv8A46PQb33rW/p4qMvDH3bM7MbHpJ1BcII/eO1nY6OW8EDgo1IEfcuXL9ePt0Pha83Ozu7yY6JMwUitKsosOqvFRZeDUKhLxfGF+3oRkCDIKCsr0xKOzh7DSGCIj+ZxnhGcBOoqO9OdY+qK7pQGRIMWbuGCHnxEDoE3ZIGArr3Qj8Txhg8fwf/lL3/R13aocG+cuvr9QLkKgvOGhgZ58cUX9XlCgz6cfwTqKLXAJZzAceHnBz877UsxULsbDn5OESyGwrlBFxAE5JGe6+yzz9YWdShTQvkTasDxBgpvmgPHj/IDBLMIRnEMs2fP1jdMKJvqTOANSvvXG44Tb74CtwfgZ6v914vvN8orOnutGe0tTtSTGPwSJQj8kQp0e0CmD/WP+GOFmjtkWAIZnp/+9KeadQon8IcWNaDIKiIzhMwh/lCibhCtnPAH80B19gcMGb5QOAb8YUYm65577tGsNv6QIsuM4+ksaxUrCCw7a8cVmlXsrq4+BupRuzvBLNZQZxwISGOps0x4IPgJfM+RYQ3XTiy0Awk+5UBt8vXXX6+t4AI/B3gzF+6109XvB2pTA98P/MzhjQaynPjZw2s18BzIbqJGOZxIbygjCXeseD4cE35WwsExBe6LN8fIBCMbi6wzaqrxhgI/7/ge4M0Rfne8/PLLejsy2JjIhoAfbyji8b0OFXit4Y0rUW9j8EuUgPBHBRPWMIv6gQce0OxO4GNvTDgxEkChGwQ+VsUFmS0ExJjM0lnwO2zYMP3ji4A1NPODP6DtIbvTfvY3tM8MYXIbZqmjfCM0I9jZJKDehGwbJsSF+3rRYQNBdCD4SMRj6mpGDW9I0O2iu9n37gp8soBuCJFexwiWli5dqoFa6AIJXSnl6ao777xTM8C33367vlEMdD3Bm7poP3P4+UHnAwR+od8LfGLTlXPz+eef6xvGaN9PfO8xDhcEy5jk9/Of/1x/tgLHitIpZIlxQTkDssP42m688cawbf3wNQBeb6FlNrgvOpIcyBs33B/HjE+jiHoba36JEhRqQpENxmx51DsiWMA+zPTHjPL2QttJtW8FhYwZssLt2yWFCszORseAUHj+cH+kETSFfryJY0LgEC4zFJoJwv3Q/izR4Fjx0TCy5aGtnzDbH7P2kQ2M9yz1rhxToKdtuDcl4UybNk2/L2i3FU/41ALHjGANXTs6ex2He+109nqMFbyuzzzzTG0BVl5erseAbWRNwy3PG/ozh68LNfehbQfxc4uuC0Yh043HCHef5ubmYEcRlIO0F1gkJfAz3v53AD5xQY07zme48w4IbjEOvwNCz/sf//hH/bk9kM4veJ2hPCeeb7SIOsPML1ECw8e9qBHFH2NM5kFdMAIefDSKj2eRnUEghHpaTG5B1gjwRw6BMtoLIQOMNmdoQ4RWTZ3BH09MQsJHo/hDh1ZnyLyFy1yhPRNqCtFaDRPkAq2qkNUJnYiEwA1/TDFh6Ic//KFmoPGHHYF8uADeKAQIaMnWHoJ8fHzdXb/+9a+D/VPRxgwfwePNBgKKcP1L48HoMeH7h2ANE+jw/UPJR6C/cjh4PJQ+oC40XP0tvvcI3trD+UUdeXch8MVrBTXoWPQDryVkWLdt26Yf4aMmFZ92YBw+rcDXiGANNbL4SD9aT+RY/MyhBR6CbGSCcUE2FZPx8DOHny0En3id49wFAlG8vnHc+BlCazFMSkRmPZBhNZKZxznBc+NnHc+Jc4GsM7L82I+ewSiNQk0/yh4QjCJbi1pg/NyiBjfQ3xg/eygrwWOgjRpqiXF8uA+y2eHg+4CsMLLtKC3B5D1kgfHYmATYnYVlAN+/QE9sooQQl54SRBS13dBHH33U4Ta0Gxo5cqReAi210PLqggsu0JZCNpvNP3jwYP83v/lNbY8W8Otf/9p/5JFHakuptLQ0bbd0++23+10uV8S2ZGjN9JOf/ERbYDkcDv9pp52mrdbat9+C119/3T9x4kRtjTRmzBj/c889F/Yx//3vf/snT57sT01N9Q8fPtx/1113acuk0BZLsWp1Ftp+DW248DWEg7E/+tGPwt726aefaiu2jIwMf3p6uv+4447zv//++4a/Z+EYbR8WOLb259rIMcHjjz+uLeTQWsxI2zN8r9HeK9yxdnZBO65Irc7an5NAW7H2x4JtfE1oF4bXBl7j8+bN83/88cfBMdu3b/d/+9vf1tcxxp111lnalqz9OQq87iK1/gp3TGgPF87MmTP9WVlZwfZsFRUV+nopKSnRnzn87KHt4GOPPdbmfps3b9YWg/iZQ6vC6667TtvY4bk++OCD4Di8zjtrQ4afUfyM4Ha0OszNzfVPmTJF2+TV1tbqmKVLl2ors0GDBunPH67R5m39+vXBx3n00Ue1FR5+lvE4OL/XX3998DHCtToLbW2G3xn4WouKivyXX365v7q6us2Yzr6GcG0QX331VX2eDRs2hP2aieLNhH96OwAnIqL4Q0sq1P5i0QbUjlLsIYOMld7wyQyy18kInxYg892+LIqotzD4JSJKYuiDjNKW0KWvqXtQl9u+NzFW0EPpAlZoS0Yot0CZ1sqVKw+oXIYolhj8EhERxQAmjaKrCeqvUXeNunQsNoPa30hLChNRfHHCGxERUQyg4wN6aiPYRbYXk+OwcAZajRFR4mDml4iIiIiSBvv8EhEREVHSYPBLREREREmDNb9RYLnXnTt3alPwri4fSkREREQ9D5176+vrZdCgQbqUdiQMfqNA4FtSUhLL7w8RERER9YCysjJd7TASBr9RBJaBxMnEcptERERElFjq6uo0WdnZ8t2hGPxGESh1QODL4JeIiIgocRkpUeWENyIiIiJKGgx+iYiIiChpMPglIiIioqTB4JeIiIiIkgaDXyIiIiJKGgx+iYiIiChpMPglIiIioqTB4JeIiIiIkgaDXyIiIiJKGlzhjYiIiIhixufzy46aZml0ecRht8rgnDQxm6OvvBYvDH6JiIiIKCY2VtbL4lUVsml3g7R4vJJqtcjIARkyZ2KRjCrMlETQp8oe3nnnHTnttNNk0KBBunbzSy+9FPU+y5Ytk8MOO0xSUlJk1KhR8tRTT8XlWImIiIiSLfBd9N5WWbWzVnLSbVJakKHX2MZ+3J4I+lTw29jYKAcffLA8+OCDhsZv2bJFTj31VDnuuONk5cqVcvXVV8sll1wiixcv7vFjJSIiIkqmUofFqypkb6NLRhdmSGaqTSxmk15jG/tfX12h43pbnyp7OPnkk/Vi1COPPCIjRoyQ3/3ud7o9btw4effdd+Xee++VOXPm9OCREhERESWPHTXNWuowMDtVP50PhW3s31jZoONK8tKlN/WpzG9XLV++XGbNmtVmH4Je7O+M0+mUurq6NhciIiIi6hwmt6HGN90ePq+aZreI0+PVcb2tXwe/5eXlUlRU1GYfthHQNjc3h73PwoULJTs7O3gpKSmJ09ESERER9U0Ou1UntzV1Etw2u7ySYrXouN7Wr4Pf7rjxxhultrY2eCkrK+vtQyIiIiJKaINz0rSrw67aFvH729b1Yhv7RxVm6Lje1vvhdw8qLi6WioqKNvuwnZWVJWlp4U8+ukLgQkRERETGoI8v2pntrG2WDZWttb8odUDGF4FvnsMusycUJUS/336d+Z02bZosXbq0zb4lS5bofiIiIiKKHfTxvfDo4TJxULbUNLll655GvZ40OFv3J0qf3z6V+W1oaJCNGze2aWWGFmZ5eXkydOhQLVnYsWOHPPPMM3r7ZZddJg888ID87Gc/k4suukjefPNN+dvf/iavvPJKL34VRERERP3TqMJMKZ2ZwRXeYuXjjz/Wnr0B1157rV7PnTtXF6/YtWuXbNu2LXg72pwh0L3mmmvk97//vQwZMkSeeOIJtjkjIiIi6iEobejtdmaRmPztq5KpDXSGQNcHTH5DrTARERER9d14rV/X/BIRERERhWLwS0RERERJg8EvERERESUNBr9ERERElDQY/BIRERFR0mDwS0RERERJg8EvERERESUNBr9ERERElDQY/BIRERFR0mDwS0RERERJw9rbB0BERERE3ePz+WVHTbM0ujzisFtlcE6amM0mns4IGPwSERER9UEbK+tl8aoK2bS7QVo8Xkm1WmTkgAyZM7FIRhVm9vbhJSwGv0RERER9MPBd9N5W2dvokoHZqZJuT5Mml0dW7ayVnbXNcuHRwxkAd4I1v0RERER9rNQBGV8EvqMLMyQz1SYWs0mvsY39r6+u0HHUEYNfIiIioj4ENb4odUDG12RqW9+LbezfWNmg46gjBr9EREREfQgmt6HGN90evno1zW4Rp8er46gjBr9EREREfYjDbtXJbajxDafZ5ZUUq0XHUUcMfomIiIj6ELQzQ1eHXbUt4ve3revFNvaPKszQcdQRg18iIiKiPgR9fNHOLM9hlw2VDVLf4haPz6fX2Mb+2ROK2O+3Ewx+iYiIiPoY9PFFO7OJg7KlpsktW/c06vWkwdlscxYFi0GIiIiI+mgAXDozgyu8dRGDXyIiIqI+uiwx7lOSl94Th9hvMfglIiIiivPqbK99WS5f7qiVRrdHHDarliucNKmYq7LFAYNfIiIiojgGvve9sUHWV9SLN2QFti1VjbK2ol6unjWaAXAP44Q3IiIiojiVOjz/wTb5vKxGA18sR4zODLjGNvb/ecU2Lkvcwxj8EhEREcVBWXWTfLBlr5hNJsl32CXFatb/4xrb+P/yzXt1HPUcBr9EREREcbAF7ciaXZKTbhOTqe3kNmxnp9ukttml46jnsOaXiIiIKE5MfhG/tF2Vbb/O9vetDhSJjsEvERERURyUFjg0u1vX5JbULEub7C+WJa5tcktOmk3H9UoHilWtHSiaXB5Jt+/rQDGx/3WgYPBLREREFAdDctPlqNJ8WbKmQqoanJKZZhObxSxur0/qm92C5g9TS/N1XK90oCivF68f2WdcTLJld6OsLe9/HShY80tEREQUj6DLbJLzpg6Vg0tyxGI2S32LR/Y2OvUa29iP2+NZauBDB4oVgQ4UPslMtUqeI0WvsY39uB3j+gtmfomIiIjiBBlUZFL3lxh4Jd1ukcmDc2TOxKK4Z1i3owPF5iqxmETyM1KCpRgpVovYM8xSUdciKzZX6bih+fEvx+gJDH6JiIiI4ggB7hUzMxJictnmPY1aa5yfae+0A0VVg0vHMfglIiIiom5BoFuSF9/a3s74Tajw7SzwZrcHIiIioqTV39qBjShwSE6aXWqa3FKUZQ7bgSI7za7j+guWPRAREREZ7IqweFWFbNrdIC0er6RaLTJyQEav1OrGSgk6UIzIkyVfVUhVo0snugU7ULR4xOf3y7TSPB3XXzD4JSIiIjIQ+C56b6vsbXTJwOxUSbenaT/cVTtrZWdts1x49PA+GQCb0YHiqKFS2eCU9RX1GvAGWMwm7UBxbpw7UPQ0Br9EREREUUodkPFF4Du6MCNYGpCZapOMFKtsqGyQ11dXSGlBRp8MEkcFOlB8ua8Dhdsj6TarTB6SLXO4yAURERFRckGNL0odkPEN1xEB+zdWNui4eE9ii1UN8ih0oDguMTpQ9DRmfomIiIgiQDCIGl+UOoSTZrdoP1yMi2fQ2h9rkOOBwS8RERFRBA67VQNL1Pii1KG9ZpdXF4XAuHgFrbGuQd4Yw0A60TtiMPglIiIiigDBGwJBBJao8W3fDmxXbYtMGpyt4+IRtMa6BnljDAPpvpCNNvf2ARARERElMgSQCN7yHHYNLOtb3OLxoRWYW7exf/aEoqiBZvugFcEqOirgGtvYj6AV42JVgxyNL0bHFBpEI2jOSbdp8I1rbGM/bk8EDH6JiIiIokDWEhnQiYOydUGIrXsa9RoZX6OZ0VgFrftrkK2d1iA7PV5DNcg7YnRMsQyiexrLHoiIiKjfi0UdKgLc0pnd74gQOnEO5RLoqevy+sRuMeviEkYnzsWyBrkxRseUyB0x2mPwS0RERP1aLOtQEeh2N3hz7Atad9Y0ya5ap1Q3ucTj9YnVYpbcdLsMzE4xFLTGsgbZEXJM5bVO2Ytj8vnEajZLXrpdig0eU090xOgpfa7s4cEHH5Thw4dLamqqTJ06VT788MNOxz711FP6ggi94H5ERESUHBKpDhXBaE6aTT7aWi2V9S2SarNIrsOu19jG/tx0W9SgNVY1yMFjSm89poq6Zkm1tQbiuMY29ucYOCZHSDY6nK52xOhJfSr4/etf/yrXXnut3HrrrfLpp5/KwQcfLHPmzJHKyspO75OVlSW7du0KXr7++uu4HjMRERH1jp6oQ8XYsr1Nsra8Tq+7XMMaiEf9uF/gvv592/v3GK1BnjAoS0sJvtheq9eoSe7yUsv+wLG1C5b3bRsp6ghko5F1Rva5zcPvy0aPKswwlI3uab0ffnfBPffcI5deeqlceOGFuv3II4/IK6+8Ik8++aTMnz8/7H2Q7S0uLjb8HE6nUy8BdXV1MThyIiIiirdY16EiSxxYArjR7RGHzarlBSdNKjY84Q2T5I4YnhssMWh0esRiNktRdpoUZ6Xo7V2qi90XQ/tb/+kQeBo6pubWYwqUYjQ4PVr2UJSVqsdUbeCYAtlotEZD9hnnFqUOyPgi8O1KNrqn9Zng1+VyySeffCI33nhjcJ/ZbJZZs2bJ8uXLO71fQ0ODDBs2THw+nxx22GFyxx13yIQJEzodv3DhQlmwYEHMj5+IiIjiK5Z1qAh873tjg6yvqBdvSLZ3S1WjrK2ol6tnjY4aAAeOB6UXQ3LTO0wu8/r92kXC6PEEevMOzk3Tzg8oOVi9q0521bUYzv42xvCYAtnoQH01zi1KHfAGAYFvovT57TPB7549e8Tr9UpRUVGb/dheu3Zt2PuMGTNGs8KTJ0+W2tpaufvuu2X69OmyevVqGTJkSNj7ILhGaUVo5rekpCTGXw0RERH1NEeMuiKgtOH5D7bJ52U1GhSmWM1iMov4fSJOj0/3/3nFNvn5qeMjZjbbH09WWttjanZ6DB9PrBa5cIQcE+57oLW6B9oRIx76TPDbHdOmTdNLAALfcePGyaOPPiq/+tWvwt4nJSVFL0RERNS3xaorQll1k3ywZa9mfFt8Xi0T8Pn9YsZEeqtZKw+Wb96r44blO3r8eELLOaCu2d0mW9uVco7B+47pg81VOmkOJQ77O1DYtPxh2sj8LtXqHkhHjHjoM8FvQUGBWCwWqaioaLMf20Zrem02mxx66KGycePGHjpKIiIiShSxqkPdsqdR9jS0iMerlbVit5rFYjJrSUCT26sTwnA7xkUKfmN1PIFShRa3Rb7atVcq65zi9vrEZjFLYVaKDC9wGF7kwmw2ydiBmfLiyh3aLSLfYZfsdJse0+Y9jZpNHlOcmVCZ26Tp9mC322XKlCmydOnS4D7U8WI7NLsbCcomvvzySxk4cGAPHikRERH1p5XZkOVtdvk0I5pms4jVjPapotfYxn7cjnHx6NLgsFvF5fHJ8k17ZF1FvVQ1uqSuxa3X2P5gU5WWY2Bc1K/N55e1u+o1EC/NdwjKmZFJxnVpgUP3ryuvT4iV2ZIu8wuoxZ07d64cfvjhcuSRR8p9990njY2Nwe4PF1xwgQwePFgnrcFtt90mRx11lIwaNUpqamrkt7/9rbY6u+SSS3r5KyEiIqJ4OdA6VIfdosFuILZtzQD7xSQmbZ2G3XgojDPK7/NLs9MrDS63mPytCT2jBmalSnWjS8p1QplZUmwWsZhMmol2ur26Pz/DruOi2bGvhAK1wyjFaD/hDZ0fEmVltqQMfs8++2zZvXu33HLLLVJeXi6HHHKIvPbaa8FJcNu2bdMOEAHV1dXaGg1jc3NzNXP8/vvvy/jx43vxqyAiIiKjPB6ffFpWrVlNfCR/WEmuWK1d/+D6QOpQM9NsWpKwu94pVQ2t7VAR8AZCZ9THItjEuO50jahr9kj5ly2yrrLBUNcIlE2g7hiBd/vwHdvYj9pdjBsaoQyjfUcM1CC3n4SXSCuzJWXwC1deeaVewlm2bFmb7XvvvVcvRERE1Pcs/apCFr27RTOTgWwkJmddeMwIOWFc2+5PPSkzxaYf/1fWO8Xt8wczwKDlDxa/3o5xhrtGWJFZtYnNYhK316/1tka7RqAWt8XllcE5qdLo9Emz2ytuv0+DV0eqTdLtZml0ttbsRgt+HTHqiNGX9J+vhIiIiPpV4LvgP2tkb6NTP9JHkNnk9crK7TW6H+IVAKN8ADW2Xp9PbPvKHAIQonp8fg3Oo5UZBLpGoEsEstiBbg8pVpPYHXapqHMa6hoBfpNIqs0q2Wnm1mPz+/U8Iahu8fg0+DVicIw6UPQlfWbCGxERESVPqcNDb22U3fUtOqks1W7RRRxwjW3sf3jZRh3Xlcf8cEuVvLpql1535b5aZtDk0m4KqTazOFKsWt+La2xjf22jS8dFgm4QNc0uyUm3aWCJiWUI7nGNbXRZqG126bhIRhQ4JCfNrhP3ADW/OD+4htomt2Sn2XVcNOZ9HShQ1oEOFMhAo+UZrrGdSCuzxQozv0RERJRQPt62VwMvBLoI6gLJSKvJJBa7Vbw+t6yvaNBxR5UWGMoiP/XeVtla1RhsCTY83yHzjh5uKHusZQZun9b17q13SpMLwWpryQNKBvIz7dLs8RkqM8DkNgTA1Q0ubZMWeJx0m0VyM+yGzk9JbrocNSJPlnxVobXQmJiGrwlfGyasoevEtNI8HWfEqD6yMlusMPglIiKihLKhokE/ys9K3R/4BmjAabNokIdx0YJfBL4LX10b7GEb6Ku7vrJe94ORANjl80lDk19cmjBGGUbrlDeXzy81TViZLXpmFK3DkEDdvrdZvKG1E2gv5kRf3mYZjJZjUTK2yMKed9RQqWxwyrryOl3pDZljlCyg+8PBJTly7tShXcrWjuoDK7PFCsseiIiIKKEguEWQizrWcJDZDATBkaC0ARlfBL5Dc9N0QhdWLMM1trH/6fe3Ri2BGJafru3NGlAS4G3t5+v1tR4Htlv3+3VcJMWZqdLg8rYNfENgP27HOCPB6rcPHSyFmSk64a2uxaPXRZmpur872Vrzvo4YY4uz9Lo/Br7A4JeIiIgSyhHDc3XyFTK07RdXwHaTy6sf9WNcJGiRhlKHwOQy9MBFVwNcYxv7UV+LcZGY9j0vDgUXBN7aZszUuo0L2pZFCxU/2VatAXckuB3jjLRMe/GzHVJZ75J0q0XPB64r6p26H7dTeAx+iYiIKKEMzXPIsaMLNEBFRhOrlSH4xDW20S3hmFEFOi4S1MOiDhZR6Y7qJtla1SRfV7VeYxv7cTvGRYIAGR0dkAjFRYNdf2swHNiH26NNVPvw670SbZ6d29c6LmrLtBWtLdOwem16Kro+2PUa29iP2/vTqmyxxJpfIiIiSij4uP2K40ZpULpqR520uL3SvK+mFaUOEwdn6e3RPpZHZhdQY+v0tE4uC2h2i9Q7sbiDJTiuM1UNLi1xQP9cpwelDljfbd+CEhbU2Zo0+MW4SGoaWxfIiCbauO1omba5Sluv+f0mqa1z6vHhTUGazaz/X7G5SsdFm4CXjBj8EhERUcJBzerN3xwvr365Sz7aWq3L7KIU4sjheXLSpGJDNa2HDM7RgBD3DYTJge4K4Pa2PibGRYJuDngcBOG4tlpMwQlmeCh0grDv6/oQidHVj6ONQ1eJPfVO8fhbF9zAJDccFxK9jS6UdIjsbnAa6j6RjBj8EhERUUIuS4wA90fHdb8Dwa76Fs2CIkBEtQGeHYFhYFtrebGQQ31LxEUl0BYNi0doa7I2pQSt/8djZlpb26dFkhplBTij43DMmNxmMpskw47Jga3nw2ISzfxi0hzOP8ZRRwx+iYiIKKYOtK9uuA4E3bF5T4M0Oj2CphAub2vAG7o8G/bjdoyLFPxi5TQElp3FktiPeBzjIhmQkWLouKONS98X8LYG4u2fs3U/bsc46ojBLxEREcVMrPrqxkJVvUsnybm9rcFpaJiIsBH7ERJjXCRYMQ2lE5HgdoyT/M7HYPEII6KNy0q1SV66XaoanZoBRlYagTcm4aE/MmBlNoyjjtjtgYiIiGIiVn11Q6FjQdneJllbXqfXXelgkJ1u1YlouIdlX3uy4AWZXPTW9WFZ4ci5wE/L9orb6xdUbXTMs4rux+0YF0lFjbEJb9HG4XyOKsqQ/IwUfX68uah3evQa29g/qjBDx1FHzPwSERFRTIT21TWb2+bXsB3aV/fIERFSpPugV+3+CW9uyUixaW/fkycNNDThTeti9wWo6Hhm0aLf1rTvvg5owXGRuDytATTu0x72I5ZHZhnjIj6OL/LzGB2HuudDS3Klusmli2zUNLk164vsryPVqsswHzY0V8dRRwx+iYiIKCYCfXVR6hAO9mMp3mh9dQOB769eXqOtzlrblLXWsa7eWScff12tnSCiBcAWk1k7IeCYWhej8IsfQS9KILRGF3W/KBmI/EF4cXZqp/W+Abgd4yKZNCRHXlpZHvmB9o2LVgc9dmCmvLhyh2acB+akitVi1kC4rtmjlzHFmf12hbYDxbIHIiIiiglkdhFM4uP3cLAft0frq4vShofe2igfb63W9mLo7Yv6VVxjG/txe7QSiAGZKZKV1no/G+piza1tynCNbX3cNJuOi2RUkSN0nlxY/n3jIpkwKFsn2UWC2zEuEnzda3fVy8CsVCkd4BCLuTXAxzW2i7NSZV15PRe56AQzv0RERBQTaGeGrg6Y3OawW9qUPvh8rSupjSnK1HGRbNvbKP/bsEezvdlptuCKavhYPyvVKjXNbnl34x4dN7wgI+LxjC7MlDW76iTTItLk9gcXg0i3mcTpFTnIwPG89dVuQ18/xo0r7jxre/jQvH3H0/nSwzgejIsErd827W6Q0UUZ2qe4vsUjLq9P7BbUV1t18t3GygYd191OGf0ZM79EREQUE+jji3ZmmGi1rbpZJ7h5fD69xjayt3OnD4/a7zewqAW6GOAata3VjW69DuxHwIdxRo4n12HXutyc9NZ6WFxjGx0RjBzPuvI6Q19/tHEoQ0A5Anrx4hnbX7B/TFFW1HIF9Dxu8WB1OquWgiB7XZDRmuXGNspLUCqCcdQRM79EREQUM4E2ZoE+v6jxRakDMr4INI20OUNpA7owINDFJLPQkgO316sT1wIrrhk5np01zfL4O5tlZ02LPi7KHlAacMG0YYaOx9lJGUdXxyETizXhjhlVIGt31Uk1JqrtO55ch03GFmcFx0XK2DrsVkm1WqTJ5Qnb0QHlJSlWi46jjnhWiIiIKKYQUM4YPaDbK7yhTRdKHgId0QIdG/wh3RVsZr+OMzJx7t+f79TlfjE5DPf3ef26jf3TRuZH7xwRZfEKo+MCGdsxxVka6O6qa9ZAFZnagVlp4hO/bN3TGDVjiy4OIwdkyKqdtVr2EFjhDXDedtW2yKTB2ez20AkGv0RERBSzJYmDAYbVbKidWTgDMu2tq7GF8IfZxrhoE8Pu/O9a+WxbjWZYbWaToLEDOj60uH26/85X18pjPzg8YqmB3WYs+I02ztEuYzs4p212t7HFYyhji2OdM7FIdtY2y4bKBhmYnRpcTASBL8o5Zk8oYreHTjD4JSIiIl2Z7cl3N8va8npdJQx1tWOLM+WiY0rjtiJbwGfbarVvrmZpwwS+2q7X1DpuVGFrqUA4W3c3yPubq3ShC4SlLu131nobtrF/+aYqHVda1Hn2F7W1RkQbF8uMLbLVFx49XBavqtDJb1gVDoEz7o/A10gf5GTF4JeIiCjJIfCd/48vNOMb7B7m9MryzXtlfUWD3Hnm5LgGwKjlRW2s2YTuDB1vb12qOHrN75J1FcG2a+Eyx9Dk8uq4H0YIflOsxjK/0cbFOmOLALd0ZobWCKNUwmG3auDM/r6RMfglIiJK8lKHO/67RnY3dFx4AoEn9uN21PB2twSiq0YWOjQT6vXvy/LuC1YD19hv8vt1XCQ1jW5D/XkxLhIE2kYYGRfrjC0CXbYz6xoGv0REREnsw61VsmVPU3Bbw9t9UWag7ha3Y9z0UQMMPy7qbbubkSzOTBWLxSxun08PRe8XXJa4ddIaVjTDuEhslmihr7FxqTZj4ZLRcczY9i4Gv0REREls6VeVwdICjU39rUv1atBpas3+4oJxRoNfdFh47cty+XJHrTS6PeKwWTWzedKkYkOZTfQETrdZxOv1aWcHBLwB+J/NjJ64Fh1XGuHxctMjB8dGxw0yUIPblXHAjG0fDX6dTqekpEReEpCIiIgSF/rwBoTW1+p//eHHRQt873tjg6yvqG8TtG6papS1FfVy9azRhgJgBLdY9GFPg0tc+1qUISC3W0xSkGE31H4sPSXKWsIGx2FVNlR8BFqvhYOAHOMo8XWpeOfVV1+VuXPnSmlpqdhsNklPT5esrCyZMWOG3H777bJz586eO1IiIiKKuYOKMmI2DqUOz3+wTT4va20thnZemMSFa2xj/59XbNNxkZQWOCTVZpbaFo+k2a2Sk26T3LTWa2zrfqtZx0WCWlojoo0rzkmN2n4MnR4wjvpJ8Pviiy/KQQcdJBdddJFYrVa54YYb5J///KcsXrxYnnjiCQ1+33jjDQ2KL7vsMtm929ga2ERERNS7TkR3gShJVIupdVw0ZdVN8sGWvbr6Wm6aTRpa3DqhC9fYxn50kMC4SAZlp0lOur01c+xvbbuGoBfX2Mb+bIddx0VS02wsWx1tXLOBleS6Mo76QNnDb37zG7n33nvl5JNPFrO5Y7z8ve99T6937Ngh999/vzz33HNyzTXXxP5oiYiIKKZsFosUZqRIeb2z0zEDMlJ0XDRb9jRqIIlY+ovtNeIKKROwm7EoRYrUNvt03LD8zrO2u+paJNdhl6KsVKltckl9i1v86NVrNkmKxSxFWSmSm27XcZE6HRhZ/tjIuJoGl9S1RF51DbdjHPWT4Hf58uWGHmzw4MFy5513HugxERERUZwgW3lQcaaW0FbUOdusrIZ0FwLN0UWZhrOaWKUMZQntIRDeUeuU7NTooQc6RCDLi9reXTXN4kRvM+UXrwUtzuySYjVHXQY402D3hWjjPt9ebahlGsZNH228Iwb1ji437LvtttukqanjxxXNzc16GxEREfUdDrtVCjJSZNrIfDl8WI4MzEqRPIdNr48YnqP7cTvGRTMkK00anZEDUtyOcdGOaUd1s3yxvVbc+1ZnC1ywjf3bq5ujHtO2msjlFUbHratoMPQ4RsdRHwt+FyxYIA0NHb+5CIhxGxEREcV/oYoPt1TJq6t26TW2jQosudvs9snU0nw5aeJAOXniQL0+ckS+7h9VmGFoyd1VFTXiiZIixe0YF8mAdLts3dOkXR607HdfZlWXO/aL7v+6qknHRVLXFHnxCqPjjLbGYv/YvqHL3yesuBK6FnXA559/Lnl5ebE6LiIiIjK4NPGid7foamEur0/sFrMGsxceM8LQksShS+5u3N2oS+6iqwKW3MV2V5bcXber3tD3TMcd0vntb6yvkLqWyAFpbbNbx31z8uBOx2yrajR0PNHG2VCwbIDRcdRHgt/c3FwNenFB54fQANjr9Wo2GJ0eiIiIKH6B74L/rJGqRmewLMDp8cln22tk23/W6BgjAXBgyd3AwhRNbo+k26wyeUi2zJlobGEKqG50xmTc1j2NhmpsMS6SuiglGEbHYXKdEUbHUR8Jfu+77z7N+qLdGcobsrOzg7fZ7XYZPny4TJs2raeOk4iIiEKgtOGhtzZqK7HWUNDU5hr7H162UWaMHiBWtAgzAPfGxLZGp1dMYmqz6IURO2ucMRn3wSZjLVMx7srjD+r09uxUY8FotHFjB2YHV7vrDG7HOOpHwS8Wt4ARI0bI9OnTdZELIiIi6h0fb9sr63QVNZ9YzCaxmls/ncXSxB6fX/evLa/XcUeVFhhbla28Xrx4APFrWUH55zv1OYyuylbTbKzGNtq4vY3GHifauNMPGyTvbt4b9XEwLpKTxhVLcVaK7KztPGjHBEGMo8TX5eIULGgRCHxbWlqkrq6uzYWIiIh6HpYPRl0u/pDbLGbNPCLni2vdRhbX5dVxUVdlWxFYlc0nmalWyXOk6DW2sf95A6uywWCDK5xFG+dIMZabizbusMHG5iJFG2e3W+TymaMkI8Wq5xWLflhNrdfYxv7LZo7ScdQPg190dbjyyiulsLBQHA6H1gKHXoiIiKjntbh8WqaAiWjtp6Jp/a/ZpLdjXCTbsSrb5ioN5PIzUnSpX6zEhmtsI5hesblKx0VzztShho492rgTxhcaepxo47bXNUu6LXKog9sxLpofTBsuN5w0Rkpy01rfXJhNel2Sl6b7cTv1024P119/vbz11lvy8MMPyw9+8AN58MEHdWW3Rx99lAtcEBERxcnIQoeWOqDEwWL2a8Aa4PP7xev16+0YF8nmPY1S2+SW/Ey7zu2pb/GIx+cTq9ksGSkWyU63SVWDS8cNjbAqGxxdOkCKM+1SXt/5SmcDM+06LpLSAcYm2EUbh8x1izty8I/bMc4IBLhnTymR19eWS3mtU4qzU2T22GJmfPt78Puf//xHnnnmGZk5c6ZceOGFcuyxx8qoUaNk2LBh8qc//Um+//3v98yREhERURBqcLH8b3lti7g8frFaWkseUJ3gwYpoJpPebqRW128SqWv2yN4Gl7R4vFo3jFg61WqR3AzjHQwwse7270yWq/+6UoPo9lBK8evvTI46AQ+BN0ZECknN+8ZFUt3oivgY4Ns3ziiUNkRqr0b9sOxh7969Ulpaqv/PysrSbTjmmGPknXfeif0REhERUQcluely4rgizcxaLCYNeF0en15bLSbt1Tt7fJGOi2REgUMsJpOuqIZOD5g8Z7ea9Brb2I+sMsYZgdZq9519iBxRkikogUWggesjh2bqfiOt11BPayRoxbhIUM5hhNFxlKTBLwLfLVu26P/Hjh0rf/vb34IZ4ZycnNgfIREREXWAmtPzjhoqR5Xmy5CcNBmQaZe8jBS9xmps2H/u1KFRF6cYmJmqH/ujywOyvQh00TWi9bq1hMLn8+k4o1aW1cj6yiZxe1uDVFyvq2jS/Ua8t6kqJuOqm4xldI2OoyQte0CpA1ZzQ9eH+fPny2mnnSYPPPCAuN1uueeee3rmKImIiKgDlDSgDdmBLE6xckeNlko4Uizi9qBF2v6uDgiAHXazoIoC47DccTS/e32dPLxsk9YiS0j34VqnV/fDdbPHRHyMHTXRJ6AZGTeyMEOWrt0T9XEwjpJHl4Pfa665Jvj/WbNmydq1a+WTTz7Rut/JkyfH+viIiIgoAgS4VxyXoYFgo8sjDrtVM79GliOGqn31riiPQG9fLHCBbC8CX0x4y0qzyd5GV3BcJC0tHnnqvS3BwBdCG6Rh/9PvbZEffWOkpKZ2HoIgk21EtHFHjyiQx97ZGvVxMI6SxwEvQo2Jbt/5znfiFviiuwRWk0tNTZWpU6fKhx9+GHH8Cy+8oOUZGD9p0iT573//G5fjJCIiiga9c8v2Nsna8jq9NtJLNxwEuiV56TK2OEuvjQa+kO+wa8suQNA8PD9dhuWn6/WgfcElbse4aP78yTapd3ojjqlzenVcJMeMNBaMRhu3qwGr30VndBwlaeYXli5dqpfKykqtAwr15JNPSk/561//Ktdee6088sgjGvhiyeU5c+bIunXrtO9we++//76ce+65snDhQvnmN78pzz//vJxxxhny6aefysSJE3vsOImIiKLBqmqLV1XIpt0N2mEBnRVGDsiQOROLDJUrhELQ3N3M72EluTI83yHrK+vFYbdIim3/Qg34G4+M75iiTB0XzbryyAtqGB2Xl5kieek22dvU+QpuuB3jItld5wz2QA73tsIUMo6SR5eD3wULFshtt90mhx9+uAwcOFCL4uMFNcWXXnqp1h0DguBXXnlFA27UH7f3+9//Xk466STtTQy/+tWvZMmSJVqjjPt2SWOjiCXMyi3Yl5radlxn0JIlLa17Y5uaRHvPhIPvQXp698Y2N+O3W+fH4XB0b2xLi4jXG5uxON7A68zpxIL2sRmL8xtok+NyibjdsRmL10PgtdKVsRiH8Z1JSUEfoa6PxTnAueiM3S4SWK68K2PxPcP3rjMYh/FdHYvXGF5rsRiLc4BzAfiZwM9GLMZ25eeevyP24++IVqmpsrGqSRa9t1VqaxtlsMMi6RlWaXK5Zf3mctldUSU/OGqYjEQAbOB3xKbKelmyukI+390s9T4Rh80qBxely5yD8lofI8rvCKv45KJDB8jvXq+Wyoq9kpdulzS7RVeH29vkklxHusydPry1PVmU3xFW3/7fd2afV1I84X//pbiaW7+WTn5HZHldclRxqny0uUkaXF7xWCzitrT+7jH5fVJg8soRxZk6rsPPX8jviKIMu2R49j2uX7R2GX8d8VcCi3p4LRZxWW3aEo6/I9L7dhwR6fdwe/4uKi4u9j/zzDP+eHM6nX6LxeJ/8cUX2+y/4IIL/KeffnrY+5SUlPjvvffeNvtuueUW/+TJkzt9npaWFn9tbW3wUlZWpouc17a+DDpeTjml7QOkp4cfh8uMGW3HFhR0Pvbww9uOHTas87Hjx7cdi+3OxuJxQuF5OhuL4wuF4+9sLL7uUDgvnY1t/7L77ncjj21o2D927tzIYysr94+94orIY7ds2T/2pz+NPHbVqv1jb7018tgPP9w/9je/iTz2rbf2j33ggchjX355/9hFiyKP/dvf9o/F/yONxWMF4DkijcUxBuDYI43F1x6AcxJpLM5pAM51pLH4XgXgexhpLF4DAXhtRBqL11YAXnORxuI1GyrSWP6O4O+Idq8J7wcr/A8s3eC/7NmP/W9fcn3MfkfceNEd/uPvfksvvznnhpj9jlh9+32Gf0csv+ZW/7AbXtbL2efeEbPfEfcefa4+5vAbXvbPvuhBw78jyj6O/PvkmUNP9R+6YLF/S2U9f0f08TgCcZrGa7W1bW8Lo8s1vy6XS6ZPny7xtmfPHvF6vVJU1LY/ILbLy8vD3gf7uzIeUCKRnZ0dvJSUlMToKyAiIhLZXe/UUoeB2cZbhxmRZrdKnsMumak2jQ5iZfygbMNj68IsbBFrXfnAeVCUHscwpjgz6sp11L+YEAF35Q433HCDZGRkyM033yzxtHPnThk8eLDW8U6bNi24/2c/+5m8/fbbsmLFig73sdvt8vTTT2vdb8BDDz2kpRsVFRVhn8fpdOoloK6uTgPg2p07dVGPDviR5n78SLMVyx5aseyBvyPa4+8ItbbGJX9YtllKCzLE5nWLuV15ltfvk6/3NMllx42UMcMKOy172FbVKFf9ZaU0uTwyIMMuTSaruM0WXbAiVbxSXdMo6Xar/P6cQzoGd2FKo1A+8caaStmypzFYg4yFLU44ZIiMGpzXZmxnfrdsk9z/v7KoZQ8/nDFcrj55UqdlDx9vrZKr/7JSu094fNKh7CHD65LsNJvcd84hcvjw/E5/93hcHrngwWWyemedLv4RGvBoDG2zyrjhBfKXS6fpwiAsjeq7ZQ911dWSPWiQ1NbWho/Xulrzi0lmocXvjz32mLzxxhva4cEWqP/bp6d6/RYUFIjFYukQtGK7uLg47H2wvyvjISUlRS9hT3Loie6MkTHdGRv6Qovl2NC64liODa2HjOVYfG/CfX8OdCx+UQZ+CffWWPwstft5islY/IEL/JGL5Vj8QTb6Gu7KWNRW98RY/MLuibGQCGP5O6LP/I5wOE0aWCJozUy1i8/Wdmx9i1tMGWZJz8luO9ek3c/95u2NUuGzSKYjRba2eKTZ7Raf36UtytJsZkl3OKTS6ZHNzSJDI72WrFbZuLdZFq3cLVUNbslKT5dUs0kn0X221y3bPtwhFx5ta52EF+V3xOgh+WIxlWltrc9skWYs7dYOYszS4cVtz1G73xG7PDVS4bWIG2s2t+M3maXemiotXoyL/Lvl0x21UuYyS0FxrrS4fbrkMvoYY/W6rFSrpNjMUlHnlE/Lqlt7GPN3RN+NI7rw+9LQX7nPPvuszfYhhxyi16tWrWqzvycnvyGLO2XKFO0ygY4NgUAc21deeWXY+yBDjNuvvvrq4D5MeAvNHBMREcUTOjGgq8OqnbWSkWJt87cTH8buqm2RSYOzdVw0Ho9PdrudmqRLsZo18EW3tEaXV5rcXrEa6PiAIBddJ7btbRKX2yNfbG8Wp8enj1eSm6YdJF5fXaGZ6mgdJGaPKRKb1Sxed+fZPbvVrOMiqWpwSoSHULgd4yI+TqNL3F6fFGalaUYcyz9jJTv8H8eB/2P5ZiM9jKn/MBT8vvXWW11+4O3bt8ugQYPEHJghHwPIQM+dO1c7TRx55JHa6qyxsTHY/eGCCy7Q0gjU7cJVV12lK9H97ne/k1NPPVX+8pe/yMcff6yZayIiot6AABLtzHbWNsuGytba30B3BQS+qNudPaEoaqCJPrz4YLrF5dUSgMB4ZFZTrWapaXZLZqpVx0WCFmmflVXLuvI62VPv0uWIA8prnVKQYddAGOPQQzhav1wElpHgdowbkdr5qmruSB+Nd2FcoIcxzi1qoUPbuEGz02O4hzEleZ9fI8aPHy8rV66U0tLSmD3m2WefLbt375ZbbrlFJ60hA/3aa68FJ7Vt27atTbCNiXno7fuLX/xCbrrpJhk9erS89NJL7PFLRES9CiUEFx49PNjnt6KuRVKsFs34IvA10ucXWV6svtbs9urFajEHlxL2eH360T4CPoyLBGUWn5fVyO6GjtlPhJaVDS75YnuNjovm463V4vJEXuTC6fHquBEFnQe/W3Yba1sVbVz7HsahMUJXexhT/9FjwW8X59EZhhKHzsocli1b1mHfWWedpRciIqJYcbm88vracs2MFmenyOyxxWIPU98aCQLc0pndX5YYZQ0Y7/b4pLK+RdwtHi1/QKxrs5ikMDNVb8e4SKobXbInTOAbane9S8dF0+h0GypXwLiIj+OKfMxGx6E38byjh8vCV9fKtupmzfAGsuwIfLNSbft7GFPS6LHgl4iIqD96dvlWeeJ/W2R3fUuwfvS3mevlkmNHyA+mDe/WssTd4bBbtW4VnRk8Pr9OMlMIgH1+aXF79HaMi2RlWXXY1c9C+feNO3r0gIjjquqNrZQWbVyBw9hERCPjThjX+unwU+9tla1VjbK30aWlDsj4IvAN3E7Jg8EvERFRFwLf3y5epx/do41YitUkTo9fyuuadT90JQA+kGWJB2alys6a1slauEeq1bS/7MHnl6omt9YVY1wkmyqNlRgYGbetOsLKiF0Yd/y4Qln0/ladvNcZnCaMMwIB7ozRA7SrA84XMsAodWDGNzkx+CUiIjJY6oCMLwLfvHRMMGv9qDzd3hp47m1yyx/f3SJnTykxVAKxsbJeXltVLl/uqNW2ZwimUfN70sRiQzW/22uadIIcol3U91rMZi15aF3+yqcBcHlNi44bHqG+NifD2GQvI+PMJmPlA9HGTR2eLyPy02XTns6D5NL8dB1nFAJdbWdGSa/Hilx6su0ZERFRvKHGF6UOCFLbdzLCNvZX1rXoOCOB731vbJB/r9wpGysbNIOLa2xjP26P5qOt1dLiRheD1vIHn9+vCzng2m61SEaqVSfCYVwks8YUti74EIFp37hoZoyJXBZhdBwC1ZtOHa+dJtonwrGN/TeeOp6ZW0qs4LenJrwRERH1BkxuQ40vSh3CwX7cjnHRSh2eX7FNOyx4fT4NXvMcKXqNbezH7RgXCQJf/Km1W8za1QGTt7LSrHqtAbHFrLdjXCT4+N+O/mgR4HYjHRFOmTBQctMjL8CDrDnGGSlVuOvMyTJtRJ7kp9skM8Wi19NL83Q/a3UpbmUPixYt0pZj6VFW/1izZo32+SUiIuoP0NUBk9tQ44tSh/awH7djXCTbq5vkg81V2o83PyMl+EkpWp3ZM7DiWIus2Fyl4zosSxxidFGGZnyR3c20mFuX592Xww0Evbgd4yJZubNm3zF0Hmzjdow7qrQg4mOh3OP8o4bJQ29t3D8BLwQO8ftHDTPcGYO1upQQmd/58+fr8sAXX3yxvP/++52OKykp0eWIiYiI+gO0MxuQmar1uegRGwrb2F+YlarjItm8p1Fqm7CMsK1DiSC2s9NtukAFxkVy+NA8GV2YobW9eG5cI+gN3T6oKEPHRbK+ol5XdIsEt2NcNMhWY+nmMQMzJdNuDgYZuM6ym3V/ms0SNasdrlb35IkD9ZqT1Cjuwe+OHTvk6aeflj179sjMmTNl7Nixctddd+miE0RERP0VspVoZ4YMLSa3Nbm8WqaAa2wj6Lv4mBGGspp+E3K0nZUaGJszgyDwiuNGaUDu9vp1EYqaJpdeYxt9fi+fOSpqsNjQ7DbU6gzjokHnCizacdSIfG0jNmdCkRwzOl+vL5g+XPejthnjiPpM8Gu1WuXb3/62/Otf/5KysjK59NJL5U9/+pMMHTpUTj/9dN3f/h0xERFRf4A2ZtfPGSPFWWnidHulusmt1wOz0+Snc8YYanM2osAhOWl2qWlyd5gfg21khbPT7DrOSFnAtw4ZJBYTsr0+aXIjGPfp9umHDDJUF4sssxFGxqFlG/oOY/IfPv09qDhLpgzN02tsY4EJdMvAOKI+2eoMywofc8wxsn79er18+eWXMnfuXMnNzdXaYGSGiYiI+hMEuGhn1t0V3kpy0+WoEXmy5KsKqWpwSYrVLOj85fe1lhegW8O00jwdF83Sryrkzx9uk3pn26QTtrH/kJKcqAFwc7Ql2bowzmG3agYcZReYhNfhMVxezZxjHFGf6vZQUVEhd999t0yYMEED3Lq6Onn55Zdly5YtWhbxve99T4NgIiKiRIJa07K9TbK2vE6vu1J7GgqB7jcnD5ZLji3V664sbYxFLM47aqiUDnBoNhULPmzd06jX2Mb+c6cOjbrYhcfjkzteWaNLE7f/KrCN/bgd4yLBwhpGGBmHMSMHZGj/4XBZbewfVZhh+DmJekKX33qddtppsnjxYjnooIO05OGCCy6QvLz9xfQOh0Ouu+46+e1vfxvrYyUiIuo29M5dvKpCa1Lx0TwylAjU5kwsMrSoRKwhM5rnsInTY9GVzBDrIgscLmMazoqtVbKlKvJKabgd444e1Xlf3dkTiuS+pRukJUJmN81m1nHRIGDH+cTKchsqG2RgdqqWOiDji8A3z2HXxzG6ih1RQgS/hYWF8vbbb8u0adM6HTNgwADNAhMRESVK4Lvova2yt9GlAVm6PU0/ml+1s1YDtQuPHh63ABjZZgThXp9fTppQLA1Or7i8Pu3Lm5FikY27G+X11RVSWpARMUhc+lVlxOV/9bn8reMiBb/D8zPkmFH58ta63RJuyg7W8zh6VL6OMwLnEecz8EYDrdtQ6oDV6xD49sYbDaIDCn7/+Mc/Rh2DVi3Dhg3r6kMTERH1WLCJwBetwQLtxZBhzUixaobSSLAZK4GOCAjCsTJcVlrbCkTsD3REKMnrvO63qiHyYhpGx+Frnn/yOJ2At3pnnbg8Pi2bwJlAn+AJg7L09q6cGwS4pTMz9GvA5DaH3aqlDsz4UiJgxTkREfVrocFmuL66RoPNWNnfESF83SvKBJAtjdYRId1ubNqOkXEIVu88c7L894ud8u7GKqlvwYQ1qxw7qkBOnjywW9laBLrxOJ9EXcXgl4iI+rVYBZux4ohRR4TCzMgryXV1HALcK48/SL59GLO11L8x+CUion7NkWDttwIdEVBvjLKL0Gx0oCMC6mOjdUTAMRthdBwwW0vJoFutzoiIiPqKRGu/FeiIgM4HqDfGimwen0+vsW20I0K7Co4DHkeULA4o+D311FNl165dsTsaIiKiBA02YynQEWH8wEytN16+qUqvJwzMMtx5wmWwR7HRcbHsg0yUyA7oM5533nlHmpu5PjcRESW2WLffQlB4oJ0MvkYP3s179XgCrc7wuOMGZRk6nkHZadobOFJ8itsxri/2QSbqKaz5JSKipBCr9luxCBKxLPHCV9dKfbNbstKsYrWYxeP1aSYa+yHassRTSnLFZjaJ09t59GuzmHRcX+qDTJTQwS96+dpsxlaiISIi6o5YZFljNaErFkEilht+6r2tUt3oEqyKXFHrFK/fLxaTSRwpZt3/9PtbZcboAWK1dl6daLKYxGY1i9Pr7XSMzWLWcX2pDzJRQge/q1atit2REBERhQk2X1tVLl/uqNUgM91u1VKFkyYWxz0TGasg8dOyatlQWS8tbo/UNPvE75PgohKNbpFUi1nWV9TruCNH5Hf6OFurGvWYEB979z1GAB4LMS9ux7gRBRl9pg8yUU9j2QMRESVs4HvfGxtkfXm9ZkYDIeKW3Y2ytrxerp41Oq4BcKyCxN0NTqlpconL4xe/qTVI1WjVL4IKhma3T7x+l46LpKrepWfEkWIVr8/X+nh+vx5LitWkq8dhtTaM60t9kIl6GludERFRwkHG8vkV2+TzshoN7LDaWJ4jRa+xjf24PZ7dCPYHidZOg0Snxxs1SERtrxOB6r7sLLLEZhOCVZNuYz8CWYyLJD/DLlZkmP1+yUyxSW66TXIddr3OSLHpTDjcjnGROEL6IIcT7z7IRD2NwS8RESWc7dVN8sHmKg0G8zNSNPhCgIhrbCPmW7G5SsfFiyNGQWKzu7VGN1DqEGpfAlgvgXGdKR2QIYVZqdrtQceaTGI1m/Ua27g3bse4vtQHmainMfglIqKEs3lPo9Q2uSUr3Ra2xCA73SY1zW4dFy+xChLdntaMLP4Ao8zB528tV8A1trEft2NcJCW56TopzpFq0zcGTrdPml0evUYWOSPVJjMPGqDj+lofZKKECn5vvfVW+frrr3vmaIiIiPZBPaypQ240IP6BWGiQuL6iQXbWNGstLK6xbTRIHF2UoSUSdisytSbN3KLCAdfYxn7cjnHRjue8o4bK4cNyNRuOlmkIeHGd70jR/edOHWooaA30QZ44KFtqmtyydU+jXmNyIducUX/T5QKef/3rX3L77bfLjBkz5OKLL5YzzzxTUlJSeuboiIgoKY0ocEhOml0DsKIsc5vsL7KkyApnp9l1XDzbpiFIPH5sobYqW72zVtxen7YTG57vkLMOH2JoAt7hQ/O0W8SaXXWSholpJpQq+DXa9/l94vL65aCiDB1n5Hgw8e+1L/d1xHB7JN1mlclDsmVOFztixKoPMlGiM/nbf3ZjwGeffSaLFi2SP//5z+LxeOScc86Riy66SI444gjpb+rq6iQ7O1tqa2slKyurtw+HiCgpIEj99ctrZMlXFWK3mnWiG4JMBJv1LR7tYjB7fJH8/NTxhoOzWCxOEejzu6feqVnaQH9ej88vBZkphrOkWORiwX/WyN5Gp94fsT3+GuPxkLW95bTxURe56KleyET9PV7rVvAb4Ha75T//+Y8GwosXL5axY8dqNnjevHl6AP0Bg18iol5udVZRL96Qrg4Ws0kOKmrNeHY1aN2/OIVVJ66hThflCkaCVgSYDy/bJB9sqdKFKqqbW2tjMcksN82mC1JMK82Xy2aMNBR4IgD+4zubZM2u+uDyxhMGZcpFx47sUuBLRNKleO2AJrwhbkYA7HK59P+5ubnywAMPSElJifz1r3/l94KIiLot8JH+6ZMHyagBGTIoJ1Wvv3XwoC4Fvu0Xp8CiFAigcY1t7MfiFNHapiGz+llZteyub5HKBqd2nGjtQiG6XVnXIp9uq9ZxRqBWeHtNszS5veL0+PS6rLpZ9xNRz+lW075PPvkkWPaAet8LLrhAHnzwQRk1apTefv/998tPfvITOfvss2N9vERE1EfE4qN4BLhXHHdgdaihi1MgUYPgEoFmus2i+4wuToHuB9uqmrSjAsJk1COjQwM6LaTZzIKlJMr2Num4aJ5dvlXuem2dPhbauVmQivLjfLXofvjBtOGGv0Yi6sHgd9KkSbJ27VqZPXu2/PGPf5TTTjtNLBZLmzHnnnuuXHXVVV19aCIi6k/LEu+bhNXo9ojDtm9Z4kldX5YYge6BLKsbWJyios4nX2yvkdpmt5ZRIPubnWaTSUOyW5cWjrI4RYPTI3Utbmlxe3UCHmqRLSaz1uk2urytn4b6/DouEpfLKw8v26hlF1ia2GaxBGt+xevV/Y8s2yhnTykRu73t31ci6oXg93vf+55Obhs8eHCnYwoKCsTni7wyDRERJVet7paqRllbEf9liR12q1Q3urS7gsfr1zZiNvTR9fm15OG9jXtk/MCsqItTpKdYxO316yUr1RLMPluxOpvVLHUtCGb9Oi6S174ql8p6THQTsVstwaZtpn3bfrdXKuqdOu70gzv/W0tE3dPlmt+bb745YuBLRERJvizxB4Flif1aV4sJZbjGNvb/Oc7LEhdlpMjOmhbN2GamWLS7QqBLA7axHxPfMC6SJqdXbJbWjG+Lx6cdHpDtxTW2sd9qMem4SNaV1wvyQ+gWEW6FN+3962sdR4kHr12Ut6wtr9PreL6WKY6Z3zvvvFPLGNLSoi9tuGLFCtmzZ4+ceuqpsTg+IiLqQ8qwLPGWvVoHm++wB/vzplhNYnfYpaLOKcs379Vxw/IdcakdXrmjRpweLD1slprmjiUJ6LKAABjjjhyR3+njZKRYJSvVFqz5bXb7xO3369fosLdmcNNTrDouEjwGBncWMunnpqZ94yihxKJdHvWR4HfNmjUydOhQOeuss7TG9/DDD5cBAwbobejzi9vfffddee6552Tnzp3yzDPP9PRxExFRAtqClcGaXTIgI6XTZYmrGpw6zkjwG4tgo6rRpeUOCMixmARqa03iFz/Wj9PJZia9HeMiQfZ6aH66bK9uErfHJ5lprcsKY9Kby+0Vq8WstckYF8mJ4wvl90vX6zLEFixuYQoejRb+oqwCE+gwjhJHx3Z5aVqfvWpnreysbeZKeP0t+EUw+/nnn2sbs/POO097qWGSGzo9NDU16ZhDDz1ULrnkEu3xm5qa2tPHTURECUoXK+s0r+mPe7CRm27TProoUchLR/mFBINNdFnAohlYWQ3jIkHG+dCSXG1LFujz6/J6xWI2S2FWqga/hw3N1XGRDM/PkOkj8+Wtdbulye1rU/qAs2M2i0wbma/jKDG0b5cXeGOHNzrI9G+obNB2eaUFGVxcpD9NeDv44IPl8ccfl0cffVS++OIL+frrr6W5uVkntx1yyCF6TUREya20wKHZ3bomt6RmWcIuS5yTZtNx8Qo2irNSteSh0elpV5/p19pa1Oxmplp0XCR4HmScEXhX1TslN8Om90ew6vOK5GemyOwJRVGPB7efe+QwWVlWq18fMtE4KtwLX2Zeul1v5wptiSO0XV64TzSMtsujPtrtwWw2a7CLCxERUaghuelyVGm+LFlToeUNKA0ILkvcjL64IlNL83VcvIINTEYblp8u6ysapKrRrQFmoLUYLuj+MDQvXcdFg0zz8WML5an3tsrWqkb9uvD1Dc93yFljCw1lohGAr91VL+OKs8Tpdsv26hZxen2SgrKJ3DSx26w62e24MYUMgBNEoF0ePn0IB6+hirqWqO3yqA8vckFERBQOspXnTR2qrbzWl9drSUEgr4nygIMHZert0bKasQw2HHar5KSj44RVg1XU6wYyrTarWffjdowzUorx5tpKcaRY5KjSPP2avD6ffp3YjyA7WgAcCOxHF2XoRLmhtS1tFt1Az2BmEROLw27VenOU3YSr6W52YUKlxdBriHofv0tERNQjyxK/tqp1kYsmF4JYi0wenGN4opojhsHGwKxUnVzW4vZJTqpF6p2m4CIXmSno9OATl8en44yWYhxUlNmhpMNoKUYgsG9xW+SrXXVSWecMZpB3ZKXI8AKHdqdgFjFxoI4bEy1Rb46ym/bfe7TKwyIu0eq9KTEw+CUiojYwmevTsmrtfoB2ZYeV5IoVS5F1dVnimd1fljg02EB2tMHp1UlraEuWkWLpUrCxq65FPD6fON1eqfN4teYBR4EOD87G1iAawSfGRSqhiFUpBs4Fgu3lm/ZIbYtb64YD2fHqZpeU17bIyEJkhfknOlGE1nvjTQ6+1/j0AW/C8FpEL2sj9d6UGPiTRUREQUu/qpAn/7dZ1lc2BIPNgwoz5KJjS+WEcUVxW5Y4EGx8VV4ni9dUtFkpDhlbZF6NBhv1LW5d5AILW6DGt+1jie5HAINx8SjFQIYZK86V17XoRLwU2/6FNxCgY39+hj1qJpriC2/o0GEk0HoP32u8ccKbMLwW2ee37+jSW3m32y1Wq1VWrVol8bZ37175/ve/L1lZWZKTkyMXX3yxNDQ0RLzPzJkz9d146OWyyy6L2zETEfW1wPcXL62Sj76ulpoml3ZHwDW2sR+394p9sSq64YZuG1XX4paqRqdmehE4p9rM2kcX1wg6sX9Pg1PHReIIKcUIx2gpBrKHNc1uPZZwK7xhf3WTW8dRYkGAe/nMkXLNiQfJj08YrdeXzRjJwLc/Z35tNpsuduH1Rl66sScg8N21a5csWbJEg/ALL7xQ/u///k+ef/75iPe79NJL5bbbbgtup6ezBQkRUbhSh9+9vk4q61vELCbtWYukKpKkCA6x/54l62TG6AFdLoHojkB9LbK0cyYUdSh72Li70XCrM2RiUWaA2kxMcEOHX/T5xddpsUiw5jdaxjZWdZ+b9zRKi8srg3NSpdHpk2a3V9x+X+tKcak2SbejLZtXxw01uAoexc+BfKJBfbTs4ec//7ncdNNN8uyzz0peXp7Ew1dffSWvvfaafPTRR7q6HNx///1yyimnyN133y2DBg3q9L4IdouLi+NynEREfdWHX1fJpsoGzarababW1dDwh97Uemlx+2VjRYOOmz6ydYXPnhRaX4sWm1lpbQPurrQ6q27Y394M7cwCLc4C+wIXjItX3affJJJqs0p2mlkDb5Q8IAttt5r1GBH8ElHP6PLbd6zy9s4772jAOWbMGDnssMPaXHrC8uXLtdQhEPjCrFmz9BfiihUrIt73T3/6ky7AMXHiRLnxxhuDK9J1xul06gp2oRciov7u463VuqyuzbI/8A3ANvbjdoyLh/31teFzNAg6jXZEQP2sFS3JtN4XNb4imGMWuo3bMc5o3efEQdlS0+SWrVjOucmtGV+jK86NKHBITppd7weo+cXXiWvAQiDZaXYdR0QJkPk944wzJN7Ky8ulsLDtGueoPUbmGbd1BksxDxs2TAN1rEp3ww03yLp16+Sf//xnp/dZuHChLFiwIKbHT0TUJ0RLWMZxIrsjhq3OEERazabgSmqWkEUuEPhiJ243GmwiwC09gE4WJVgIZESeLPmqQjtqoM9wcCEQXWrZL9NK83QcESVA8HvrrbfG7Mnnz58vd911V9SSh+5CTXDApEmTZODAgXLCCSfIpk2bZOTIkWHvg+zwtddeG9xG5rekpKTbx0BE1BccMTxPbObW7C5KekOTvwgSA1lhjOuLfVURmIbGpmgvhodEICz7JpnFs5PFeUcNlcoGp6yvCCwEsv84Di7JkXMNLARCRHFudfbJJ58EA9MJEybIoYce2uXHuO6662TevHkRx5SWlmrNbmVlZZv9Ho9HO0B0pZ536tSper1x48ZOg9+UlBS9EBElkyOG5WlvWSyr2+L26sSwQPstrIgGCEYxLh5iWV+7tapJA/uMVKs4UV/r9YvfhGlvmPBm0nZjVotJxw0vyIjvQiBf7lsIxO2RdJtVJg/JljkTi9k9gCiRgl8Eoeecc44sW7ZM63ChpqZGjjvuOPnLX/4iAwYYnwiBsUbGT5s2TZ8DAfeUKVN035tvvik+ny8Y0BqxcuVKvUYGmIiI9kMHh+tmj9GWZmj7pcsA71sD2GQ2yYCMFL09Hp0eeqKvKo47PcUqVfVO8aLiV782v9hMZl3a2IPi3zjThUCO6375BBHFKfj98Y9/LPX19bJ69WoZN26c7luzZo3MnTtXfvKTn8if//xniTU8z0knnaRtyx555BFtdXbllVdqEB7o9LBjxw4taXjmmWfkyCOP1NIGtEFDR4j8/Hyt+b3mmmvkG9/4hkyePDnmx0hE1NcFFrFY9O4WWV9Zr10I0H1gTFGmzDt6RJcXuYiFA62vBdTyptksUlnXImazSHa6XcuXEf+6PV6panBKUVZqr0wwY9ssoj4Q/KLl2BtvvBEMfGH8+PHy4IMPyuzZs6WnoGsDAl4EuOjycOaZZ8of/vCH4O0IiDGZLdDNwW6363Hed9990tjYqHW7uM8vfvGLHjtGIqK+DgEuevke6PLGiRQgDs5Ok5w0m+ysadbMMepqUeuLyW4ek1l71+em23QcEfV/XQ5+UWqAxS7awz7c1lPQ2SHSghbDhw/XSRABCHbffvvtHjseIqJEXKgiFkEr7nPkiHxJFFjw4kAyv7vqWiTXYdfsbl2zWzPaAXiYouxULX3AOC5eQNT/dTn4Pf744+Wqq67S8obQkgOUFCArS0RE8Yelh596b6tsrWrUel20zhqe75B5Rw/vlXKFWNlYWR+s+UXfX7Q/w8Q7TIYzWvOLoBnlG9NHFsjm3Q1SWe8UNxI5ZrMUZaXI8AKHBsVGegYTURIGv1jk4vTTT9dMa6AFWFlZmS4i8dxzz/XEMRIRUZTAd+Gra6W+xa0Z30BXBNTtYj/0xQAYge+i97bK3kaXdntIt6dp31+0P0MXCKOLSjj29QxOtSGjnaetxQJLJaPHboPTI063z1DPYCLq+7r8k46A99NPP9V62rVrW3+pov4XK64REVH8Sx2Q8UXgOzQX5QCtZQ6ZqWZx2C2yrbpZnn5/q9bx9mbdbndKHZDxReA7ujAj2OcXC16g7y/an72+ukJKCzKilkCE9gzGY2Wl2Q6oZzARJVHwi0llaWlp2jLsxBNP1AsREfUe1Pii1AEZ30DgG4Bt7N+yp1HHJVIdbzSo8UWpAzK+oQtcALaxf2Nlg46LVqcby57BRNT3dSkNgEltQ4cO1ZmxRETU+zC5DTW+CObCwX7cjnG9kb0t29ska8vr9BrbRqH+FjW+6Z2UIuDrcnq8hut0Az2DJw7Klpomt2zd06jXyPgaLZ8goiQte/j5z38uN910kzz77LPagYGIiHoPMruY3IYsJkod2sN+3I5x8equEIuJanhe3Ac1vihzaF+ni68LbcswLp49g4koSSe8YXlgdHoYNmyYOBxtm4KjHpiIiOID7czQ1QGT21DjG1r6gPaTyPhikQqMi1d3hVhMVAvU6X6wpUrrmqub3eLx+cRqNktumk3rl6eV5ne5TpeLShBRl4PfM844g2eNiChBIAhEOzN0dcDkttBuDwh8s1JtMnf6cEOT3WIRtMZqohpuGzswU15cuSPYxSI7zaZf1+aqRv26xhRnMmtLRD0b/Ho8Hv1FdtFFF8mQIUO6/mxERBRzgTZmgT6/CDxR6oCMLwJfI23OYhW0hk5UA11UIqRcwehENRzP2l31MjArVQZk2KW6yS21zW7N/JYWOPR6XXm9HDemkAEwEfVc8Gu1WuW3v/2tXHDBBV17FiIiSuhliWPVXSEwUa3FbdbgdW+TK1iukJdul+EF6YYmqgWOZ3RRRtiaX/TmNdrtgYjogFd4w7LBWOSCiIgOXCwmmB3ossT7uyukae/b9sEmSikq6lqiBq04fiwf/Om2avF4/ZKRahWbxaodJyrrW6Sq0anBKsYZPR4E36G9ecHo8RARHXDwe/LJJ8v8+fPlyy+/lClTpnSY8IbV34iIyBjU2b62qly+3FGr9bVo7YX2WydNLI5r+y3Hvu4KO2uaZFetU6qRsfX6xGoxS266XQZmpxjqroAyBayWhjKF0EU3cF9buknrkos8Ph1n5HhwTlB60V53uj0QEUGXf2tcccUVen3PPfd0uA3vztkDmIjIeOB73xsbZN2uOnF6feLz+8VsMsnmygZZW14vV88aHbcAGNnmnDSbLPmqQuxWZHttYktFxtavGdvt1U0ye3xR1O4Ku+paJMVm1sdCANya+TVr5rehxSM56XZ9fIyLVK4Quiobyh5CSzG4KhsRHYgur3WJ1jmdXRj4EhEZ/V3ql+dXbJOPt+6VPY0uLTNodHr1GtvYj9u7sjDEAQvEl348Z+B5/fu29++JBGUICG6nDMuTAZmp0qJZYJdeF2alymFDcyTFao5arhBYlQ2rr2GyHTo+oHYY19jmqmxE1F38vIiIqBcgk/r2ukqduIXMKAJClPki1nV6fLr/nXWVsn36cBma37a8rCeg5hgrnh0xPFfKa506Ua3R6RGL2SxF2WlSnJWit0ebYObYV66QajPrY4WbqIayCIwzuipboO8wanxR6oCyECxHzFXZiKhHg99TTjlF/vznP0t2drZu33nnnXLZZZdJTk6ObldVVcmxxx4ra9as6daBEBElk427G2R3vVMznGk2c/BjfYtJdNvrR7mBU8fFI/gNTDBDK7MhuekdglYcD5YEjpaxDS1XQMu00Ilq3SlX4KpsRNRrZQ+LFy8Wp9MZ3L7jjjtk7969bXoAr1u3LuYHSETUH1U1uMTt84vdvD/wDcC2zWzW2zEuHhwhE8wC3RUKMlL0GttGJ5ixXIGI+k3mF+/YI20TEZFx+Rl27X3r8ni1RjY0/sWvV7fHq7djXDzEcoJZLMsVYrHcMhFRKNb8EhH1glEDMqQwM0Uq6luk2d0aAFvQMcfv1z65PhGts8W4eAhkbLGMMSaUYVGLwDLJCHy7OsEsFuUKsVhumYio28EvsgDhPpojIqKuQ13tjDED5L9f7tIVzxDw7ufX7Os3Dhqg4+Il1hPMEOh2d/W1WC23TER0QGUP8+bNk5SUFN1uaWnRCW+BRS5C64GJiCgyBGznTR2qk9rWldeLy+0Vn/jFLCZJsVnkoOJMvT3egV2iTDCL1XLLRETdDn7nzp3bZvv888/vMOaCCy4w+nBEREkPgSYWsti/whuW87XI5ME5vVrTeiAZ21gJXd44HC5vTEQ9HvwuWrSo209CREThIcC9IgEyrYnGweWNiaiHcMIbEVEvS4RMa/t6294Oxrm8MRH1FAa/RESUcK3FYt19gogogMEvERElZGsxLm9MRD2BwS8RESVsa7FE6T5BRP0Hg18iIkro1mKJVhNNREkQ/P773/82/ICnn376gRwPERH1ArYWI6JkYSj4PeOMMww9GLIDXq/3QI+JiIjizMHWYkSUJAwFvz5f6LKbRETU34S2FnPYLdLg9IrL6xO7xSwZKRbtsIBljjGOiKgvY80vEREFW4t9VV4ni9dUiNfnD54Vi9kkBxVlsrUYESVv8NvY2Chvv/22bNu2TVwuV5vbfvKTn8Tq2IiIqDfsi3tN4he/mILbRERJGfx+9tlncsopp0hTU5MGwXl5ebJnzx5JT0+XwsJCBr9ERH241RkyvnMmFHUoe9i4u7FXWp0REcWauat3uOaaa+S0006T6upqSUtLkw8++EC+/vprmTJlitx9990xP0AiIopvqzOz2SxZaTYpyEjRa2yHtjojIkqq4HflypVy3XXX6S9Di8UiTqdTSkpK5De/+Y3cdNNNPXOUREQUp1Zn4T8QxNLCTo9XxxERJVXwa7O1ZgEAZQ6o+4Xs7GwpKyuL/RESEVGPc4S0Ogun2eWVFKtFxxER9WVd/i126KGHykcffSSjR4+WGTNmyC233KI1v88++6xMnDixZ46SiIji1uoMyxmHrvLm9/vZ6oyIkjfze8cdd8jAgQP1/7fffrvk5ubK5ZdfLrt375bHHnusJ46RiIji1Oosz2GX9RUNsrOmWSrqWvQa29g/e0IRJ7sRUZ9n8uMtPXWqrq5OSzpqa2slKyuLZ4qI+rWlX1XIU+9tla1VjeL2+sRmMcvwfIfMO3q4nDCuqLcPj4jogOM1Fm8REZHaWFkvb66tFEeKRY4qzROL2Sxen0/qWzy6f1h+uowqzOTZIqI+rcvB74gRI9rUgrW3efPmAz0mIiLqpT6/extduppb+5rfDZUN7PNLRMkZ/F599dVttt1uty588dprr8n1118fy2MjIqJe6PPbPsGB7dA+vyV56fy+EFHyBL9XXXVV2P0PPvigfPzxx7E4JiIi6rU+v2md9vnFBDj2+SWipOv20JmTTz5Z/vGPf8Tq4YiIOnwsX7a3SdaW1+k1tntbIh5TdznY55eIkkTMJrz9/e9/l7y8vFg9HBFRm4lYqEfFx/LITmIxBvSkRWuu3pqAhWN6bVW5fLmjVheGwMpokwZny0kTi/vkpDD2+SWiZNGtRS7aT4QoLy/XPr8PPfSQ9BT0FH7llVd0eWW73S41NTVR74Nju/XWW+Xxxx/X8UcffbQ8/PDDukAHEfUNCDIXvbdVJ2Kh7hQfyyPYxGIMO2ub5cKjh8c92MQx3ffGBllfXi9e7RaJi0m27G6UteX1cvWs0X0uAA70+cU5xeQ2nGuUOmBlt121LezzS0TJG/yeccYZbbax1PGAAQNk5syZMnbsWOkpLpdLzjrrLJk2bZr88Y9/NHSf3/zmN/KHP/xBnn76ae1ScfPNN8ucOXNkzZo1kpqa2mPHSkSx70AwujAj+MY7M9Wmq5D1RgcCHNPzK7bJ52U1YreYJDPNpr1w0RO3vtmt+3H7L04d3+cWhEDAjjcTgSw7anyxpDEy2ljgoq8F9ERE/WKRi6eeeko7TkTL/OLLGjRokFx33XXy05/+VPeh8XFRUZE+xjnnnGPo+bjIBVHvQR3tvUvWS066TQPe9upb3FLT5JZrTjwobh0ItlU1ymXPfSJNTo8UZrXtjIDfOwgYEZg/fP4UGZrvkL4IAT66OmBym8Nu1ZKIvhbIE1FyqYv1Ihd4QKMSZRW0LVu2aDnGrFmzgvtwUqZOnSrLly/vNPh1Op166c7XTkT9vwPB5j2NUtvklvxMe9iWYNnpNqlqcOm4vhr8ItBlOzMi6q8MBb85OTkRF7YI5fV6JREg8AVkekNhO3BbOAsXLpQFCxb0+PERUXSOkA4E4TK/qEfFx/IYF09+Eyp8O/udyAwpEVGfb3X21ltvyZtvvqmXJ598UgoLC+VnP/uZvPjii3rB/xFU4raumD9/vgbVkS5r166VeLrxxhs1ZR64lJWVxfX5iahjBwJMuGpfoYVt7B9VmKHj4mVEgUNy0uxabhHumJAVzk6z67hkbJlGRJToDKVLZsyYEfz/bbfdJvfcc4+ce+65wX2nn366TJo0SR577DGZO3eu4SdHPe68efMijiktLZXuKC4u1uuKigoZOHBgcD+2DznkkE7vl5KSohci6n2J2IGgJDddjhqRJ0u+qpCqRpdkplr3T3hr8YjP75dppXk6rq+2cSMi6s+6/Fkh6mUfeeSRDvsPP/xwueSSS7r0WOgSgUtPQHcHBMBLly4NBruo312xYoVcfvnlPfKcRNT/OxAg0D7vqKFS2eCU9RX1GvAGWMwmObgkR86dOtRQQJ6IbdyIiPq7Lge/JSUl2jcXbcRCPfHEE3pbT9m2bZvs3btXr1FXjH6/MGrUKMnIyND/o9Uaana//e1va8kEukL8+te/1r6+gVZn6ADRvl0bESU2BIClMzMSpgMBjge9fF/7ct8iF26PpNusMnlItswxuMhFIrZxIyJKBl0Ofu+9914588wz5dVXX9XOCfDhhx/Khg0benR541tuuUX79YYuthGoR0aPYVi3bp3W6QagFrmxsVH+7//+T1ujHXPMMfLaa6+xxy9RH5RoHQgQ4F5xXPcDctwPmWxkfMN1jcD+jZUNOi6Rvm4ioqTs84tJYFgpLTAZbdy4cXLZZZf1aOa3t7DPLxH1BExu+8PSDZrZRblEex6fT7buaZQfnzBaxhYnRgtJIqKk6fPbHoLcO+64o7vHR0TULxzIYhCJ2saNiKi/M/Rb9YsvvpCJEyfqUsb4fySTJ0+O1bERESUsTFZ7bdW+ml+XR9LtVp2Ed5LBmt9AGzdMbkONb/uV4tDNAo8XzzZuRETJwFDwi24JWBgC/X3xf/ySDlctgf2JssgFEVFPBr73vbFB1pfXi1d/F+Jiki27G2Vteb1OhosWACdiGzciomRgNbpUcKAlGf5PRJTMpQ7Pr9gmn5fViN1iksw02/4+v81u3Y/bf3Hq+KiBa6K1cSMiSgaGgt9hw4aF/T8RUbLZXt0kH2yuEotJJD8jJViugKDVnmHWAHbF5iodNzTf0efauBER9XeGljcOhXZjr7zySpt2Yjk5OTJ9+nT5+uuvY318REQJtQTw5j2NuoRxVrotbIuy7HSb1DS7dVxX27ihqwOuGfgSESVQ8IsuD2lpacHV3h544AFd8KKgoECuueaanjhGIkpyqLF9eNkmuXfJem0PhmtsY39v8JtQ4dtZZpYZWyKiRGbtTo9frKoGL730knz3u9/VRSSOPvro4GITRESxkmhLAI8ocEhOml1qmtxSmGkSt9evk94sJpPYLCbNCmen2XUcERH1g8wvlhKuqqrS/7/++uty4okn6v9TU1Olubk59kdIREmr/RLA6IeLBSFwjW3sxxLA8SyBKMlNl6NG5InT45NNexpla1WTlmHgGtvYP600T8cREVE/CH4R7F5yySV6Wb9+vZxyyim6f/Xq1TJ8+PCeOEYiSlJdWQI4XlCPe/ToArFbzRro+va1fcQ1trF/+qgC1u0SEfWX4PfBBx+UadOmye7du+Uf//iH5Ofn6/5PPvlEzj333J44RiJKUuh+0OLx6gIS4aAvrtPj1XHxgizz2l31Miw/XSYNzJKCjBTJSrPp9aRBWbp/XXl9r03IIyKiGNf8orMDJrm1t2DBgq4+FBFRRI4EXAI4kI1G2QVWZqtv8YjL6xO7xSyZqVZpcHqC2Wh0biAioj6e+YX//e9/cv7552t7sx07dui+Z599Vt59991YHx8RJbHAEsBY8az9qpKBJYBHFWbEdQng0Gw0Si8CWV9cY7s3stFERNSDwS9KHebMmaPtzj799FNxOp26v7a2VtugERHFSmAJYCz1iyWA61vc4vH59BrbvbEEsCMkGx1Ob2SjiYioB4PfX//61/LII4/I448/Ljbb/o8h0eoMwTARUSwFlgCeOChb24tt3dOo11gCON5tzhI1G01ERMZ1OTWxbt06+cY3vtFhf3Z2ttTU1HT14YiI+tQSwIFsNHoMI/uMjhModUDGF4Fvb2SjiYioB4Pf4uJi2bhxY4e2Zqj3LS0t7erDERF1aQngRMpGowcxJr9V1LVoqQOy0Qh8452NJiKiHgx+L730UrnqqqvkySef1MkdO3fu1GWOf/rTn8rNN9/c1YcjIuqTEikbTUREPRj8zp8/X3w+n5xwwgnS1NSkJRApKSka/P74xz/u6sMREfVZiZSNJiIiY0z+9jM2DHK5XFr+0NDQIOPHj9dlj7G8MbpA9Cd1dXVaz4xuFllZWb19OERERER0APFat/r8gt1u16D3yCOP1K4P99xzj4wYMaK7D0dERERE1OMMB7/o53vjjTfK4YcfrotbvPTSS7p/0aJFGvTee++9cs011/TksRIRERERxafm95ZbbpFHH31UZs2aJe+//76cddZZcuGFF8oHH3ygWV9sWyyWAzsaIiIiIqJECH5feOEFeeaZZ+T000+XVatWyeTJk8Xj8cjnn3+uXR+IiIiIiPpN2cP27dtlypQp+v+JEydqhweUOTDwJSIiIqJ+F/x6vV6d5BZgtVq1wwMRERERUb8re0BHtHnz5mnGF1paWuSyyy4Th8PRZtw///nP2B8lEREREVE8g9+5c+e22T7//PNj8fxERERERIkX/KKlGRERERFRX9btRS6IiIiIiPoaBr9ERERElDQY/BIRERFR0mDwS0RERERJg8EvERERESUNBr9ERERElDQY/BIRERFR0mDwS0RERERJg8EvERERESUNBr9ERERElDQY/BIRERFR0mDwS0RERERJg8EvERERESUNBr9ERERElDQY/BIRERFR0mDwS0RERERJo88Ev7fffrtMnz5d0tPTJScnx9B95s2bJyaTqc3lpJNO6vFjJSIiIqLEZJU+wuVyyVlnnSXTpk2TP/7xj4bvh2B30aJFwe2UlJQeOkIiIiIiSnR9JvhdsGCBXj/11FNduh+C3eLi4h46KiIiIiLqS/pM2UN3LVu2TAoLC2XMmDFy+eWXS1VVVcTxTqdT6urq2lyIiIiIqH/o18EvSh6eeeYZWbp0qdx1113y9ttvy8knnyxer7fT+yxcuFCys7ODl5KSkrgeMxERERH10+B3/vz5HSaktb+sXbu2249/zjnnyOmnny6TJk2SM844Q15++WX56KOPNBvcmRtvvFFqa2uDl7Kysm4/PxERERElll6t+b3uuuu0I0MkpaWlMXs+PFZBQYFs3LhRTjjhhE5rhDkpjoiIiKh/6tXgd8CAAXqJl+3bt2vN78CBA+P2nERERESUOPpMze+2bdtk5cqVeo2aXfwfl4aGhuCYsWPHyosvvqj/x/7rr79ePvjgA9m6davW/X7rW9+SUaNGyZw5c3rxKyEiIiKi3tJnWp3dcsst8vTTTwe3Dz30UL1+6623ZObMmfr/devWaZ0uWCwW+eKLL/Q+NTU1MmjQIJk9e7b86le/YlkDERERUZIy+f1+f28fRCJDqzN0fUBQnZWV1duHQ0REREQHEK/1mbIHIiIiIqIDxeCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg18iIiIiShoMfomIiIgoaTD4JSIiIqKk0SeC361bt8rFF18sI0aMkLS0NBk5cqTceuut4nK5It6vpaVFfvSjH0l+fr5kZGTImWeeKRUVFXE7biIiIiJKLH0i+F27dq34fD559NFHZfXq1XLvvffKI488IjfddFPE+11zzTXyn//8R1544QV5++23ZefOnfKd73wnbsdNRERERInF5Pf7/dIH/fa3v5WHH35YNm/eHPb22tpaGTBggDz//PPy3e9+NxhEjxs3TpYvXy5HHXWUoeepq6uT7OxsfbysrKyYfg1EREREdOC6Eq/1icxvOPji8vLyOr39k08+EbfbLbNmzQruGzt2rAwdOlSD3844nU49gaEXIiIiIuof+mTwu3HjRrn//vvlhz/8YadjysvLxW63S05OTpv9RUVFeltnFi5cqO8cApeSkpKYHjsRERERJWnwO3/+fDGZTBEvKFUItWPHDjnppJPkrLPOkksvvTTmx3TjjTdqVjlwKSsri/lzEBEREVHvsEovuu6662TevHkRx5SWlgb/jwlrxx13nEyfPl0ee+yxiPcrLi7WbhA1NTVtsr/o9oDbOpOSkqIXIiIiIup/ejX4xYQ0XIxAxheB75QpU2TRokViNkdOWmOczWaTpUuXaoszWLdunWzbtk2mTZsWk+MnIiIior6lT9T8IvCdOXOmTla7++67Zffu3Vq3G1q7izGY0Pbhhx/qNup10Rv42muvlbfeeksnwF144YUa+Brt9EBERERE/UuvZn6NWrJkiU5yw2XIkCFtbgt0akNnB2R2m5qagrehHzAyxMj8oovDnDlz5KGHHor78RMRERFRYuizfX7jJZ59fj0en3xaVi1VjS7Jd9jlsJJcsVr7RHKeiIiIqE/Ea30i85sMln5VIU+9t1W2VjWK2+sTm8Usw/MdMu/o4XLCuKLePjwiIiKifoHBb4IEvgtfXSv1LW7N+KbZLdLs8sr6ynrdDwyAiYiIiA4cP1PvZSh1QMYXge/Q3DTJTLWJ1WzWa2xj/9Pvb9VxRERERHRgGPz2MtT4otQBGd/27duwjf1b9jTqOCIiIiI6MAx+exkmt6HGF6UO4WA/bsc4IiIiIjowDH57GTK7mNyGGt9wsB+3YxwRERERHRgGv70M7czQ1QGZXZ+vbV0vtrF/RIFDxxERERHRgWHw28vQxxftzDDBbVt1s05w8/h8eo3trFSbzJ0+nP1+iYiIiGKArc4SQKCNWaDP795Gl5Y6jCnK1MCXbc6IiIiIYoPBb4JAgDtj9ACu8EZERETUgxj8JlgJxJEj8nv7MIiIiIj6Ldb8EhEREVHSYPBLREREREmDwS8RERERJQ0Gv0RERESUNBj8EhEREVHSYPBLREREREmDwS8RERERJQ0Gv0RERESUNBj8EhEREVHSYPBLREREREmDyxtH4ff79bquri4e3w8iIiIi6qJAnBaI2yJh8BtFfX29XpeUlHT1+0BEREREcY7bsrOzI44x+Y2EyEnM5/PJzp07JTMzU0wmk/Sld0AI2MvKyiQrK6u3D6df47nmue6P+Lrmue6P+Lruv+ca4SwC30GDBonZHLmql5nfKHAChwwZIn0VXnAMfnmu+xu+rnmu+yO+rnmu+6OsOMYh0TK+AZzwRkRERERJg8EvERERESUNBr/9VEpKitx66616TTzX/QVf1zzX/RFf1zzX/VFKAschnPBGREREREmDmV8iIiIiShoMfomIiIgoaTD4JSIiIqKkweCXiIiIiJIGg98+aOHChXLEEUfoqnOFhYVyxhlnyLp166Le74UXXpCxY8dKamqqTJo0Sf773//G5XiT7Vw/9dRTuhpg6AXnnCJ7+OGHZfLkycGG6NOmTZNXX3014n34mo7PueZrOnbuvPNO/Z1w9dVXRxzH13Z8zjVf293zy1/+ssPfOcQXfeU1zeC3D3r77bflRz/6kXzwwQeyZMkScbvdMnv2bGlsbOz0Pu+//76ce+65cvHFF8tnn32mQRwuq1atiuuxJ8O5BgQUu3btCl6+/vrruB1zX4WVFPHH6pNPPpGPP/5Yjj/+ePnWt74lq1evDjuer+n4nWvga/rAffTRR/Loo4/qG49I+NqO37kGvra7Z8KECW3+zr377rt95zXtpz6vsrLSj2/l22+/3emY733ve/5TTz21zb6pU6f6f/jDH8bhCJPrXC9atMifnZ0d1+Pqr3Jzc/1PPPFE2Nv4mo7fueZr+sDV19f7R48e7V+yZIl/xowZ/quuuqrTsXxtx+9c87XdPbfeeqv/4IMPNjw+0V7TzPz2A7W1tXqdl5fX6Zjly5fLrFmz2uybM2eO7qfYnmtoaGiQYcOGSUlJSdSMGnXk9XrlL3/5i2bY8ZF8OHxNx+9cA1/TBwafIJ166qkdfg+Hw9d2/M418LXdPRs2bJBBgwZJaWmpfP/735dt27b1mde0tVeelWLG5/NpPdPRRx8tEydO7HRceXm5FBUVtdmHbeyn2J7rMWPGyJNPPqkftyFYvvvuu2X69OkaAOPjZurcl19+qQFYS0uLZGRkyIsvvijjx4/na7qXzzVf0wcGby4+/fRT/SjeCP6+jt+55mu7e6ZOnar10jh/KHlYsGCBHHvssVrGgDkyif6aZvDbD97h4sUWqdaG4nuuEVCEZtAQ+I4bN07rz371q1/x2xEBfpGuXLlS3zT8/e9/l7lz52rddWdBGcXnXPM13X1lZWVy1VVX6ZwBTnxNvHPN13b3nHzyycH/I9GDYBifdv7tb3/Tut5Ex+C3D7vyyivl5ZdflnfeeSdqRrG4uFgqKira7MM29lNsz3V7NptNDj30UNm4cSNPdRR2u11GjRql/58yZYpmb37/+9/rG4f2+JqO37luj69p4zCpsLKyUg477LA2pSb4XfLAAw+I0+kUi8XS5j58bcfvXLfH13b35OTkyEEHHdTp37lEe02z5rcP8vv9GozhY8o333xTRowYYejd7dKlS9vsw7vjSDV+1L1z3R5++eIj5oEDB/KUdqPUBH+wwuFrOn7nuj2+po074YQT9OcfWfbA5fDDD9caSfw/XDDG13b8znV7fG13D+qmN23a1OnfuYR7TffKNDs6IJdffrl2E1i2bJl/165dwUtTU1NwzA9+8AP//Pnzg9vvvfee32q1+u+++27/V199pTM1bTab/8svv+R3I8bnesGCBf7Fixf7N23a5P/kk0/855xzjj81NdW/evVqnusIcA7RRWPLli3+L774QrdNJpP/9ddf52u6l881X9Ox1b4DAX9f99655mu7e6677jr9u4jfIYgvZs2a5S8oKNCOSH3hNc2yhz7aoB5mzpzZZv+iRYtk3rx5+n/MujSbzW3qTp9//nn5xS9+ITfddJOMHj1aXnrppYgTt6h757q6ulouvfRSLeTPzc3Vj5TR45B1q5Hh48oLLrhAJ09kZ2drHdnixYvlxBNP5Gu6l881X9M9i7+v44ev7djYvn279u2tqqqSAQMGyDHHHKP98PH/vhCDmBAB98ozExERERHFGWt+iYiIiChpMPglIiIioqTB4JeIiIiIkgaDXyIiIiJKGgx+iYiIiChpMPglIiIioqTB4JeIiIiIkgaDXyIiIiJKGgx+iYj6kKeeekpycnKkL/jlL38phxxySG8fhqxbt06Ki4ulvr7e0Pg9e/ZIYWGhrmJFRP0Pg18i6hdMJlPECwKxeMFy2IHnTU1NlYMOOkgWLlwoXV1Qc/jw4XLfffe12Xf22WfL+vXrpSf97ne/06W5W1paOtzW1NQkWVlZ8oc//EH6ihtvvFF+/OMfS2ZmpqHxBQUFuvzzrbfe2uPHRkTxx+CXiPqFXbt2BS8IGBGghe776U9/GhyLINTj8fTo8Vx66aX6vMg6Ivi65ZZb5JFHHjngx01LS9OsZE/6wQ9+II2NjfLPf/6zw21///vfxeVyyfnnny99wbZt2+Tll1+WefPmdel+F154ofzpT3+SvXv39tixEVHvYPBLRP0CPtYOXLKzszXrGtheu3atZv1effVVmTJliqSkpMi7776rAdEZZ5zR5nGuvvpqzdwG+Hw+zdqOGDFCA8+DDz5YA8Bo0tPT9bmHDRumgdTkyZNlyZIlwds3bdok3/rWt6SoqEgyMjLkiCOOkDfeeCN4O47h66+/lmuuuSaYRQ5X9hAoLXj22Wc1U4yv/ZxzzmnzET/+//3vf18cDocMHDhQ7r33Xn18fK3hILg+7bTT5Mknn+xwG/bhnOXl5ckNN9ygWW18raWlpXLzzTeL2+3u9JyEe048Vmhg6nQ69Y3K4MGD9XinTp0qy5YtC96Oc4JjQ2Yat0+YMEH++9//dvqcf/vb3/R7hscDBPV4Y9T+e/jSSy/p4wXOGx530KBB8uKLL3b62ETUNzH4JaKkMX/+fLnzzjvlq6++0mDUCAS+zzzzjGZtV69ercEosp5vv/22ofsjy/y///1PA3C73R7c39DQIKeccoosXbpUPvvsMznppJM0qEOmEpB1HTJkiNx2223B7HVnEEgjeEOGExccG77OgGuvvVbee+89+fe//60BOI7n008/jXjcF198sbz55psabAZs3rxZ3nnnHb0N8IYCwfiaNWvk97//vTz++OMaWB+IK6+8UpYvXy5/+ctf5IsvvpCzzjpLz82GDRv09h/96EcaIOM4vvzyS7nrrrv0zUNn8LUefvjhwW0EuHhzsGjRojbjsP3d7363TWnEkUceqfcnov7F2tsHQEQULwgkTzzxRMPjEWTdcccdmpGdNm2a7kOGE1njRx99VGbMmNHpfR966CF54okntEQA2VDU/v7kJz8J3o5sJC4Bv/rVrzTLiAAVASAyqxaLRYMxZJAjQXYaQWggcEPZAoLq22+/XTOZTz/9tDz//PNywgknBAM9ZDUjmTNnjo7B2EC9NJ6jpKQk+Di/+MUvguORdUbGFkHrz372M+kOBP54PlwHjg+P+dprr+l+fC9w25lnnimTJk0Kfj8iQfAeGvzCJZdcItOnT9c3FMiEV1ZWavY4NPMOOAa8MSGi/oWZXyJKGu2DoGg2btyoE7wQMCO7GLggE4xsayQoM1i5cqVmXE8++WT5+c9/rgFXaOYXgd24ceO0jAGPi4x0IPPbFQg8QzOWgYAukK1F8I0sZgBKI8aMGRPxMRF4z507VwNeZK8RYCOIRgmH2dz6p+Ovf/2rHH300Rqc4/gRDHfn+AOQyfV6vVpKEXq+kckOnG+8gfj1r3+tz4sJacgOR9Lc3KxvPELhXKCsAV8PPPfcc1qe8o1vfKPNOJS54PtPRP0LM79ElDTwkXcoBHHtOzCE1qwiQIVXXnklWDMagLrhSBBgjho1Klh3iv8fddRRMmvWLN2HwBclCHfffbfehkALH7sjU9xVNputzTbqgxGsHqiLLrpIyz5Q/oDHKysr0+AXUJqAAH/BggWaJcbXi6wvOkV0xsj5RtD9ySef6HWoQGkDsrZ4PnxPXn/9dT0+PCe6OXTWuaG6urrDfjzOgw8+qKUwyCrj6wrUVQdgstuAAQMMnSsi6juY+SWipIXApn0tLbK1AePHj9cgF9lMBKihF3z8bxQCt6uuukoD3kDwh4wwJnp9+9vf1o/wkT3dunVrm/uhRhiZ0AOBsgAExx999FFwX21traF2aSNHjtTSDkxyQ4CIwB0ZUnj//ff1/8hoI6M+evToNvXBRs43vrZVq1YFtw899FDdh6x1+/MdWvqBc3/ZZZdpXfR1112ntcadwWOiJrk91G3jeNGyDbcjy90ejg33J6L+hcEvESWt448/Xj7++GMtY8CEKnyMHhqMoZQAASsmueEjcnz0joli999/f/Ajc6N++MMfasD5j3/8Q7cRLCJ4Q7D9+eefy3nnndchW4tyBkzs2rFjhy680B34GhDYXX/99fLWW2/ppD1MWEMWtn2mMxyMxXGiHjkw0S1w/HhTgGwvzguCyGidEXC+kbHFBRMAL7/8cqmpqQnejnIHZJPRYxfPuWXLFvnwww81u4v7ALpFLF68WG/D9wJfE0pHOoMsMbLU7d9EoFvEd77zHT0vs2fP1smFoVDugAw0biOi/oXBLxElLQRGaM+FCVpoNYbJYQi8QmEiGsYgAEOQhc4DCMTQ+qwrMIENj43JYwhy77nnHg3AUAeMLg84lsMOO6zDBD1kg5GBPZCP3/FcmLD3zW9+U7O3qJfF19K+FjYcTC5D9hvtzELbwp1++un6pgCT89BqDZlgnKdoZRQIxHEekFFGVvq4445rMwYZZtyOjC7qkvGcyFoPHTpUb0cQi44Pge8FAmZMLuwM6q2tVmuHyWyAYB5lJjiu9v71r3/pcx577LFRzxER9S0mf1eXHCIioj4NvW5Rw4xa2dBsbn+F2l500UDGOBR6IyOA37lzZ5s2dID6bEyuQ0aeiPoXTngjIurn0K4LZQbocoB6X2SUAYtsJAOUnKC8Apl9lIGgpAG1x+iFjNvaB74oMUFJxLnnnttrx0xEPYeZXyKiJAh+0d0ASy0j0MMqdyiFCPTKTTYoPUEPZLQ2Q3lDpEUyiKj/YfBLREREREmDE96IiIiIKGkw+CUiIiKipMHgl4iIiIiSBoNfIiIiIkoaDH6JiIiIKGkw+CUiIiKipMHgl4iIiIiSBoNfIiIiIpJk8f+emuX7jxpABwAAAABJRU5ErkJggg=="
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 394
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Trying Polynomial Regression",
"id": "28a6926de3a1a2e7"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.782476500Z",
"start_time": "2026-04-25T14:53:58.774436300Z"
}
},
"cell_type": "code",
"source": [
"poly_converter = PolynomialFeatures(degree=2)\n",
"X_poly = poly_converter.fit_transform(X)"
],
"id": "b867289f4b8dd0ae",
"outputs": [],
"execution_count": 395
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.787833400Z",
"start_time": "2026-04-25T14:53:58.782476500Z"
}
},
"cell_type": "code",
"source": "X_train_p, X_test_p, y_train_p, y_test_p = train_test_split(X_poly, y, test_size=0.3, random_state=101)",
"id": "cf11946087afa62f",
"outputs": [],
"execution_count": 396
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.819419400Z",
"start_time": "2026-04-25T14:53:58.788835500Z"
}
},
"cell_type": "code",
"source": [
"poly_model = LinearRegression()\n",
"poly_model.fit(X_train_p, y_train_p)\n",
"y_hat_poly = poly_model.predict(X_test_p)"
],
"id": "61b135564e36f71d",
"outputs": [],
"execution_count": 397
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.835519700Z",
"start_time": "2026-04-25T14:53:58.820414Z"
}
},
"cell_type": "code",
"source": [
"print(f\"Mean absolute error = {mean_absolute_error(y_test_p, y_hat_poly)}\")\n",
"print(f\"Root mean squared error = {np.sqrt(mean_squared_error(y_test_p, y_hat_poly))}\")\n"
],
"id": "bfd534c1abda8530",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Mean absolute error = 0.29501714163585174\n",
"Root mean squared error = 0.4157783198958284\n"
]
}
],
"execution_count": 398
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T14:53:58.840547200Z",
"start_time": "2026-04-25T14:53:58.836521600Z"
}
},
"cell_type": "markdown",
"source": [
"### Model Performance Results:\n",
"\n",
"Linear Regression: `MAE = 0.2806 | RMSE = 0.3867`\n",
"\n",
"Polynomial Regression: `MAE = 0.2950 | RMSE = 0.4158`\n",
"\n",
"This shows that the Linear Regression model performed better than the Polynomial Regression model in terms of both MAE and RMSE, indicating that the linear model is a better fit for this dataset. The residual error plot for the linear model also suggests that there are no clear patterns in the residuals, which is a good sign for the model's performance. This means that for this particular case, handling the rating predictions with a linear regression model would be better due to its lower error rate as compared to the polynomial regression model.\n"
],
"id": "eaefa3aed2214793"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Part F",
"id": "3c89e2f8ae31de3b"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T15:14:41.668654900Z",
"start_time": "2026-04-25T15:14:41.650113100Z"
}
},
"cell_type": "code",
"source": "features_to_test = ['Reviews', 'Size in bytes', 'Numeric Installs']",
"id": "ab09192a122e6e8f",
"outputs": [],
"execution_count": 404
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T15:15:26.186132400Z",
"start_time": "2026-04-25T15:15:26.176807100Z"
}
},
"cell_type": "code",
"source": [
"for feature in features_to_test:\n",
" X_single = df_encoded[[feature]]"
],
"id": "3f65e25b63cc8e93",
"outputs": [],
"execution_count": 407
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T15:15:37.813266600Z",
"start_time": "2026-04-25T15:15:37.797080500Z"
}
},
"cell_type": "code",
"source": "X_train_s, X_test_s, y_train_s, y_test_s = train_test_split(X_single, y, test_size=0.3, random_state=101)",
"id": "213bcc196f94054d",
"outputs": [],
"execution_count": 408
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T15:15:59.633576900Z",
"start_time": "2026-04-25T15:15:59.612227200Z"
}
},
"cell_type": "code",
"source": [
"simple_model = LinearRegression()\n",
"simple_model.fit(X_train_s, y_train_s)"
],
"id": "75e6c5289568ef2f",
"outputs": [
{
"data": {
"text/plain": [
"LinearRegression()"
],
"text/html": [
"<style>#sk-container-id-1 {\n",
" /* Definition of color scheme common for light and dark mode */\n",
" --sklearn-color-text: #000;\n",
" --sklearn-color-text-muted: #666;\n",
" --sklearn-color-line: gray;\n",
" /* Definition of color scheme for unfitted estimators */\n",
" --sklearn-color-unfitted-level-0: #fff5e6;\n",
" --sklearn-color-unfitted-level-1: #f6e4d2;\n",
" --sklearn-color-unfitted-level-2: #ffe0b3;\n",
" --sklearn-color-unfitted-level-3: chocolate;\n",
" /* Definition of color scheme for fitted estimators */\n",
" --sklearn-color-fitted-level-0: #f0f8ff;\n",
" --sklearn-color-fitted-level-1: #d4ebff;\n",
" --sklearn-color-fitted-level-2: #b3dbfd;\n",
" --sklearn-color-fitted-level-3: cornflowerblue;\n",
"}\n",
"\n",
"#sk-container-id-1.light {\n",
" /* Specific color for light theme */\n",
" --sklearn-color-text-on-default-background: black;\n",
" --sklearn-color-background: white;\n",
" --sklearn-color-border-box: black;\n",
" --sklearn-color-icon: #696969;\n",
"}\n",
"\n",
"#sk-container-id-1.dark {\n",
" --sklearn-color-text-on-default-background: white;\n",
" --sklearn-color-background: #111;\n",
" --sklearn-color-border-box: white;\n",
" --sklearn-color-icon: #878787;\n",
"}\n",
"\n",
"#sk-container-id-1 {\n",
" color: var(--sklearn-color-text);\n",
"}\n",
"\n",
"#sk-container-id-1 pre {\n",
" padding: 0;\n",
"}\n",
"\n",
"#sk-container-id-1 input.sk-hidden--visually {\n",
" border: 0;\n",
" clip: rect(1px 1px 1px 1px);\n",
" clip: rect(1px, 1px, 1px, 1px);\n",
" height: 1px;\n",
" margin: -1px;\n",
" overflow: hidden;\n",
" padding: 0;\n",
" position: absolute;\n",
" width: 1px;\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-dashed-wrapped {\n",
" border: 1px dashed var(--sklearn-color-line);\n",
" margin: 0 0.4em 0.5em 0.4em;\n",
" box-sizing: border-box;\n",
" padding-bottom: 0.4em;\n",
" background-color: var(--sklearn-color-background);\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-container {\n",
" /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
" but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
" so we also need the `!important` here to be able to override the\n",
" default hidden behavior on the sphinx rendered scikit-learn.org.\n",
" See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
" display: inline-block !important;\n",
" position: relative;\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-text-repr-fallback {\n",
" display: none;\n",
"}\n",
"\n",
"div.sk-parallel-item,\n",
"div.sk-serial,\n",
"div.sk-item {\n",
" /* draw centered vertical line to link estimators */\n",
" background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
" background-size: 2px 100%;\n",
" background-repeat: no-repeat;\n",
" background-position: center center;\n",
"}\n",
"\n",
"/* Parallel-specific style estimator block */\n",
"\n",
"#sk-container-id-1 div.sk-parallel-item::after {\n",
" content: \"\";\n",
" width: 100%;\n",
" border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
" flex-grow: 1;\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-parallel {\n",
" display: flex;\n",
" align-items: stretch;\n",
" justify-content: center;\n",
" background-color: var(--sklearn-color-background);\n",
" position: relative;\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-parallel-item {\n",
" display: flex;\n",
" flex-direction: column;\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
" align-self: flex-end;\n",
" width: 50%;\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
" align-self: flex-start;\n",
" width: 50%;\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
" width: 0;\n",
"}\n",
"\n",
"/* Serial-specific style estimator block */\n",
"\n",
"#sk-container-id-1 div.sk-serial {\n",
" display: flex;\n",
" flex-direction: column;\n",
" align-items: center;\n",
" background-color: var(--sklearn-color-background);\n",
" padding-right: 1em;\n",
" padding-left: 1em;\n",
"}\n",
"\n",
"\n",
"/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
"clickable and can be expanded/collapsed.\n",
"- Pipeline and ColumnTransformer use this feature and define the default style\n",
"- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
"*/\n",
"\n",
"/* Pipeline and ColumnTransformer style (default) */\n",
"\n",
"#sk-container-id-1 div.sk-toggleable {\n",
" /* Default theme specific background. It is overwritten whether we have a\n",
" specific estimator or a Pipeline/ColumnTransformer */\n",
" background-color: var(--sklearn-color-background);\n",
"}\n",
"\n",
"/* Toggleable label */\n",
"#sk-container-id-1 label.sk-toggleable__label {\n",
" cursor: pointer;\n",
" display: flex;\n",
" width: 100%;\n",
" margin-bottom: 0;\n",
" padding: 0.5em;\n",
" box-sizing: border-box;\n",
" text-align: center;\n",
" align-items: center;\n",
" justify-content: center;\n",
" gap: 0.5em;\n",
"}\n",
"\n",
"#sk-container-id-1 label.sk-toggleable__label .caption {\n",
" font-size: 0.6rem;\n",
" font-weight: lighter;\n",
" color: var(--sklearn-color-text-muted);\n",
"}\n",
"\n",
"#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
" /* Arrow on the left of the label */\n",
" content: \"▸\";\n",
" float: left;\n",
" margin-right: 0.25em;\n",
" color: var(--sklearn-color-icon);\n",
"}\n",
"\n",
"#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
" color: var(--sklearn-color-text);\n",
"}\n",
"\n",
"/* Toggleable content - dropdown */\n",
"\n",
"#sk-container-id-1 div.sk-toggleable__content {\n",
" display: none;\n",
" text-align: left;\n",
" /* unfitted */\n",
" background-color: var(--sklearn-color-unfitted-level-0);\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
" /* fitted */\n",
" background-color: var(--sklearn-color-fitted-level-0);\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-toggleable__content pre {\n",
" margin: 0.2em;\n",
" border-radius: 0.25em;\n",
" color: var(--sklearn-color-text);\n",
" /* unfitted */\n",
" background-color: var(--sklearn-color-unfitted-level-0);\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
" /* unfitted */\n",
" background-color: var(--sklearn-color-fitted-level-0);\n",
"}\n",
"\n",
"#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
" /* Expand drop-down */\n",
" display: block;\n",
" width: 100%;\n",
" overflow: visible;\n",
"}\n",
"\n",
"#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
" content: \"▾\";\n",
"}\n",
"\n",
"/* Pipeline/ColumnTransformer-specific style */\n",
"\n",
"#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
" color: var(--sklearn-color-text);\n",
" background-color: var(--sklearn-color-unfitted-level-2);\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
" background-color: var(--sklearn-color-fitted-level-2);\n",
"}\n",
"\n",
"/* Estimator-specific style */\n",
"\n",
"/* Colorize estimator box */\n",
"#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
" /* unfitted */\n",
" background-color: var(--sklearn-color-unfitted-level-2);\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
" /* fitted */\n",
" background-color: var(--sklearn-color-fitted-level-2);\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
"#sk-container-id-1 div.sk-label label {\n",
" /* The background is the default theme color */\n",
" color: var(--sklearn-color-text-on-default-background);\n",
"}\n",
"\n",
"/* On hover, darken the color of the background */\n",
"#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
" color: var(--sklearn-color-text);\n",
" background-color: var(--sklearn-color-unfitted-level-2);\n",
"}\n",
"\n",
"/* Label box, darken color on hover, fitted */\n",
"#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
" color: var(--sklearn-color-text);\n",
" background-color: var(--sklearn-color-fitted-level-2);\n",
"}\n",
"\n",
"/* Estimator label */\n",
"\n",
"#sk-container-id-1 div.sk-label label {\n",
" font-family: monospace;\n",
" font-weight: bold;\n",
" line-height: 1.2em;\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-label-container {\n",
" text-align: center;\n",
"}\n",
"\n",
"/* Estimator-specific */\n",
"#sk-container-id-1 div.sk-estimator {\n",
" font-family: monospace;\n",
" border: 1px dotted var(--sklearn-color-border-box);\n",
" border-radius: 0.25em;\n",
" box-sizing: border-box;\n",
" margin-bottom: 0.5em;\n",
" /* unfitted */\n",
" background-color: var(--sklearn-color-unfitted-level-0);\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-estimator.fitted {\n",
" /* fitted */\n",
" background-color: var(--sklearn-color-fitted-level-0);\n",
"}\n",
"\n",
"/* on hover */\n",
"#sk-container-id-1 div.sk-estimator:hover {\n",
" /* unfitted */\n",
" background-color: var(--sklearn-color-unfitted-level-2);\n",
"}\n",
"\n",
"#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
" /* fitted */\n",
" background-color: var(--sklearn-color-fitted-level-2);\n",
"}\n",
"\n",
"/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
"\n",
"/* Common style for \"i\" and \"?\" */\n",
"\n",
".sk-estimator-doc-link,\n",
"a:link.sk-estimator-doc-link,\n",
"a:visited.sk-estimator-doc-link {\n",
" float: right;\n",
" font-size: smaller;\n",
" line-height: 1em;\n",
" font-family: monospace;\n",
" background-color: var(--sklearn-color-unfitted-level-0);\n",
" border-radius: 1em;\n",
" height: 1em;\n",
" width: 1em;\n",
" text-decoration: none !important;\n",
" margin-left: 0.5em;\n",
" text-align: center;\n",
" /* unfitted */\n",
" border: var(--sklearn-color-unfitted-level-3) 1pt solid;\n",
" color: var(--sklearn-color-unfitted-level-3);\n",
"}\n",
"\n",
".sk-estimator-doc-link.fitted,\n",
"a:link.sk-estimator-doc-link.fitted,\n",
"a:visited.sk-estimator-doc-link.fitted {\n",
" /* fitted */\n",
" background-color: var(--sklearn-color-fitted-level-0);\n",
" border: var(--sklearn-color-fitted-level-3) 1pt solid;\n",
" color: var(--sklearn-color-fitted-level-3);\n",
"}\n",
"\n",
"/* On hover */\n",
"div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
".sk-estimator-doc-link:hover,\n",
"div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
".sk-estimator-doc-link:hover {\n",
" /* unfitted */\n",
" background-color: var(--sklearn-color-unfitted-level-3);\n",
" border: var(--sklearn-color-fitted-level-0) 1pt solid;\n",
" color: var(--sklearn-color-unfitted-level-0);\n",
" text-decoration: none;\n",
"}\n",
"\n",
"div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
".sk-estimator-doc-link.fitted:hover,\n",
"div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
".sk-estimator-doc-link.fitted:hover {\n",
" /* fitted */\n",
" background-color: var(--sklearn-color-fitted-level-3);\n",
" border: var(--sklearn-color-fitted-level-0) 1pt solid;\n",
" color: var(--sklearn-color-fitted-level-0);\n",
" text-decoration: none;\n",
"}\n",
"\n",
"/* Span, style for the box shown on hovering the info icon */\n",
".sk-estimator-doc-link span {\n",
" display: none;\n",
" z-index: 9999;\n",
" position: relative;\n",
" font-weight: normal;\n",
" right: .2ex;\n",
" padding: .5ex;\n",
" margin: .5ex;\n",
" width: min-content;\n",
" min-width: 20ex;\n",
" max-width: 50ex;\n",
" color: var(--sklearn-color-text);\n",
" box-shadow: 2pt 2pt 4pt #999;\n",
" /* unfitted */\n",
" background: var(--sklearn-color-unfitted-level-0);\n",
" border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
"}\n",
"\n",
".sk-estimator-doc-link.fitted span {\n",
" /* fitted */\n",
" background: var(--sklearn-color-fitted-level-0);\n",
" border: var(--sklearn-color-fitted-level-3);\n",
"}\n",
"\n",
".sk-estimator-doc-link:hover span {\n",
" display: block;\n",
"}\n",
"\n",
"/* \"?\"-specific style due to the `<a>` HTML tag */\n",
"\n",
"#sk-container-id-1 a.estimator_doc_link {\n",
" float: right;\n",
" font-size: 1rem;\n",
" line-height: 1em;\n",
" font-family: monospace;\n",
" background-color: var(--sklearn-color-unfitted-level-0);\n",
" border-radius: 1rem;\n",
" height: 1rem;\n",
" width: 1rem;\n",
" text-decoration: none;\n",
" /* unfitted */\n",
" color: var(--sklearn-color-unfitted-level-1);\n",
" border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
"}\n",
"\n",
"#sk-container-id-1 a.estimator_doc_link.fitted {\n",
" /* fitted */\n",
" background-color: var(--sklearn-color-fitted-level-0);\n",
" border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
" color: var(--sklearn-color-fitted-level-1);\n",
"}\n",
"\n",
"/* On hover */\n",
"#sk-container-id-1 a.estimator_doc_link:hover {\n",
" /* unfitted */\n",
" background-color: var(--sklearn-color-unfitted-level-3);\n",
" color: var(--sklearn-color-background);\n",
" text-decoration: none;\n",
"}\n",
"\n",
"#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
" /* fitted */\n",
" background-color: var(--sklearn-color-fitted-level-3);\n",
"}\n",
"\n",
".estimator-table {\n",
" font-family: monospace;\n",
"}\n",
"\n",
".estimator-table summary {\n",
" padding: .5rem;\n",
" cursor: pointer;\n",
"}\n",
"\n",
".estimator-table summary::marker {\n",
" font-size: 0.7rem;\n",
"}\n",
"\n",
".estimator-table details[open] {\n",
" padding-left: 0.1rem;\n",
" padding-right: 0.1rem;\n",
" padding-bottom: 0.3rem;\n",
"}\n",
"\n",
".estimator-table .parameters-table {\n",
" margin-left: auto !important;\n",
" margin-right: auto !important;\n",
" margin-top: 0;\n",
"}\n",
"\n",
".estimator-table .parameters-table tr:nth-child(odd) {\n",
" background-color: #fff;\n",
"}\n",
"\n",
".estimator-table .parameters-table tr:nth-child(even) {\n",
" background-color: #f6f6f6;\n",
"}\n",
"\n",
".estimator-table .parameters-table tr:hover {\n",
" background-color: #e0e0e0;\n",
"}\n",
"\n",
".estimator-table table td {\n",
" border: 1px solid rgba(106, 105, 104, 0.232);\n",
"}\n",
"\n",
"/*\n",
" `table td`is set in notebook with right text-align.\n",
" We need to overwrite it.\n",
"*/\n",
".estimator-table table td.param {\n",
" text-align: left;\n",
" position: relative;\n",
" padding: 0;\n",
"}\n",
"\n",
".user-set td {\n",
" color:rgb(255, 94, 0);\n",
" text-align: left !important;\n",
"}\n",
"\n",
".user-set td.value {\n",
" color:rgb(255, 94, 0);\n",
" background-color: transparent;\n",
"}\n",
"\n",
".default td {\n",
" color: black;\n",
" text-align: left !important;\n",
"}\n",
"\n",
".user-set td i,\n",
".default td i {\n",
" color: black;\n",
"}\n",
"\n",
"/*\n",
" Styles for parameter documentation links\n",
" We need styling for visited so jupyter doesn't overwrite it\n",
"*/\n",
"a.param-doc-link,\n",
"a.param-doc-link:link,\n",
"a.param-doc-link:visited {\n",
" text-decoration: underline dashed;\n",
" text-underline-offset: .3em;\n",
" color: inherit;\n",
" display: block;\n",
" padding: .5em;\n",
"}\n",
"\n",
"/* \"hack\" to make the entire area of the cell containing the link clickable */\n",
"a.param-doc-link::before {\n",
" position: absolute;\n",
" content: \"\";\n",
" inset: 0;\n",
"}\n",
"\n",
".param-doc-description {\n",
" display: none;\n",
" position: absolute;\n",
" z-index: 9999;\n",
" left: 0;\n",
" padding: .5ex;\n",
" margin-left: 1.5em;\n",
" color: var(--sklearn-color-text);\n",
" box-shadow: .3em .3em .4em #999;\n",
" width: max-content;\n",
" text-align: left;\n",
" max-height: 10em;\n",
" overflow-y: auto;\n",
"\n",
" /* unfitted */\n",
" background: var(--sklearn-color-unfitted-level-0);\n",
" border: thin solid var(--sklearn-color-unfitted-level-3);\n",
"}\n",
"\n",
"/* Fitted state for parameter tooltips */\n",
".fitted .param-doc-description {\n",
" /* fitted */\n",
" background: var(--sklearn-color-fitted-level-0);\n",
" border: thin solid var(--sklearn-color-fitted-level-3);\n",
"}\n",
"\n",
".param-doc-link:hover .param-doc-description {\n",
" display: block;\n",
"}\n",
"\n",
".copy-paste-icon {\n",
" background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNy4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTIwOCAwTDMzMi4xIDBjMTIuNyAwIDI0LjkgNS4xIDMzLjkgMTQuMWw2Ny45IDY3LjljOSA5IDE0LjEgMjEuMiAxNC4xIDMzLjlMNDQ4IDMzNmMwIDI2LjUtMjEuNSA0OC00OCA0OGwtMTkyIDBjLTI2LjUgMC00OC0yMS41LTQ4LTQ4bDAtMjg4YzAtMjYuNSAyMS41LTQ4IDQ4LTQ4ek00OCAxMjhsODAgMCAwIDY0LTY0IDAgMCAyNTYgMTkyIDAgMC0zMiA2NCAwIDAgNDhjMCAyNi41LTIxLjUgNDgtNDggNDhMNDggNTEyYy0yNi41IDAtNDgtMjEuNS00OC00OEwwIDE3NmMwLTI2LjUgMjEuNS00OCA0OC00OHoiLz48L3N2Zz4=);\n",
" background-repeat: no-repeat;\n",
" background-size: 14px 14px;\n",
" background-position: 0;\n",
" display: inline-block;\n",
" width: 14px;\n",
" height: 14px;\n",
" cursor: pointer;\n",
"}\n",
"</style><body><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>LinearRegression()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>LinearRegression</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.8/modules/generated/sklearn.linear_model.LinearRegression.html\">?<span>Documentation for LinearRegression</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"\">\n",
" <div class=\"estimator-table\">\n",
" <details>\n",
" <summary>Parameters</summary>\n",
" <table class=\"parameters-table\">\n",
" <tbody>\n",
" \n",
" <tr class=\"default\">\n",
" <td><i class=\"copy-paste-icon\"\n",
" onclick=\"copyToClipboard('fit_intercept',\n",
" this.parentElement.nextElementSibling)\"\n",
" ></i></td>\n",
" <td class=\"param\">\n",
" <a class=\"param-doc-link\"\n",
" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.8/modules/generated/sklearn.linear_model.LinearRegression.html#:~:text=fit_intercept,-bool%2C%20default%3DTrue\">\n",
" fit_intercept\n",
" <span class=\"param-doc-description\">fit_intercept: bool, default=True<br><br>Whether to calculate the intercept for this model. If set<br>to False, no intercept will be used in calculations<br>(i.e. data is expected to be centered).</span>\n",
" </a>\n",
" </td>\n",
" <td class=\"value\">True</td>\n",
" </tr>\n",
" \n",
"\n",
" <tr class=\"default\">\n",
" <td><i class=\"copy-paste-icon\"\n",
" onclick=\"copyToClipboard('copy_X',\n",
" this.parentElement.nextElementSibling)\"\n",
" ></i></td>\n",
" <td class=\"param\">\n",
" <a class=\"param-doc-link\"\n",
" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.8/modules/generated/sklearn.linear_model.LinearRegression.html#:~:text=copy_X,-bool%2C%20default%3DTrue\">\n",
" copy_X\n",
" <span class=\"param-doc-description\">copy_X: bool, default=True<br><br>If True, X will be copied; else, it may be overwritten.</span>\n",
" </a>\n",
" </td>\n",
" <td class=\"value\">True</td>\n",
" </tr>\n",
" \n",
"\n",
" <tr class=\"default\">\n",
" <td><i class=\"copy-paste-icon\"\n",
" onclick=\"copyToClipboard('tol',\n",
" this.parentElement.nextElementSibling)\"\n",
" ></i></td>\n",
" <td class=\"param\">\n",
" <a class=\"param-doc-link\"\n",
" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.8/modules/generated/sklearn.linear_model.LinearRegression.html#:~:text=tol,-float%2C%20default%3D1e-6\">\n",
" tol\n",
" <span class=\"param-doc-description\">tol: float, default=1e-6<br><br>The precision of the solution (`coef_`) is determined by `tol` which<br>specifies a different convergence criterion for the `lsqr` solver.<br>`tol` is set as `atol` and `btol` of :func:`scipy.sparse.linalg.lsqr` when<br>fitting on sparse training data. This parameter has no effect when fitting<br>on dense data.<br><br>.. versionadded:: 1.7</span>\n",
" </a>\n",
" </td>\n",
" <td class=\"value\">1e-06</td>\n",
" </tr>\n",
" \n",
"\n",
" <tr class=\"default\">\n",
" <td><i class=\"copy-paste-icon\"\n",
" onclick=\"copyToClipboard('n_jobs',\n",
" this.parentElement.nextElementSibling)\"\n",
" ></i></td>\n",
" <td class=\"param\">\n",
" <a class=\"param-doc-link\"\n",
" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.8/modules/generated/sklearn.linear_model.LinearRegression.html#:~:text=n_jobs,-int%2C%20default%3DNone\">\n",
" n_jobs\n",
" <span class=\"param-doc-description\">n_jobs: int, default=None<br><br>The number of jobs to use for the computation. This will only provide<br>speedup in case of sufficiently large problems, that is if firstly<br>`n_targets > 1` and secondly `X` is sparse or if `positive` is set<br>to `True`. ``None`` means 1 unless in a<br>:obj:`joblib.parallel_backend` context. ``-1`` means using all<br>processors. See :term:`Glossary <n_jobs>` for more details.</span>\n",
" </a>\n",
" </td>\n",
" <td class=\"value\">None</td>\n",
" </tr>\n",
" \n",
"\n",
" <tr class=\"default\">\n",
" <td><i class=\"copy-paste-icon\"\n",
" onclick=\"copyToClipboard('positive',\n",
" this.parentElement.nextElementSibling)\"\n",
" ></i></td>\n",
" <td class=\"param\">\n",
" <a class=\"param-doc-link\"\n",
" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.8/modules/generated/sklearn.linear_model.LinearRegression.html#:~:text=positive,-bool%2C%20default%3DFalse\">\n",
" positive\n",
" <span class=\"param-doc-description\">positive: bool, default=False<br><br>When set to ``True``, forces the coefficients to be positive. This<br>option is only supported for dense arrays.<br><br>For a comparison between a linear regression model with positive constraints<br>on the regression coefficients and a linear regression without such constraints,<br>see :ref:`sphx_glr_auto_examples_linear_model_plot_nnls.py`.<br><br>.. versionadded:: 0.24</span>\n",
" </a>\n",
" </td>\n",
" <td class=\"value\">False</td>\n",
" </tr>\n",
" \n",
" </tbody>\n",
" </table>\n",
" </details>\n",
" </div>\n",
" </div></div></div></div></div><script>function copyToClipboard(text, element) {\n",
" // Get the parameter prefix from the closest toggleable content\n",
" const toggleableContent = element.closest('.sk-toggleable__content');\n",
" const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
" const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;\n",
"\n",
" const originalStyle = element.style;\n",
" const computedStyle = window.getComputedStyle(element);\n",
" const originalWidth = computedStyle.width;\n",
" const originalHTML = element.innerHTML.replace('Copied!', '');\n",
"\n",
" navigator.clipboard.writeText(fullParamName)\n",
" .then(() => {\n",
" element.style.width = originalWidth;\n",
" element.style.color = 'green';\n",
" element.innerHTML = \"Copied!\";\n",
"\n",
" setTimeout(() => {\n",
" element.innerHTML = originalHTML;\n",
" element.style = originalStyle;\n",
" }, 2000);\n",
" })\n",
" .catch(err => {\n",
" console.error('Failed to copy:', err);\n",
" element.style.color = 'red';\n",
" element.innerHTML = \"Failed!\";\n",
" setTimeout(() => {\n",
" element.innerHTML = originalHTML;\n",
" element.style = originalStyle;\n",
" }, 2000);\n",
" });\n",
" return false;\n",
"}\n",
"\n",
"document.querySelectorAll('.copy-paste-icon').forEach(function(element) {\n",
" const toggleableContent = element.closest('.sk-toggleable__content');\n",
" const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
" const paramName = element.parentElement.nextElementSibling\n",
" .textContent.trim().split(' ')[0];\n",
" const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;\n",
"\n",
" element.setAttribute('title', fullParamName);\n",
"});\n",
"\n",
"\n",
"/**\n",
" * Adapted from Skrub\n",
" * https://github.com/skrub-data/skrub/blob/403466d1d5d4dc76a7ef569b3f8228db59a31dc3/skrub/_reporting/_data/templates/report.js#L789\n",
" * @returns \"light\" or \"dark\"\n",
" */\n",
"function detectTheme(element) {\n",
" const body = document.querySelector('body');\n",
"\n",
" // Check VSCode theme\n",
" const themeKindAttr = body.getAttribute('data-vscode-theme-kind');\n",
" const themeNameAttr = body.getAttribute('data-vscode-theme-name');\n",
"\n",
" if (themeKindAttr && themeNameAttr) {\n",
" const themeKind = themeKindAttr.toLowerCase();\n",
" const themeName = themeNameAttr.toLowerCase();\n",
"\n",
" if (themeKind.includes(\"dark\") || themeName.includes(\"dark\")) {\n",
" return \"dark\";\n",
" }\n",
" if (themeKind.includes(\"light\") || themeName.includes(\"light\")) {\n",
" return \"light\";\n",
" }\n",
" }\n",
"\n",
" // Check Jupyter theme\n",
" if (body.getAttribute('data-jp-theme-light') === 'false') {\n",
" return 'dark';\n",
" } else if (body.getAttribute('data-jp-theme-light') === 'true') {\n",
" return 'light';\n",
" }\n",
"\n",
" // Guess based on a parent element's color\n",
" const color = window.getComputedStyle(element.parentNode, null).getPropertyValue('color');\n",
" const match = color.match(/^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)\\s*$/i);\n",
" if (match) {\n",
" const [r, g, b] = [\n",
" parseFloat(match[1]),\n",
" parseFloat(match[2]),\n",
" parseFloat(match[3])\n",
" ];\n",
"\n",
" // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness\n",
" const luma = 0.299 * r + 0.587 * g + 0.114 * b;\n",
"\n",
" if (luma > 180) {\n",
" // If the text is very bright we have a dark theme\n",
" return 'dark';\n",
" }\n",
" if (luma < 75) {\n",
" // If the text is very dark we have a light theme\n",
" return 'light';\n",
" }\n",
" // Otherwise fall back to the next heuristic.\n",
" }\n",
"\n",
" // Fallback to system preference\n",
" return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n",
"}\n",
"\n",
"\n",
"function forceTheme(elementId) {\n",
" const estimatorElement = document.querySelector(`#${elementId}`);\n",
" if (estimatorElement === null) {\n",
" console.error(`Element with id ${elementId} not found.`);\n",
" } else {\n",
" const theme = detectTheme(estimatorElement);\n",
" estimatorElement.classList.add(theme);\n",
" }\n",
"}\n",
"\n",
"forceTheme('sk-container-id-1');</script></body>"
]
},
"execution_count": 409,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 409
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T15:16:10.648492700Z",
"start_time": "2026-04-25T15:16:10.630533500Z"
}
},
"cell_type": "code",
"source": [
"y_pred_s = simple_model.predict(X_test_s)\n",
"rmse = np.sqrt(mean_squared_error(y_test_s, y_pred_s))"
],
"id": "983db24d45054c97",
"outputs": [],
"execution_count": 410
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-04-25T15:16:25.585898300Z",
"start_time": "2026-04-25T15:16:25.549110800Z"
}
},
"cell_type": "code",
"source": "print(f\"RMSE using ONLY '{feature}': {rmse}\")",
"id": "4cb7c407238e67c1",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"RMSE using ONLY 'Numeric Installs': 0.4179032096419041\n"
]
}
],
"execution_count": 411
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": "",
"id": "79c525159dd03465"
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}