machinelearning

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 0cb63ccf8d82652d77a02f8bf46dc52426cbb3af
parent 4f396342c919ebe7a530e1ff99f2c4cff78b18b4
Author: Andrew <andrewlaack1@gmail.com>
Date:   Wed, 15 May 2024 20:37:57 -0500

added start of book lin reg

Diffstat:
AlinearRegression/LinearRegressionHousingV2.ipynb | 151++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 151 insertions(+), 0 deletions(-)

diff --git a/linearRegression/LinearRegressionHousingV2.ipynb b/linearRegression/LinearRegressionHousingV2.ipynb @@ -0,0 +1,151 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# This is from following along with the hands on machine learning book. \n", + "# I already implemented a similar, albeit unoptimized, verison of the same thing\n", + "# without help from the book (see LinearRegressionHousing.ipynb).\n", + "\n", + "from pathlib import Path\n", + "import pandas as pd\n", + "import tarfile\n", + "import requests\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.linear_model import LinearRegression\n", + "\n", + "# Download tar file and write it out to a csv then read that back into a pandas dataframe\n", + "def load_data():\n", + " filePath = Path(\"../datasets/housing.tgz\")\n", + " if not filePath.is_file():\n", + " Path(\"../datasets\").mkdir(parents=True, exist_ok=True)\n", + " url = \"https://github.com/ageron/data/raw/main/housing.tgz\"\n", + " req = requests.get(url)\n", + " with open('../datasets/housing.tgz', 'wb') as f:\n", + " f.write(req.content)\n", + "\n", + " with tarfile.open(filePath) as housingFile:\n", + " housingFile.extractall(path=\"../datasets\")\n", + " return pd.read_csv(Path(\"../datasets/housing/housing.csv\"))\n", + "\n", + "housing = load_data()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "16512\n", + "4128\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "# Pass in data and percent to be in test set. \n", + "# Return test and validation sets.\n", + "def splitTestingAndTraining(data, testPercent):\n", + "\n", + " # This ensures that the current dataset will always have the same split. \n", + " # Issues would arise however if we were to change the dataset in some way, but\n", + " # this should be fine as we are using a static dataset. Alternatives are hashing\n", + " # algorithms using identifiers and writing to seperate files. \n", + " \n", + " np.random.seed(10)\n", + "\n", + " # Create random list of integers for all integers 0 to length of set -1.\n", + " shuffled = np.random.permutation(len(data))\n", + " testSize = int(len(data) * testPercent)\n", + " testIndices = shuffled[:testSize]\n", + " trainIndices = shuffled[testSize:]\n", + " return data.iloc[trainIndices], data.iloc[testIndices]\n", + " \n", + "\n", + "trainingData, testingData = splitTestingAndTraining(housing, .2)\n", + "\n", + "print(len(trainingData))\n", + "print(len(testingData))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "16512\n", + "4128\n" + ] + } + ], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "# This is pretty much the same as the code written above, but simpler as it has been defined already. \n", + "trainingData, testingData = train_test_split(housing, test_size=.2, random_state=10)\n", + "\n", + "print(len(trainingData))\n", + "print(len(testingData))" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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AJgegQgAAJgegQgAAJgegQgAAJiex7/tHiiN6r251K3jW70NTX5QapKYqpw8i9u289vEaLeNDQDlCUeIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6RGIAACA6Xk8EP3rX//Sc889p+rVq8vf318PPPCAtm/f7lhvGIZGjRqlWrVqyd/fX507d9Yvv/ziNMaZM2fUu3dv2Ww2ValSRQMGDNDFixed+vz000965JFH5Ofnp5CQEE2ePLlE9g8AAJR+Hg1EZ8+e1UMPPSQfHx99//332rdvn6ZMmaKqVas6+kyePFkzZ87UnDlztGXLFlWsWFFRUVG6evWqo0/v3r21d+9epaWlacmSJVq3bp0GDRrkWJ+dna3IyEiFhoZqx44devfdd5WYmKiPP/64RPcXAACUThU8ufFJkyYpJCRESUlJjrawsDDHz4ZhaPr06Ro5cqS6desmSfrss88UFBSkb7/9Vs8884z279+v5cuXa9u2bWrVqpUk6f3339df/vIXvffee6pdu7bmz5+va9eu6dNPP5Wvr68aN26s9PR0TZ061Sk4AQAAc/JoIFq0aJGioqL01FNPae3atbr77rv1yiuv6IUXXpAkHTlyRJmZmercubPjOYGBgWrTpo02bdqkZ555Rps2bVKVKlUcYUiSOnfuLC8vL23ZskVPPvmkNm3apHbt2snX19fRJyoqSpMmTdLZs2edjkhJUk5OjnJychzL2dnZkqTc3Fzl5ua65bUoCQW1l+V9KClWb8O943sZTv+6S3mZa3fOB3NRuvB7qvQoD3PhSu0eDUS//vqrZs+erYSEBP3P//yPtm3bpiFDhsjX11cxMTHKzMyUJAUFBTk9LygoyLEuMzNTNWvWdFpfoUIFVatWzanPH488/XHMzMzMQoFowoQJGjNmTKF6V6xYoYCAgDvY49IhLS3N0yWUepMfLJntjGuV79bxly1b5tbxS0pJzAdzUbrwe6r0KMtzcfny5SL39Wggys/PV6tWrfTOO+9Ikpo3b649e/Zozpw5iomJ8VhdI0aMUEJCgmM5OztbISEhioyM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XLi4nTL83nBl7FL7OURhYWEKDg7WqlWrHG3Z2dnasmWL7Ha7JMlut+vcuXPasWOHo8/q1auVn5+vNm3aOPqsW7fO6TxiWlqaGjRocMPTZQAAwHw8GoguXryo9PR0paenS/r9Qur09HRlZGTIYrEoLi5O48eP16JFi7R792717dtXtWvXVvfu3SVJjRo10mOPPaYXXnhBW7du1YYNGzR48GA988wzql27tiSpV69e8vX11YABA7R371598cUXmjFjhtMpMQAAYG4ePWW2fft2dejQwbFcEFJiYmKUnJysYcOG6dKlSxo0aJDOnTunhx9+WMuXL5efn5/jOfPnz9fgwYPVqVMneXl5qWfPnpo5c6ZjfWBgoFasWKHY2Fi1bNlSd911l0aNGsUt9wAAwMGjgah9+/YyjJvfzmexWDR27FiNHTv2pn2qVaumlJSUW24nIiJCP/74423XCQAAyrdSew0RAABASSEQAQAA0yu1t92bUb03l7p1fKu3ockP/v7ZFe68hfK3idFuGxsAAHfgCBEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9AhEAADA9UwWiWbNmqV69evLz81ObNm20detWT5cEAABKAdMEoi+++EIJCQkaPXq0du7cqaZNmyoqKkonT570dGkAAMDDTBOIpk6dqhdeeEH9+vVTeHi45syZo4CAAH366aeeLg0AAHhYBU8XUBKuXbumHTt2aMSIEY42Ly8vde7cWZs2bSrUPycnRzk5OY7l8+fPS5LOnDmj3Nxct9VZ4folt40tSRXyDV2+nK8KuV7Ky7e4bTunT59229glhbkoXdw5H8yFa8rDe4O5KOL45eC9ceHCBUmSYRh/3tkwgX/961+GJGPjxo1O7UOHDjUefPDBQv1Hjx5tSOLBgwcPHjx4lIPH0aNH/zQrmOIIkatGjBihhIQEx3J+fr7OnDmj6tWry2JxX0p2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bJlT27Zt25yW7+R1euCBB9SqVSv97W9/U0pKij744INb9gfAXWYAitmjjz6qdu3aqWfPnkpLS9ORI0f0/fffa/ny5ZKk119/XatWrdK4ceN08OBBzZs3Tx988IHeeOONO9ru8OHDtXHjRg0ePFjp6en65Zdf9N133xW64+qPRo8erb///e8aPXq09u/fr927d2vSpEmSfj+q5Ovrq/fff1+//vqrFi1apHHjxjk9PzQ0VBaLRUuWLNGpU6d08eJFVa5cWW+88Ybi4+M1b948HT58WDt37tT777+vefPmSZJefPFF/fzzzxo+fLgOHjyoBQsWKDk5WdL/P/J1p6/TwIEDNXHiRBmG4XTnHICb8PRFTABKtxtdVP3aa6859enWrZsRExPjWD59+rTRr18/o3r16oafn5/RpEkTY8mSJY71X375pREeHm74+PgYdevWNd59912n8UJDQ41p06Y5tUkyvvnmG8fykSNHDEnGrl27HG1bt241unTpYlSqVMmoWLGiERERYbz99tu33L+vvvrKaNasmeHr62vcddddRo8ePRzrUlJSjHr16hlWq9Ww2+3GokWLCm1z7NixRnBwsGGxWByvQX5+vjF9+nSjQYMGho+Pj1GjRg0jKirKWLt2reN53333nVG/fn3DarUa7du3N2bPnm1IcroA/HZepwIXLlwwAgICjFdeeeWW+w/gdxbDMAzPRjIAwNtvv605c+bo6NGjxTLeb7/9pnvvvVfbtm1TixYtimVMoDzjGiIA8IAPP/xQrVu3VvXq1bVhwwa9++67tzy9V1S5ubk6ffq0Ro4cqbZt2xKGgCIiEAGAB/zyyy8aP368zpw5o7p16+r111/XiBEj7njcDRs2qEOHDrr//vsLfTo2gJvjlBkAADA97jIDAACmRyACAACmRyACAACmRyACAACmRyACAACmRyACAACmRyACAACmRyACAACm9/8ANauQ3Vg9kScAAAAASUVORK5CYII=", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Define strata for median income as it is a key indicator for housing prices\n", + "# This will help to ensure we get a representative sample of each grouping in our testing\n", + "# and validation sets.\n", + "housing[\"income_cat\"] = pd.cut(housing[\"median_income\"],\n", + " bins=[0, 1.5, 3, 4.5, 6, np.inf],\n", + " labels=[1,2,3,4,5]\n", + " )\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "notebook", + "language": "python", + "name": "notebook" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}