2760 lines
112 KiB
Plaintext
2760 lines
112 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {
|
||
"id": "Q6ifg03dKPR4"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"############################\n",
|
||
"# BLOCK 1: IMPORTS\n",
|
||
"############################\n",
|
||
"\n",
|
||
"# libraries!\n",
|
||
"import numpy as np # numpy is Python's \"array\" library\n",
|
||
"import pandas as pd # Pandas is Python's \"data\" library (\"dataframe\" == spreadsheet)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {
|
||
"id": "0ghtg7ecRQ50"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"#############################\n",
|
||
"# BLOCK 2: VARIABLES LISTING\n",
|
||
"#############################\n",
|
||
"\n",
|
||
"# for reference, as you work throughout, come back and list all the variable names\n",
|
||
"# here along with what that variable holds\n",
|
||
"\n",
|
||
"# Variable: Contents\n",
|
||
"# -------------------\n",
|
||
"# [FILL IN VARS BELOW]\n",
|
||
"#"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 49,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 424
|
||
},
|
||
"id": "DjCaxH3BKJ_O",
|
||
"outputId": "ab33e45d-d332-412e-db2a-88cc4c9528f4"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"####################################\n",
|
||
"#from sklearn.datasets import load_iris\n",
|
||
"#data = load_iris()\n",
|
||
"#df = pd.DataFrame(data.data, columns=data.feature_names)\n",
|
||
"#df"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 50,
|
||
"metadata": {
|
||
"id": "ANJhDRNPKPR5"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"iris.csv: file read into a pandas DataFrame.\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"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>sepallen</th>\n",
|
||
" <th>sepalwid</th>\n",
|
||
" <th>petallen</th>\n",
|
||
" <th>petalwid</th>\n",
|
||
" <th>irisname</th>\n",
|
||
" <th>junk</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>0</th>\n",
|
||
" <td>NaN</td>\n",
|
||
" <td>3.5</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>4.9</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>4.7</td>\n",
|
||
" <td>3.2</td>\n",
|
||
" <td>1.3</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>4.6</td>\n",
|
||
" <td>3.1</td>\n",
|
||
" <td>1.5</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>4</th>\n",
|
||
" <td>5.0</td>\n",
|
||
" <td>3.6</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"</div>"
|
||
],
|
||
"text/plain": [
|
||
" sepallen sepalwid petallen petalwid irisname junk\n",
|
||
"0 NaN 3.5 1.4 0.2 setosa remove_me\n",
|
||
"1 4.9 3.0 1.4 0.2 setosa remove_me\n",
|
||
"2 4.7 3.2 1.3 0.2 setosa remove_me\n",
|
||
"3 4.6 3.1 1.5 0.2 setosa remove_me\n",
|
||
"4 5.0 3.6 1.4 0.2 setosa remove_me"
|
||
]
|
||
},
|
||
"execution_count": 50,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"#############################\n",
|
||
"# BLOCK 3: READING DATA\n",
|
||
"#############################\n",
|
||
"\n",
|
||
"# let's read in our flower data...\n",
|
||
"#\n",
|
||
"filename = 'iris.csv'\n",
|
||
"df = pd.read_csv(filename, header=0) # encoding=\"latin1\" et al.\n",
|
||
"print(f\"{filename}: file read into a pandas DataFrame.\")\n",
|
||
"df.head()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 14,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 361
|
||
},
|
||
"id": "8v3oVZYTKPR6",
|
||
"outputId": "4110ac58-5c52-4cbf-a83f-16d9a7189ccb"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"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>sepallen</th>\n",
|
||
" <th>sepalwid</th>\n",
|
||
" <th>petallen</th>\n",
|
||
" <th>petalwid</th>\n",
|
||
" <th>irisname</th>\n",
|
||
" <th>junk</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>0</th>\n",
|
||
" <td>NaN</td>\n",
|
||
" <td>3.5</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>4.9</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>4.7</td>\n",
|
||
" <td>3.2</td>\n",
|
||
" <td>1.3</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>4.6</td>\n",
|
||
" <td>3.1</td>\n",
|
||
" <td>1.5</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" <td>remove_me</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",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>146</th>\n",
|
||
" <td>6.3</td>\n",
|
||
" <td>2.5</td>\n",
|
||
" <td>5.0</td>\n",
|
||
" <td>1.9</td>\n",
|
||
" <td>virginica</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>147</th>\n",
|
||
" <td>6.5</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>5.2</td>\n",
|
||
" <td>2.0</td>\n",
|
||
" <td>virginica</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>148</th>\n",
|
||
" <td>6.2</td>\n",
|
||
" <td>3.4</td>\n",
|
||
" <td>5.4</td>\n",
|
||
" <td>2.3</td>\n",
|
||
" <td>alieniris</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>149</th>\n",
|
||
" <td>5.9</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>5.1</td>\n",
|
||
" <td>1.8</td>\n",
|
||
" <td>alieniris</td>\n",
|
||
" <td>remove_me</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"<p>150 rows × 6 columns</p>\n",
|
||
"</div>"
|
||
],
|
||
"text/plain": [
|
||
" sepallen sepalwid petallen petalwid irisname junk\n",
|
||
"0 NaN 3.5 1.4 0.2 setosa remove_me\n",
|
||
"1 4.9 3.0 1.4 0.2 setosa remove_me\n",
|
||
"2 4.7 3.2 1.3 0.2 setosa remove_me\n",
|
||
"3 4.6 3.1 1.5 0.2 setosa remove_me\n",
|
||
".. ... ... ... ... ... ...\n",
|
||
"146 6.3 2.5 5.0 1.9 virginica remove_me\n",
|
||
"147 6.5 3.0 5.2 2.0 virginica remove_me\n",
|
||
"148 6.2 3.4 5.4 2.3 alieniris remove_me\n",
|
||
"149 5.9 3.0 5.1 1.8 alieniris remove_me\n",
|
||
"\n",
|
||
"[150 rows x 6 columns]"
|
||
]
|
||
},
|
||
"execution_count": 14,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"#############################\n",
|
||
"# BLOCK 4: SETTING OPTIONS\n",
|
||
"#############################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# a dataframe is a \"spreadsheet in Python\"\n",
|
||
"# (this one seems to have an extra column!)\n",
|
||
"#\n",
|
||
"pd.set_option('display.max_rows', 8) # None for no limit; default: 10\n",
|
||
"pd.set_option('display.min_rows', 8) # None for no limit; default: 10\n",
|
||
"# let's view it!\n",
|
||
"df"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"id": "aksGQcJ8KPR6",
|
||
"outputId": "4cbdedf5-cabe-4263-c06c-26bbb8f509b1"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"<class 'pandas.DataFrame'>\n",
|
||
"RangeIndex: 150 entries, 0 to 149\n",
|
||
"Data columns (total 6 columns):\n",
|
||
" # Column Non-Null Count Dtype \n",
|
||
"--- ------ -------------- ----- \n",
|
||
" 0 sepallen 149 non-null float64\n",
|
||
" 1 sepalwid 150 non-null float64\n",
|
||
" 2 petallen 150 non-null float64\n",
|
||
" 3 petalwid 149 non-null float64\n",
|
||
" 4 irisname 149 non-null str \n",
|
||
" 5 junk 150 non-null str \n",
|
||
"dtypes: float64(4), str(2)\n",
|
||
"memory usage: 7.2 KB\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"##############################\n",
|
||
"# BLOCK 5: USING DF'S .info()\n",
|
||
"##############################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# let's look at our pandas DataFrame's info (Aargh: that extra column!)\n",
|
||
"#\n",
|
||
"df.info()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 18,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"id": "ADWpUqeKKPR7",
|
||
"outputId": "76ac8d2f-0d98-4721-e0f2-b79b48736b00"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"<class 'pandas.DataFrame'>\n",
|
||
"RangeIndex: 150 entries, 0 to 149\n",
|
||
"Data columns (total 5 columns):\n",
|
||
" # Column Non-Null Count Dtype \n",
|
||
"--- ------ -------------- ----- \n",
|
||
" 0 sepallen 149 non-null float64\n",
|
||
" 1 sepalwid 150 non-null float64\n",
|
||
" 2 petallen 150 non-null float64\n",
|
||
" 3 petalwid 149 non-null float64\n",
|
||
" 4 irisname 149 non-null str \n",
|
||
"dtypes: float64(4), str(1)\n",
|
||
"memory usage: 6.0 KB\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"#############################\n",
|
||
"# BLOCK 6: CLEANING DATA\n",
|
||
"#############################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# let's drop that last column (dropping is usually by _name_):\n",
|
||
"#\n",
|
||
"# if you want a list of the column names use df.columns\n",
|
||
"#col5name = df.columns[5] # get column name at index 5\n",
|
||
"\n",
|
||
"df_clean = df.drop(columns=['junk']) # drop by name is typical, but what else is possible?\n",
|
||
"df_clean.info() # Is the bad last column gone?"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 19,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"id": "9RAydRsiKPR7",
|
||
"outputId": "18ec37ec-3a95-4ef9-c111-847ac8f6ecec"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"FEATURES: Index(['sepallen', 'sepalwid', 'petallen', 'petalwid', 'irisname'], dtype='str')\n",
|
||
"\n",
|
||
"First feature: sepallen\n",
|
||
"\n",
|
||
"feature_name_to_index: {'sepallen': 0, 'sepalwid': 1, 'petallen': 2, 'petalwid': 3, 'irisname': 4}\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"##############################\n",
|
||
"# BLOCK 7: FEATURE NAMES DICT\n",
|
||
"##############################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# let's keep our column names in variables, for reference;\n",
|
||
"# in machine learning contexts, these are referred to as \"features\"\n",
|
||
"#\n",
|
||
"features = df_clean.columns # \"list\" of columns\n",
|
||
"print(f\"FEATURES: {features}\\n\")\n",
|
||
" # It's a \"pandas\" list, called an Index\n",
|
||
" # use it just as a Python list of strings:\n",
|
||
"print(f\"First feature: {features[0]}\\n\")\n",
|
||
"\n",
|
||
"# let's create a dictionary to look up any column index by name\n",
|
||
"feature_name_to_index = {}\n",
|
||
"for i, name in enumerate(features):\n",
|
||
" feature_name_to_index[name] = i # using the name (as key), assign the value (i)\n",
|
||
"print(f\"feature_name_to_index: {feature_name_to_index}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 20,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 1000
|
||
},
|
||
"id": "PWkPTOGnKPR8",
|
||
"outputId": "f6a46e8f-0169-4646-864f-1b3ed749f238"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"<class 'pandas.DataFrame'>\n",
|
||
"RangeIndex: 150 entries, 0 to 149\n",
|
||
"Data columns (total 5 columns):\n",
|
||
" # Column Non-Null Count Dtype \n",
|
||
"--- ------ -------------- ----- \n",
|
||
" 0 sepallen 149 non-null float64\n",
|
||
" 1 sepalwid 150 non-null float64\n",
|
||
" 2 petallen 150 non-null float64\n",
|
||
" 3 petalwid 149 non-null float64\n",
|
||
" 4 irisname 149 non-null str \n",
|
||
"dtypes: float64(4), str(1)\n",
|
||
"memory usage: 6.0 KB\n",
|
||
"======================================================================\n",
|
||
" sepallen sepalwid petallen petalwid irisname\n",
|
||
"0 NaN 3.5 1.4 0.2 setosa\n",
|
||
"1 4.9 3.0 1.4 0.2 setosa\n",
|
||
"2 4.7 3.2 1.3 0.2 setosa\n",
|
||
"3 4.6 3.1 1.5 0.2 setosa\n",
|
||
".. ... ... ... ... ...\n",
|
||
"146 6.3 2.5 5.0 1.9 virginica\n",
|
||
"147 6.5 3.0 5.2 2.0 virginica\n",
|
||
"148 6.2 3.4 5.4 2.3 alieniris\n",
|
||
"149 5.9 3.0 5.1 1.8 alieniris\n",
|
||
"\n",
|
||
"[150 rows x 5 columns]\n",
|
||
"======================================================================\n",
|
||
"Irisname entries: <StringArray>\n",
|
||
"['setosa', nan, 'versicolor', 'virginica', 'alieniris']\n",
|
||
"Length: 5, dtype: str\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"##############################\n",
|
||
"# BLOCK 8: INSPECTING DATA\n",
|
||
"##############################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# let's look at our cleaned-up dataframe...\n",
|
||
"#\n",
|
||
"df_clean.info()\n",
|
||
"print('=' * 70)\n",
|
||
"\n",
|
||
"#\n",
|
||
"# Notice that the non-null count is _different_ for irisname!\n",
|
||
"# Why? Show a table and inspect...\n",
|
||
"print(df_clean)\n",
|
||
"print('=' * 70)\n",
|
||
"\n",
|
||
"# or more to the point, grab that column and inspect:\n",
|
||
"print(f\"Irisname entries: {df_clean['irisname'].unique()}\")\n",
|
||
"\n",
|
||
"# also note how the last two rows in the df have problems, among others...\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 21,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"id": "4B2An3iML1ay",
|
||
"outputId": "5492db65-acd8-4c11-f669-742a79b6cb62"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"Index(['sepallen', 'sepalwid', 'petallen', 'petalwid', 'irisname', 'junk'], dtype='str')"
|
||
]
|
||
},
|
||
"execution_count": 21,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"df.columns"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"metadata": {
|
||
"id": "xM22NWdqKPR-",
|
||
"scrolled": false
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"<class 'pandas.DataFrame'>\n",
|
||
"Index: 147 entries, 1 to 149\n",
|
||
"Data columns (total 5 columns):\n",
|
||
" # Column Non-Null Count Dtype \n",
|
||
"--- ------ -------------- ----- \n",
|
||
" 0 sepallen 147 non-null float64\n",
|
||
" 1 sepalwid 147 non-null float64\n",
|
||
" 2 petallen 147 non-null float64\n",
|
||
" 3 petalwid 147 non-null float64\n",
|
||
" 4 irisname 147 non-null str \n",
|
||
"dtypes: float64(4), str(1)\n",
|
||
"memory usage: 6.9 KB\n",
|
||
"======================================================================\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"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>sepallen</th>\n",
|
||
" <th>sepalwid</th>\n",
|
||
" <th>petallen</th>\n",
|
||
" <th>petalwid</th>\n",
|
||
" <th>irisname</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>4.9</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>4.7</td>\n",
|
||
" <td>3.2</td>\n",
|
||
" <td>1.3</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>4.6</td>\n",
|
||
" <td>3.1</td>\n",
|
||
" <td>1.5</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>4</th>\n",
|
||
" <td>5.0</td>\n",
|
||
" <td>3.6</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>...</th>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>146</th>\n",
|
||
" <td>6.3</td>\n",
|
||
" <td>2.5</td>\n",
|
||
" <td>5.0</td>\n",
|
||
" <td>1.9</td>\n",
|
||
" <td>virginica</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>147</th>\n",
|
||
" <td>6.5</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>5.2</td>\n",
|
||
" <td>2.0</td>\n",
|
||
" <td>virginica</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>148</th>\n",
|
||
" <td>6.2</td>\n",
|
||
" <td>3.4</td>\n",
|
||
" <td>5.4</td>\n",
|
||
" <td>2.3</td>\n",
|
||
" <td>alieniris</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>149</th>\n",
|
||
" <td>5.9</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>5.1</td>\n",
|
||
" <td>1.8</td>\n",
|
||
" <td>alieniris</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"<p>147 rows × 5 columns</p>\n",
|
||
"</div>"
|
||
],
|
||
"text/plain": [
|
||
" sepallen sepalwid petallen petalwid irisname\n",
|
||
"1 4.9 3.0 1.4 0.2 setosa\n",
|
||
"2 4.7 3.2 1.3 0.2 setosa\n",
|
||
"3 4.6 3.1 1.5 0.2 setosa\n",
|
||
"4 5.0 3.6 1.4 0.2 setosa\n",
|
||
".. ... ... ... ... ...\n",
|
||
"146 6.3 2.5 5.0 1.9 virginica\n",
|
||
"147 6.5 3.0 5.2 2.0 virginica\n",
|
||
"148 6.2 3.4 5.4 2.3 alieniris\n",
|
||
"149 5.9 3.0 5.1 1.8 alieniris\n",
|
||
"\n",
|
||
"[147 rows x 5 columns]"
|
||
]
|
||
},
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"##############################\n",
|
||
"# BLOCK 9: USING DF'S dropna\n",
|
||
"##############################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# typically, after dropping columns that we don't want,\n",
|
||
"# we drop rows with missing data (other approaches are possible, too)\n",
|
||
"#\n",
|
||
"df_clean = df_clean.dropna() # this removes all rows with nan items\n",
|
||
"df_clean.info()\n",
|
||
"print('=' * 70)\n",
|
||
"df_clean\n",
|
||
"\n",
|
||
"#\n",
|
||
"# notice that _all_ of the rows now have 144 non-null items\n",
|
||
"# also, the first and last rows (among others) aren't valid data...\n",
|
||
"# we'll handle that next"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 23,
|
||
"metadata": {
|
||
"id": "h0spkxGzKPR-"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Irisname entries: <StringArray>\n",
|
||
"['setosa', 'versicolor', 'virginica', 'alieniris']\n",
|
||
"Length: 4, dtype: str\n",
|
||
"1 False\n",
|
||
"2 False\n",
|
||
"3 False\n",
|
||
"4 False\n",
|
||
" ... \n",
|
||
"146 False\n",
|
||
"147 False\n",
|
||
"148 True\n",
|
||
"149 True\n",
|
||
"Name: irisname, Length: 147, dtype: bool\n",
|
||
"1 True\n",
|
||
"2 True\n",
|
||
"3 True\n",
|
||
"4 True\n",
|
||
" ... \n",
|
||
"146 True\n",
|
||
"147 True\n",
|
||
"148 False\n",
|
||
"149 False\n",
|
||
"Name: irisname, Length: 147, dtype: bool\n",
|
||
"(145, 5)\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"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>sepallen</th>\n",
|
||
" <th>sepalwid</th>\n",
|
||
" <th>petallen</th>\n",
|
||
" <th>petalwid</th>\n",
|
||
" <th>irisname</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>4.9</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>4.7</td>\n",
|
||
" <td>3.2</td>\n",
|
||
" <td>1.3</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>4.6</td>\n",
|
||
" <td>3.1</td>\n",
|
||
" <td>1.5</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>4</th>\n",
|
||
" <td>5.0</td>\n",
|
||
" <td>3.6</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>setosa</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>...</th>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>144</th>\n",
|
||
" <td>6.7</td>\n",
|
||
" <td>3.3</td>\n",
|
||
" <td>5.7</td>\n",
|
||
" <td>2.5</td>\n",
|
||
" <td>virginica</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>145</th>\n",
|
||
" <td>6.7</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>5.2</td>\n",
|
||
" <td>2.3</td>\n",
|
||
" <td>virginica</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>146</th>\n",
|
||
" <td>6.3</td>\n",
|
||
" <td>2.5</td>\n",
|
||
" <td>5.0</td>\n",
|
||
" <td>1.9</td>\n",
|
||
" <td>virginica</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>147</th>\n",
|
||
" <td>6.5</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>5.2</td>\n",
|
||
" <td>2.0</td>\n",
|
||
" <td>virginica</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"<p>145 rows × 5 columns</p>\n",
|
||
"</div>"
|
||
],
|
||
"text/plain": [
|
||
" sepallen sepalwid petallen petalwid irisname\n",
|
||
"1 4.9 3.0 1.4 0.2 setosa\n",
|
||
"2 4.7 3.2 1.3 0.2 setosa\n",
|
||
"3 4.6 3.1 1.5 0.2 setosa\n",
|
||
"4 5.0 3.6 1.4 0.2 setosa\n",
|
||
".. ... ... ... ... ...\n",
|
||
"144 6.7 3.3 5.7 2.5 virginica\n",
|
||
"145 6.7 3.0 5.2 2.3 virginica\n",
|
||
"146 6.3 2.5 5.0 1.9 virginica\n",
|
||
"147 6.5 3.0 5.2 2.0 virginica\n",
|
||
"\n",
|
||
"[145 rows x 5 columns]"
|
||
]
|
||
},
|
||
"execution_count": 23,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"################################\n",
|
||
"# BLOCK 10: REMOVING BOGUS DATA\n",
|
||
"################################\n",
|
||
"\n",
|
||
"# or more to the point, grab that column and inspect:\n",
|
||
"print(f\"Irisname entries: {df_clean['irisname'].unique()}\")\n",
|
||
"print(df_clean['irisname'] == 'alieniris') # what does this show?\n",
|
||
"print(df_clean['irisname'] != 'alieniris') # what does this show?\n",
|
||
"\n",
|
||
"# define a final version of the DataFrame by pulling out the\n",
|
||
"# bad alieniris data (remember that you can pass a boolean\n",
|
||
"# Series to select data that you want)\n",
|
||
"df_final = df_clean[df_clean['irisname'] != 'alieniris'].copy()\n",
|
||
"# ^^^^ YOU NEED TO WRITE CODE HERE...\n",
|
||
"\n",
|
||
"print(df_final.shape)\n",
|
||
"df_final"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 24,
|
||
"metadata": {
|
||
"id": "EywtvRyMKPR-"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"{'setosa': 0, 'versicolor': 1, 'virginica': 2}\n",
|
||
"<class 'dict'>\n",
|
||
"setosa maps to 0\n",
|
||
"versicolor maps to 1\n",
|
||
"virginica maps to 2\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"##########################################\n",
|
||
"# BLOCK 11: CONVERT SPECIES NAME TO INDEX\n",
|
||
"##########################################\n",
|
||
"\n",
|
||
"# all of scikit-learn's ML routines need numbers, not strings\n",
|
||
"# ... even for categories/classifications (like species!)\n",
|
||
"# so, we will convert the flower-species to numbers:\n",
|
||
"\n",
|
||
"species_names = df_final['irisname'].unique()\n",
|
||
"species_name_to_index = { species_names[i]:i for i in range(len(species_names))}\n",
|
||
"print(species_name_to_index)\n",
|
||
"print(type(species_name_to_index))\n",
|
||
"\n",
|
||
"def convertSpecies(species_name: str) -> int:\n",
|
||
" ''' return the species index (a unique integer/category) '''\n",
|
||
" #print(f\"converting {species_name}...\")\n",
|
||
" return species_name_to_index[species_name]\n",
|
||
"\n",
|
||
"# Let's try it out...\n",
|
||
"for name in species_names:\n",
|
||
" print(f\"{name} maps to {convertSpecies(name)}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"id": "NuKqemiiKPR_"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"ename": "KeyError",
|
||
"evalue": "0",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
||
"\u001b[31mKeyError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[28]\u001b[39m\u001b[32m, line 14\u001b[39m\n\u001b[32m 10\u001b[39m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[32m 11\u001b[39m \u001b[38;5;66;03m# >>> ADD CODE HERE TO KEEP THE WARNING FROM HAPPENING <<<\u001b[39;00m\n\u001b[32m 12\u001b[39m \n\u001b[32m 13\u001b[39m df_final[\u001b[33m'irisname'\u001b[39m] = df_final[\u001b[33m'irisname'\u001b[39m].apply(convertSpecies)\n\u001b[32m---> \u001b[39m\u001b[32m14\u001b[39m df_final.loc[:, \u001b[33m'irisname'\u001b[39m] = df_final[\u001b[33m'irisname'\u001b[39m].apply(convertSpecies)\n\u001b[32m 15\u001b[39m \u001b[38;5;66;03m# Don't run this twice! Why?! What's \"KeyError: 0\"?\u001b[39;00m\n\u001b[32m 16\u001b[39m \u001b[38;5;66;03m# (of course, you can always go back and re-establish definitions of df_final)\u001b[39;00m\n\u001b[32m 17\u001b[39m \n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~/.local/lib/python3.14/site-packages/pandas/core/series.py:5084\u001b[39m, in \u001b[36mSeries.apply\u001b[39m\u001b[34m(self, func, args, by_row, **kwargs)\u001b[39m\n\u001b[32m 4960\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mapply\u001b[39m(\n\u001b[32m 4961\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 4962\u001b[39m func: AggFuncType,\n\u001b[32m (...)\u001b[39m\u001b[32m 4966\u001b[39m **kwargs,\n\u001b[32m 4967\u001b[39m ) -> DataFrame | Series:\n\u001b[32m 4968\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 4969\u001b[39m \u001b[33;03m Invoke function on values of Series.\u001b[39;00m\n\u001b[32m 4970\u001b[39m \n\u001b[32m (...)\u001b[39m\u001b[32m 5076\u001b[39m \u001b[33;03m dtype: float64\u001b[39;00m\n\u001b[32m 5077\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m 5078\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mSeriesApply\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 5079\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 5080\u001b[39m \u001b[43m \u001b[49m\u001b[43mfunc\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 5081\u001b[39m \u001b[43m \u001b[49m\u001b[43mby_row\u001b[49m\u001b[43m=\u001b[49m\u001b[43mby_row\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 5082\u001b[39m \u001b[43m \u001b[49m\u001b[43margs\u001b[49m\u001b[43m=\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 5083\u001b[39m \u001b[43m \u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m=\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m-> \u001b[39m\u001b[32m5084\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[43mapply\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~/.local/lib/python3.14/site-packages/pandas/core/apply.py:1520\u001b[39m, in \u001b[36mSeriesApply.apply\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 1517\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.apply_compat()\n\u001b[32m 1519\u001b[39m \u001b[38;5;66;03m# self.func is Callable\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1520\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mapply_standard\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~/.local/lib/python3.14/site-packages/pandas/core/apply.py:1578\u001b[39m, in \u001b[36mSeriesApply.apply_standard\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 1576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1577\u001b[39m curried = func\n\u001b[32m-> \u001b[39m\u001b[32m1578\u001b[39m mapped = \u001b[43mobj\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_map_values\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmapper\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcurried\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1580\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(mapped) \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(mapped[\u001b[32m0\u001b[39m], ABCSeries):\n\u001b[32m 1581\u001b[39m \u001b[38;5;66;03m# GH#43986 Need to do list(mapped) in order to get treated as nested\u001b[39;00m\n\u001b[32m 1582\u001b[39m \u001b[38;5;66;03m# See also GH#25959 regarding EA support\u001b[39;00m\n\u001b[32m 1583\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m obj._constructor_expanddim(\u001b[38;5;28mlist\u001b[39m(mapped), index=obj.index)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~/.local/lib/python3.14/site-packages/pandas/core/base.py:1022\u001b[39m, in \u001b[36mIndexOpsMixin._map_values\u001b[39m\u001b[34m(self, mapper, na_action)\u001b[39m\n\u001b[32m 1019\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(arr, ExtensionArray):\n\u001b[32m 1020\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m arr.map(mapper, na_action=na_action)\n\u001b[32m-> \u001b[39m\u001b[32m1022\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43malgorithms\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmap_array\u001b[49m\u001b[43m(\u001b[49m\u001b[43marr\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmapper\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mna_action\u001b[49m\u001b[43m=\u001b[49m\u001b[43mna_action\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~/.local/lib/python3.14/site-packages/pandas/core/algorithms.py:1710\u001b[39m, in \u001b[36mmap_array\u001b[39m\u001b[34m(arr, mapper, na_action)\u001b[39m\n\u001b[32m 1708\u001b[39m values = arr.astype(\u001b[38;5;28mobject\u001b[39m, copy=\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[32m 1709\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m na_action \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1710\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mlib\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmap_infer\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvalues\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmapper\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1711\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1712\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m lib.map_infer_mask(values, mapper, mask=isna(values).view(np.uint8))\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mpandas/_libs/lib.pyx:3071\u001b[39m, in \u001b[36mpandas._libs.lib.map_infer\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m-> \u001b[39m\u001b[32m3071\u001b[39m \u001b[33m'Could not get source, probably due dynamically evaluated source code.'\u001b[39m\n",
|
||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[24]\u001b[39m\u001b[32m, line 17\u001b[39m, in \u001b[36mconvertSpecies\u001b[39m\u001b[34m(species_name)\u001b[39m\n\u001b[32m 14\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m convertSpecies(species_name: str) -> int:\n\u001b[32m 15\u001b[39m \u001b[33m''' return the species index (a unique integer/category) '''\u001b[39m\n\u001b[32m 16\u001b[39m \u001b[38;5;66;03m#print(f\"converting {species_name}...\")\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m17\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m species_name_to_index[species_name]\n",
|
||
"\u001b[31mKeyError\u001b[39m: 0"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"##########################################\n",
|
||
"# BLOCK 12: USING DF'S .apply\n",
|
||
"##########################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# we can \"apply\" our new convertSpecies function to a whole column\n",
|
||
"#\n",
|
||
"# (The following will issue a \"SettingWithCopyWarning\" here...)\n",
|
||
"# see https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
||
"#\n",
|
||
"# >>> ADD CODE HERE TO KEEP THE WARNING FROM HAPPENING <<<\n",
|
||
"\n",
|
||
"df_final['irisname'] = df_final['irisname'].apply(convertSpecies)\n",
|
||
"#df_final.loc[:, 'irisname'] = df_final['irisname'].apply(convertSpecies)\n",
|
||
"# Don't run this twice! Why?! What's \"KeyError: 0\"?\n",
|
||
"# (of course, you can always go back and re-establish definitions of df_final)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 29,
|
||
"metadata": {
|
||
"id": "tWoVKJBGKPR_"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"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>sepallen</th>\n",
|
||
" <th>sepalwid</th>\n",
|
||
" <th>petallen</th>\n",
|
||
" <th>petalwid</th>\n",
|
||
" <th>irisname</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>4.9</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>0</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>4.7</td>\n",
|
||
" <td>3.2</td>\n",
|
||
" <td>1.3</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>0</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>4.6</td>\n",
|
||
" <td>3.1</td>\n",
|
||
" <td>1.5</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>0</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>4</th>\n",
|
||
" <td>5.0</td>\n",
|
||
" <td>3.6</td>\n",
|
||
" <td>1.4</td>\n",
|
||
" <td>0.2</td>\n",
|
||
" <td>0</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>...</th>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>144</th>\n",
|
||
" <td>6.7</td>\n",
|
||
" <td>3.3</td>\n",
|
||
" <td>5.7</td>\n",
|
||
" <td>2.5</td>\n",
|
||
" <td>2</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>145</th>\n",
|
||
" <td>6.7</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>5.2</td>\n",
|
||
" <td>2.3</td>\n",
|
||
" <td>2</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>146</th>\n",
|
||
" <td>6.3</td>\n",
|
||
" <td>2.5</td>\n",
|
||
" <td>5.0</td>\n",
|
||
" <td>1.9</td>\n",
|
||
" <td>2</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>147</th>\n",
|
||
" <td>6.5</td>\n",
|
||
" <td>3.0</td>\n",
|
||
" <td>5.2</td>\n",
|
||
" <td>2.0</td>\n",
|
||
" <td>2</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"<p>145 rows × 5 columns</p>\n",
|
||
"</div>"
|
||
],
|
||
"text/plain": [
|
||
" sepallen sepalwid petallen petalwid irisname\n",
|
||
"1 4.9 3.0 1.4 0.2 0\n",
|
||
"2 4.7 3.2 1.3 0.2 0\n",
|
||
"3 4.6 3.1 1.5 0.2 0\n",
|
||
"4 5.0 3.6 1.4 0.2 0\n",
|
||
".. ... ... ... ... ...\n",
|
||
"144 6.7 3.3 5.7 2.5 2\n",
|
||
"145 6.7 3.0 5.2 2.3 2\n",
|
||
"146 6.3 2.5 5.0 1.9 2\n",
|
||
"147 6.5 3.0 5.2 2.0 2\n",
|
||
"\n",
|
||
"[145 rows x 5 columns]"
|
||
]
|
||
},
|
||
"execution_count": 29,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"##########################################\n",
|
||
"# BLOCK 13: CONFIRMING FINAL DATAFRAME\n",
|
||
"##########################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# let's see it! (this is safe to run many times...)\n",
|
||
"#\n",
|
||
"df_final # print(df_final.tostring()) # for _all_ rows..."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 30,
|
||
"metadata": {
|
||
"id": "qxpBs7NnKPR_"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"type of A: <class 'numpy.ndarray'>\n",
|
||
" sepallen sepalwid petallen petalwid irisname\n",
|
||
"1 4.9 3.0 1.4 0.2 0\n",
|
||
"2 4.7 3.2 1.3 0.2 0\n",
|
||
"3 4.6 3.1 1.5 0.2 0\n",
|
||
"4 5.0 3.6 1.4 0.2 0\n",
|
||
"5 5.4 3.9 1.7 0.4 0\n",
|
||
"A[0] = [4.9 3. 1.4 0.2 0. ]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"##########################################\n",
|
||
"# BLOCK 14: CONVERTING TO NUMPY FORMAT\n",
|
||
"##########################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# let's convert our dataframe to a numpy array, named A\n",
|
||
"# Our ML library, scikit-learn operates entirely on numpy arrays.\n",
|
||
"#\n",
|
||
"#A = df_final.values\n",
|
||
"A = df_final.to_numpy() # better -- self-documenting!\n",
|
||
"\n",
|
||
"print(f\"type of A: {type(A)}\")\n",
|
||
"print(df_final.head())\n",
|
||
"print(f\"A[0] = {A[0]}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 31,
|
||
"metadata": {
|
||
"id": "bblbBuIiKPSA"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"array([[4.9, 3. , 1.4, 0.2, 0. ],\n",
|
||
" [4.7, 3.2, 1.3, 0.2, 0. ],\n",
|
||
" [4.6, 3.1, 1.5, 0.2, 0. ],\n",
|
||
" [5. , 3.6, 1.4, 0.2, 0. ],\n",
|
||
" [5.4, 3.9, 1.7, 0.4, 0. ],\n",
|
||
" [4.6, 3.4, 1.4, 0.3, 0. ],\n",
|
||
" [4.4, 2.9, 1.4, 0.2, 0. ],\n",
|
||
" [4.9, 3.1, 1.5, 0.1, 0. ],\n",
|
||
" [5.4, 3.7, 1.5, 0.2, 0. ],\n",
|
||
" [4.8, 3.4, 1.6, 0.2, 0. ],\n",
|
||
" [4.8, 3. , 1.4, 0.1, 0. ],\n",
|
||
" [4.3, 3. , 1.1, 0.1, 0. ],\n",
|
||
" [5.8, 4. , 1.2, 0.2, 0. ],\n",
|
||
" [5.7, 4.4, 1.5, 0.4, 0. ],\n",
|
||
" [5.4, 3.9, 1.3, 0.4, 0. ],\n",
|
||
" [5.1, 3.5, 1.4, 0.3, 0. ],\n",
|
||
" [5.7, 3.8, 1.7, 0.3, 0. ],\n",
|
||
" [5.1, 3.8, 1.5, 0.3, 0. ],\n",
|
||
" [5.4, 3.4, 1.7, 0.2, 0. ],\n",
|
||
" [5.1, 3.7, 1.5, 0.4, 0. ],\n",
|
||
" [4.6, 3.6, 1. , 0.2, 0. ],\n",
|
||
" [5.1, 3.3, 1.7, 0.5, 0. ],\n",
|
||
" [4.8, 3.4, 1.9, 0.2, 0. ],\n",
|
||
" [5. , 3.4, 1.6, 0.4, 0. ],\n",
|
||
" [5.2, 3.5, 1.5, 0.2, 0. ],\n",
|
||
" [5.2, 3.4, 1.4, 0.2, 0. ],\n",
|
||
" [4.7, 3.2, 1.6, 0.2, 0. ],\n",
|
||
" [4.8, 3.1, 1.6, 0.2, 0. ],\n",
|
||
" [5.4, 3.4, 1.5, 0.4, 0. ],\n",
|
||
" [5.2, 4.1, 1.5, 0.1, 0. ],\n",
|
||
" [5.5, 4.2, 1.4, 0.2, 0. ],\n",
|
||
" [4.9, 3.1, 1.5, 0.2, 0. ],\n",
|
||
" [5. , 3.2, 1.2, 0.2, 0. ],\n",
|
||
" [5.5, 3.5, 1.3, 0.2, 0. ],\n",
|
||
" [4.9, 3.6, 1.4, 0.1, 0. ],\n",
|
||
" [4.4, 3. , 1.3, 0.2, 0. ],\n",
|
||
" [5.1, 3.4, 1.5, 0.2, 0. ],\n",
|
||
" [5. , 3.5, 1.3, 0.3, 0. ],\n",
|
||
" [4.5, 2.3, 1.3, 0.3, 0. ],\n",
|
||
" [4.4, 3.2, 1.3, 0.2, 0. ],\n",
|
||
" [5. , 3.5, 1.6, 0.6, 0. ],\n",
|
||
" [5.1, 3.8, 1.9, 0.4, 0. ],\n",
|
||
" [4.8, 3. , 1.4, 0.3, 0. ],\n",
|
||
" [5.1, 3.8, 1.6, 0.2, 0. ],\n",
|
||
" [4.6, 3.2, 1.4, 0.2, 0. ],\n",
|
||
" [5.3, 3.7, 1.5, 0.2, 0. ],\n",
|
||
" [5. , 3.3, 1.4, 0.2, 0. ],\n",
|
||
" [7. , 3.2, 4.7, 1.4, 1. ],\n",
|
||
" [6.4, 3.2, 4.5, 1.5, 1. ],\n",
|
||
" [6.9, 3.1, 4.9, 1.5, 1. ],\n",
|
||
" [5.5, 2.3, 4. , 1.3, 1. ],\n",
|
||
" [6.5, 2.8, 4.6, 1.5, 1. ],\n",
|
||
" [5.7, 2.8, 4.5, 1.3, 1. ],\n",
|
||
" [6.3, 3.3, 4.7, 1.6, 1. ],\n",
|
||
" [4.9, 2.4, 3.3, 1. , 1. ],\n",
|
||
" [6.6, 2.9, 4.6, 1.3, 1. ],\n",
|
||
" [5.2, 2.7, 3.9, 1.4, 1. ],\n",
|
||
" [5. , 2. , 3.5, 1. , 1. ],\n",
|
||
" [5.9, 3. , 4.2, 1.5, 1. ],\n",
|
||
" [6. , 2.2, 4. , 1. , 1. ],\n",
|
||
" [6.1, 2.9, 4.7, 1.4, 1. ],\n",
|
||
" [5.6, 2.9, 3.6, 1.3, 1. ],\n",
|
||
" [6.7, 3.1, 4.4, 1.4, 1. ],\n",
|
||
" [5.6, 3. , 4.5, 1.5, 1. ],\n",
|
||
" [5.8, 2.7, 4.1, 1. , 1. ],\n",
|
||
" [6.2, 2.2, 4.5, 1.5, 1. ],\n",
|
||
" [5.6, 2.5, 3.9, 1.1, 1. ],\n",
|
||
" [5.9, 3.2, 4.8, 1.8, 1. ],\n",
|
||
" [6.1, 2.8, 4. , 1.3, 1. ],\n",
|
||
" [6.3, 2.5, 4.9, 1.5, 1. ],\n",
|
||
" [6.1, 2.8, 4.7, 1.2, 1. ],\n",
|
||
" [6.4, 2.9, 4.3, 1.3, 1. ],\n",
|
||
" [6.6, 3. , 4.4, 1.4, 1. ],\n",
|
||
" [6.8, 2.8, 4.8, 1.4, 1. ],\n",
|
||
" [6.7, 3. , 5. , 1.7, 1. ],\n",
|
||
" [6. , 2.9, 4.5, 1.5, 1. ],\n",
|
||
" [5.7, 2.6, 3.5, 1. , 1. ],\n",
|
||
" [5.5, 2.4, 3.8, 1.1, 1. ],\n",
|
||
" [5.5, 2.4, 3.7, 1. , 1. ],\n",
|
||
" [5.8, 2.7, 3.9, 1.2, 1. ],\n",
|
||
" [6. , 2.7, 5.1, 1.6, 1. ],\n",
|
||
" [5.4, 3. , 4.5, 1.5, 1. ],\n",
|
||
" [6. , 3.4, 4.5, 1.6, 1. ],\n",
|
||
" [6.7, 3.1, 4.7, 1.5, 1. ],\n",
|
||
" [6.3, 2.3, 4.4, 1.3, 1. ],\n",
|
||
" [5.6, 3. , 4.1, 1.3, 1. ],\n",
|
||
" [5.5, 2.5, 4. , 1.3, 1. ],\n",
|
||
" [5.5, 2.6, 4.4, 1.2, 1. ],\n",
|
||
" [6.1, 3. , 4.6, 1.4, 1. ],\n",
|
||
" [5.8, 2.6, 4. , 1.2, 1. ],\n",
|
||
" [5. , 2.3, 3.3, 1. , 1. ],\n",
|
||
" [5.6, 2.7, 4.2, 1.3, 1. ],\n",
|
||
" [5.7, 3. , 4.2, 1.2, 1. ],\n",
|
||
" [5.7, 2.9, 4.2, 1.3, 1. ],\n",
|
||
" [6.2, 2.9, 4.3, 1.3, 1. ],\n",
|
||
" [5.1, 2.5, 3. , 1.1, 1. ],\n",
|
||
" [5.7, 2.8, 4.1, 1.3, 1. ],\n",
|
||
" [6.3, 3.3, 6. , 2.5, 2. ],\n",
|
||
" [5.8, 2.7, 5.1, 1.9, 2. ],\n",
|
||
" [7.1, 3. , 5.9, 2.1, 2. ],\n",
|
||
" [6.3, 2.9, 5.6, 1.8, 2. ],\n",
|
||
" [6.5, 3. , 5.8, 2.2, 2. ],\n",
|
||
" [7.6, 3. , 6.6, 2.1, 2. ],\n",
|
||
" [4.9, 2.5, 4.5, 1.7, 2. ],\n",
|
||
" [7.3, 2.9, 6.3, 1.8, 2. ],\n",
|
||
" [6.7, 2.5, 5.8, 1.8, 2. ],\n",
|
||
" [7.2, 3.6, 6.1, 2.5, 2. ],\n",
|
||
" [6.5, 3.2, 5.1, 2. , 2. ],\n",
|
||
" [6.4, 2.7, 5.3, 1.9, 2. ],\n",
|
||
" [6.8, 3. , 5.5, 2.1, 2. ],\n",
|
||
" [5.7, 2.5, 5. , 2. , 2. ],\n",
|
||
" [5.8, 2.8, 5.1, 2.4, 2. ],\n",
|
||
" [6.4, 3.2, 5.3, 2.3, 2. ],\n",
|
||
" [6.5, 3. , 5.5, 1.8, 2. ],\n",
|
||
" [7.7, 3.8, 6.7, 2.2, 2. ],\n",
|
||
" [7.7, 2.6, 6.9, 2.3, 2. ],\n",
|
||
" [6. , 2.2, 5. , 1.5, 2. ],\n",
|
||
" [6.9, 3.2, 5.7, 2.3, 2. ],\n",
|
||
" [5.6, 2.8, 4.9, 2. , 2. ],\n",
|
||
" [7.7, 2.8, 6.7, 2. , 2. ],\n",
|
||
" [6.3, 2.7, 4.9, 1.8, 2. ],\n",
|
||
" [6.7, 3.3, 5.7, 2.1, 2. ],\n",
|
||
" [7.2, 3.2, 6. , 1.8, 2. ],\n",
|
||
" [6.2, 2.8, 4.8, 1.8, 2. ],\n",
|
||
" [6.1, 3. , 4.9, 1.8, 2. ],\n",
|
||
" [6.4, 2.8, 5.6, 2.1, 2. ],\n",
|
||
" [7.2, 3. , 5.8, 1.6, 2. ],\n",
|
||
" [7.4, 2.8, 6.1, 1.9, 2. ],\n",
|
||
" [7.9, 3.8, 6.4, 2. , 2. ],\n",
|
||
" [6.4, 2.8, 5.6, 2.2, 2. ],\n",
|
||
" [6.3, 2.8, 5.1, 1.5, 2. ],\n",
|
||
" [6.1, 2.6, 5.6, 1.4, 2. ],\n",
|
||
" [7.7, 3. , 6.1, 2.3, 2. ],\n",
|
||
" [6.3, 3.4, 5.6, 2.4, 2. ],\n",
|
||
" [6.4, 3.1, 5.5, 1.8, 2. ],\n",
|
||
" [6. , 3. , 4.8, 1.8, 2. ],\n",
|
||
" [6.9, 3.1, 5.4, 2.1, 2. ],\n",
|
||
" [6.7, 3.1, 5.6, 2.4, 2. ],\n",
|
||
" [6.9, 3.1, 5.1, 2.3, 2. ],\n",
|
||
" [5.8, 2.7, 5.1, 1.9, 2. ],\n",
|
||
" [6.8, 3.2, 5.9, 2.3, 2. ],\n",
|
||
" [6.7, 3.3, 5.7, 2.5, 2. ],\n",
|
||
" [6.7, 3. , 5.2, 2.3, 2. ],\n",
|
||
" [6.3, 2.5, 5. , 1.9, 2. ],\n",
|
||
" [6.5, 3. , 5.2, 2. , 2. ]])"
|
||
]
|
||
},
|
||
"execution_count": 31,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"##################################################\n",
|
||
"# BLOCK 15: CONVERTING NUMPY ARRAY TO ALL FLOATS\n",
|
||
"##################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# let's convert to make sure it's all floating-point, so we can multiply and divide\n",
|
||
"#\n",
|
||
"A = A.astype('float64') # so many: www.tutorialspoint.com/numpy/numpy_data_types.htm\n",
|
||
"A"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 32,
|
||
"metadata": {
|
||
"id": "wbns1qpJKPSA"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"\n",
|
||
"The dataset has 145 rows and 5 cols\n",
|
||
"[[4.9 3. 1.4 0.2 0. ]\n",
|
||
" [4.7 3.2 1.3 0.2 0. ]\n",
|
||
" [4.6 3.1 1.5 0.2 0. ]\n",
|
||
" [5. 3.6 1.4 0.2 0. ]\n",
|
||
" [5.4 3.9 1.7 0.4 0. ]\n",
|
||
" [4.6 3.4 1.4 0.3 0. ]\n",
|
||
" [4.4 2.9 1.4 0.2 0. ]\n",
|
||
" [4.9 3.1 1.5 0.1 0. ]\n",
|
||
" [5.4 3.7 1.5 0.2 0. ]\n",
|
||
" [4.8 3.4 1.6 0.2 0. ]\n",
|
||
" [4.8 3. 1.4 0.1 0. ]\n",
|
||
" [4.3 3. 1.1 0.1 0. ]\n",
|
||
" [5.8 4. 1.2 0.2 0. ]\n",
|
||
" [5.7 4.4 1.5 0.4 0. ]\n",
|
||
" [5.4 3.9 1.3 0.4 0. ]\n",
|
||
" [5.1 3.5 1.4 0.3 0. ]\n",
|
||
" [5.7 3.8 1.7 0.3 0. ]\n",
|
||
" [5.1 3.8 1.5 0.3 0. ]\n",
|
||
" [5.4 3.4 1.7 0.2 0. ]\n",
|
||
" [5.1 3.7 1.5 0.4 0. ]\n",
|
||
" [4.6 3.6 1. 0.2 0. ]\n",
|
||
" [5.1 3.3 1.7 0.5 0. ]\n",
|
||
" [4.8 3.4 1.9 0.2 0. ]\n",
|
||
" [5. 3.4 1.6 0.4 0. ]\n",
|
||
" [5.2 3.5 1.5 0.2 0. ]\n",
|
||
" [5.2 3.4 1.4 0.2 0. ]\n",
|
||
" [4.7 3.2 1.6 0.2 0. ]\n",
|
||
" [4.8 3.1 1.6 0.2 0. ]\n",
|
||
" [5.4 3.4 1.5 0.4 0. ]\n",
|
||
" [5.2 4.1 1.5 0.1 0. ]\n",
|
||
" [5.5 4.2 1.4 0.2 0. ]\n",
|
||
" [4.9 3.1 1.5 0.2 0. ]\n",
|
||
" [5. 3.2 1.2 0.2 0. ]\n",
|
||
" [5.5 3.5 1.3 0.2 0. ]\n",
|
||
" [4.9 3.6 1.4 0.1 0. ]\n",
|
||
" [4.4 3. 1.3 0.2 0. ]\n",
|
||
" [5.1 3.4 1.5 0.2 0. ]\n",
|
||
" [5. 3.5 1.3 0.3 0. ]\n",
|
||
" [4.5 2.3 1.3 0.3 0. ]\n",
|
||
" [4.4 3.2 1.3 0.2 0. ]\n",
|
||
" [5. 3.5 1.6 0.6 0. ]\n",
|
||
" [5.1 3.8 1.9 0.4 0. ]\n",
|
||
" [4.8 3. 1.4 0.3 0. ]\n",
|
||
" [5.1 3.8 1.6 0.2 0. ]\n",
|
||
" [4.6 3.2 1.4 0.2 0. ]\n",
|
||
" [5.3 3.7 1.5 0.2 0. ]\n",
|
||
" [5. 3.3 1.4 0.2 0. ]\n",
|
||
" [7. 3.2 4.7 1.4 1. ]\n",
|
||
" [6.4 3.2 4.5 1.5 1. ]\n",
|
||
" [6.9 3.1 4.9 1.5 1. ]\n",
|
||
" [5.5 2.3 4. 1.3 1. ]\n",
|
||
" [6.5 2.8 4.6 1.5 1. ]\n",
|
||
" [5.7 2.8 4.5 1.3 1. ]\n",
|
||
" [6.3 3.3 4.7 1.6 1. ]\n",
|
||
" [4.9 2.4 3.3 1. 1. ]\n",
|
||
" [6.6 2.9 4.6 1.3 1. ]\n",
|
||
" [5.2 2.7 3.9 1.4 1. ]\n",
|
||
" [5. 2. 3.5 1. 1. ]\n",
|
||
" [5.9 3. 4.2 1.5 1. ]\n",
|
||
" [6. 2.2 4. 1. 1. ]\n",
|
||
" [6.1 2.9 4.7 1.4 1. ]\n",
|
||
" [5.6 2.9 3.6 1.3 1. ]\n",
|
||
" [6.7 3.1 4.4 1.4 1. ]\n",
|
||
" [5.6 3. 4.5 1.5 1. ]\n",
|
||
" [5.8 2.7 4.1 1. 1. ]\n",
|
||
" [6.2 2.2 4.5 1.5 1. ]\n",
|
||
" [5.6 2.5 3.9 1.1 1. ]\n",
|
||
" [5.9 3.2 4.8 1.8 1. ]\n",
|
||
" [6.1 2.8 4. 1.3 1. ]\n",
|
||
" [6.3 2.5 4.9 1.5 1. ]\n",
|
||
" [6.1 2.8 4.7 1.2 1. ]\n",
|
||
" [6.4 2.9 4.3 1.3 1. ]\n",
|
||
" [6.6 3. 4.4 1.4 1. ]\n",
|
||
" [6.8 2.8 4.8 1.4 1. ]\n",
|
||
" [6.7 3. 5. 1.7 1. ]\n",
|
||
" [6. 2.9 4.5 1.5 1. ]\n",
|
||
" [5.7 2.6 3.5 1. 1. ]\n",
|
||
" [5.5 2.4 3.8 1.1 1. ]\n",
|
||
" [5.5 2.4 3.7 1. 1. ]\n",
|
||
" [5.8 2.7 3.9 1.2 1. ]\n",
|
||
" [6. 2.7 5.1 1.6 1. ]\n",
|
||
" [5.4 3. 4.5 1.5 1. ]\n",
|
||
" [6. 3.4 4.5 1.6 1. ]\n",
|
||
" [6.7 3.1 4.7 1.5 1. ]\n",
|
||
" [6.3 2.3 4.4 1.3 1. ]\n",
|
||
" [5.6 3. 4.1 1.3 1. ]\n",
|
||
" [5.5 2.5 4. 1.3 1. ]\n",
|
||
" [5.5 2.6 4.4 1.2 1. ]\n",
|
||
" [6.1 3. 4.6 1.4 1. ]\n",
|
||
" [5.8 2.6 4. 1.2 1. ]\n",
|
||
" [5. 2.3 3.3 1. 1. ]\n",
|
||
" [5.6 2.7 4.2 1.3 1. ]\n",
|
||
" [5.7 3. 4.2 1.2 1. ]\n",
|
||
" [5.7 2.9 4.2 1.3 1. ]\n",
|
||
" [6.2 2.9 4.3 1.3 1. ]\n",
|
||
" [5.1 2.5 3. 1.1 1. ]\n",
|
||
" [5.7 2.8 4.1 1.3 1. ]\n",
|
||
" [6.3 3.3 6. 2.5 2. ]\n",
|
||
" [5.8 2.7 5.1 1.9 2. ]\n",
|
||
" [7.1 3. 5.9 2.1 2. ]\n",
|
||
" [6.3 2.9 5.6 1.8 2. ]\n",
|
||
" [6.5 3. 5.8 2.2 2. ]\n",
|
||
" [7.6 3. 6.6 2.1 2. ]\n",
|
||
" [4.9 2.5 4.5 1.7 2. ]\n",
|
||
" [7.3 2.9 6.3 1.8 2. ]\n",
|
||
" [6.7 2.5 5.8 1.8 2. ]\n",
|
||
" [7.2 3.6 6.1 2.5 2. ]\n",
|
||
" [6.5 3.2 5.1 2. 2. ]\n",
|
||
" [6.4 2.7 5.3 1.9 2. ]\n",
|
||
" [6.8 3. 5.5 2.1 2. ]\n",
|
||
" [5.7 2.5 5. 2. 2. ]\n",
|
||
" [5.8 2.8 5.1 2.4 2. ]\n",
|
||
" [6.4 3.2 5.3 2.3 2. ]\n",
|
||
" [6.5 3. 5.5 1.8 2. ]\n",
|
||
" [7.7 3.8 6.7 2.2 2. ]\n",
|
||
" [7.7 2.6 6.9 2.3 2. ]\n",
|
||
" [6. 2.2 5. 1.5 2. ]\n",
|
||
" [6.9 3.2 5.7 2.3 2. ]\n",
|
||
" [5.6 2.8 4.9 2. 2. ]\n",
|
||
" [7.7 2.8 6.7 2. 2. ]\n",
|
||
" [6.3 2.7 4.9 1.8 2. ]\n",
|
||
" [6.7 3.3 5.7 2.1 2. ]\n",
|
||
" [7.2 3.2 6. 1.8 2. ]\n",
|
||
" [6.2 2.8 4.8 1.8 2. ]\n",
|
||
" [6.1 3. 4.9 1.8 2. ]\n",
|
||
" [6.4 2.8 5.6 2.1 2. ]\n",
|
||
" [7.2 3. 5.8 1.6 2. ]\n",
|
||
" [7.4 2.8 6.1 1.9 2. ]\n",
|
||
" [7.9 3.8 6.4 2. 2. ]\n",
|
||
" [6.4 2.8 5.6 2.2 2. ]\n",
|
||
" [6.3 2.8 5.1 1.5 2. ]\n",
|
||
" [6.1 2.6 5.6 1.4 2. ]\n",
|
||
" [7.7 3. 6.1 2.3 2. ]\n",
|
||
" [6.3 3.4 5.6 2.4 2. ]\n",
|
||
" [6.4 3.1 5.5 1.8 2. ]\n",
|
||
" [6. 3. 4.8 1.8 2. ]\n",
|
||
" [6.9 3.1 5.4 2.1 2. ]\n",
|
||
" [6.7 3.1 5.6 2.4 2. ]\n",
|
||
" [6.9 3.1 5.1 2.3 2. ]\n",
|
||
" [5.8 2.7 5.1 1.9 2. ]\n",
|
||
" [6.8 3.2 5.9 2.3 2. ]\n",
|
||
" [6.7 3.3 5.7 2.5 2. ]\n",
|
||
" [6.7 3. 5.2 2.3 2. ]\n",
|
||
" [6.3 2.5 5. 1.9 2. ]\n",
|
||
" [6.5 3. 5.2 2. 2. ]]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"##########################################\n",
|
||
"# BLOCK 16: USING NUMPY'S .shape\n",
|
||
"##########################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# nice to have num_rows and num_cols variables handy...\n",
|
||
"#\n",
|
||
"num_rows, num_cols = A.shape\n",
|
||
"print(f\"\\nThe dataset has {num_rows} rows and {num_cols} cols\")\n",
|
||
"print(A)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 33,
|
||
"metadata": {
|
||
"id": "ixiZhsuqKPSA",
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"flower #132 data is [7.7 3. 6.1 2.3 2. ]\n",
|
||
" Its sepallen is 7.7\n",
|
||
" Its sepalwid is 3.0\n",
|
||
" Its petallen is 6.1\n",
|
||
" Its petalwid is 2.3\n",
|
||
" Its irisname is virginica (2)\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"##########################################\n",
|
||
"# BLOCK 17: PRINTING FLOWER INFO\n",
|
||
"##########################################\n",
|
||
"\n",
|
||
"# let's use all of our previously-defined variables, to reinforce names...\n",
|
||
"\n",
|
||
"# choose a row index (particular flower) arbitrarily:\n",
|
||
"flower = 132\n",
|
||
"print(f\"flower #{flower} data is {A[flower]}\")\n",
|
||
"\n",
|
||
"for i in range(len(features)):\n",
|
||
" col_name = features[i]\n",
|
||
" if col_name != 'irisname':\n",
|
||
" print(f\" Its {col_name} is {A[flower][i]}\")\n",
|
||
" else:\n",
|
||
" species_num = int(A[flower][i])\n",
|
||
" species_name = species_names[species_num]\n",
|
||
" print(f\" Its {col_name} is {species_name} ({species_num})\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 34,
|
||
"metadata": {
|
||
"id": "izGld2tSKPSA"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"I predict versicolor (1) from features [4.6, 3.6, 3.0, 1.2]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"##########################################\n",
|
||
"# BLOCK 18: WRITING OUR OWN 1-NN FUNCTION\n",
|
||
"##########################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# We don't have to use scikit-learn to implement NN!\n",
|
||
"#\n",
|
||
"\n",
|
||
"#\n",
|
||
"# data-driven predictive model (1-nearest-neighbor)\n",
|
||
"#\n",
|
||
"\n",
|
||
"# Python functions are first-class objects!\n",
|
||
"dist = np.linalg.norm # built in to numpy... but what does norm do?\n",
|
||
"\n",
|
||
"num_rows, num_cols = A.shape # data size\n",
|
||
"\n",
|
||
"def predictiveModel( features: list[float] ) -> str:\n",
|
||
" \"\"\" input: a list of four features\n",
|
||
" [ sepallen, sepalwid, petallen, petalwid ]\n",
|
||
" output: the predicted species of iris, from\n",
|
||
" setosa (0), versicolor (1), virginica (2)\n",
|
||
" \"\"\"\n",
|
||
" our_features = np.asarray(features) # make a numpy array\n",
|
||
"\n",
|
||
" closest_flower = A[0]\n",
|
||
" closest_features = A[0,0:4]\n",
|
||
" closest_distance = dist(our_features - closest_features)\n",
|
||
"\n",
|
||
" for i in range(1, num_rows, 1):\n",
|
||
" current_flower = A[i]\n",
|
||
" current_features = A[i,0:4]\n",
|
||
" current_distance = dist(our_features - current_features)\n",
|
||
"\n",
|
||
" if current_distance < closest_distance:\n",
|
||
" closest_distance = current_distance # remember closest!\n",
|
||
" closest_flower = current_flower\n",
|
||
"\n",
|
||
" # done comparing with every flower in the dataset\n",
|
||
" predicted_species = int(round(closest_flower[4])) # what type is closest_flower?\n",
|
||
" name = species_names[predicted_species]\n",
|
||
" return f\"{name} ({predicted_species})\"\n",
|
||
"\n",
|
||
"#\n",
|
||
"# Try it!\n",
|
||
"#\n",
|
||
"# features = eval(input(\"Enter new features: \"))\n",
|
||
"#\n",
|
||
"features = [ 4.6, 3.6, 3.0, 1.2 ]\n",
|
||
"result = predictiveModel( features )\n",
|
||
"print(f\"I predict {result} from features {features}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 35,
|
||
"metadata": {
|
||
"id": "9nhDlGbRKPSB"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"##########################################\n",
|
||
"# BLOCK 19: COMMENTS ON SCIKIT-LEARN kNN\n",
|
||
"##########################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# but, we don't have to write our own ... because\n",
|
||
"#\n",
|
||
"# we want knn for any k (not just k=1 as above)\n",
|
||
"# we want an already-debugged algorithm!\n",
|
||
"# we want to ask iris-related questions instead of implementation ones...\n",
|
||
"#"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 36,
|
||
"metadata": {
|
||
"id": "64kSAiCvKPSB"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"+++ Start of data definitions +++\n",
|
||
"\n",
|
||
"X_all (just features) is \n",
|
||
" [[4.9 3. 1.4 0.2]\n",
|
||
" [4.7 3.2 1.3 0.2]\n",
|
||
" [4.6 3.1 1.5 0.2]\n",
|
||
" [5. 3.6 1.4 0.2]\n",
|
||
" [5.4 3.9 1.7 0.4]\n",
|
||
" [4.6 3.4 1.4 0.3]\n",
|
||
" [4.4 2.9 1.4 0.2]\n",
|
||
" [4.9 3.1 1.5 0.1]\n",
|
||
" [5.4 3.7 1.5 0.2]\n",
|
||
" [4.8 3.4 1.6 0.2]\n",
|
||
" [4.8 3. 1.4 0.1]\n",
|
||
" [4.3 3. 1.1 0.1]\n",
|
||
" [5.8 4. 1.2 0.2]\n",
|
||
" [5.7 4.4 1.5 0.4]\n",
|
||
" [5.4 3.9 1.3 0.4]\n",
|
||
" [5.1 3.5 1.4 0.3]\n",
|
||
" [5.7 3.8 1.7 0.3]\n",
|
||
" [5.1 3.8 1.5 0.3]\n",
|
||
" [5.4 3.4 1.7 0.2]\n",
|
||
" [5.1 3.7 1.5 0.4]\n",
|
||
" [4.6 3.6 1. 0.2]\n",
|
||
" [5.1 3.3 1.7 0.5]\n",
|
||
" [4.8 3.4 1.9 0.2]\n",
|
||
" [5. 3.4 1.6 0.4]\n",
|
||
" [5.2 3.5 1.5 0.2]\n",
|
||
" [5.2 3.4 1.4 0.2]\n",
|
||
" [4.7 3.2 1.6 0.2]\n",
|
||
" [4.8 3.1 1.6 0.2]\n",
|
||
" [5.4 3.4 1.5 0.4]\n",
|
||
" [5.2 4.1 1.5 0.1]\n",
|
||
" [5.5 4.2 1.4 0.2]\n",
|
||
" [4.9 3.1 1.5 0.2]\n",
|
||
" [5. 3.2 1.2 0.2]\n",
|
||
" [5.5 3.5 1.3 0.2]\n",
|
||
" [4.9 3.6 1.4 0.1]\n",
|
||
" [4.4 3. 1.3 0.2]\n",
|
||
" [5.1 3.4 1.5 0.2]\n",
|
||
" [5. 3.5 1.3 0.3]\n",
|
||
" [4.5 2.3 1.3 0.3]\n",
|
||
" [4.4 3.2 1.3 0.2]\n",
|
||
" [5. 3.5 1.6 0.6]\n",
|
||
" [5.1 3.8 1.9 0.4]\n",
|
||
" [4.8 3. 1.4 0.3]\n",
|
||
" [5.1 3.8 1.6 0.2]\n",
|
||
" [4.6 3.2 1.4 0.2]\n",
|
||
" [5.3 3.7 1.5 0.2]\n",
|
||
" [5. 3.3 1.4 0.2]\n",
|
||
" [7. 3.2 4.7 1.4]\n",
|
||
" [6.4 3.2 4.5 1.5]\n",
|
||
" [6.9 3.1 4.9 1.5]\n",
|
||
" [5.5 2.3 4. 1.3]\n",
|
||
" [6.5 2.8 4.6 1.5]\n",
|
||
" [5.7 2.8 4.5 1.3]\n",
|
||
" [6.3 3.3 4.7 1.6]\n",
|
||
" [4.9 2.4 3.3 1. ]\n",
|
||
" [6.6 2.9 4.6 1.3]\n",
|
||
" [5.2 2.7 3.9 1.4]\n",
|
||
" [5. 2. 3.5 1. ]\n",
|
||
" [5.9 3. 4.2 1.5]\n",
|
||
" [6. 2.2 4. 1. ]\n",
|
||
" [6.1 2.9 4.7 1.4]\n",
|
||
" [5.6 2.9 3.6 1.3]\n",
|
||
" [6.7 3.1 4.4 1.4]\n",
|
||
" [5.6 3. 4.5 1.5]\n",
|
||
" [5.8 2.7 4.1 1. ]\n",
|
||
" [6.2 2.2 4.5 1.5]\n",
|
||
" [5.6 2.5 3.9 1.1]\n",
|
||
" [5.9 3.2 4.8 1.8]\n",
|
||
" [6.1 2.8 4. 1.3]\n",
|
||
" [6.3 2.5 4.9 1.5]\n",
|
||
" [6.1 2.8 4.7 1.2]\n",
|
||
" [6.4 2.9 4.3 1.3]\n",
|
||
" [6.6 3. 4.4 1.4]\n",
|
||
" [6.8 2.8 4.8 1.4]\n",
|
||
" [6.7 3. 5. 1.7]\n",
|
||
" [6. 2.9 4.5 1.5]\n",
|
||
" [5.7 2.6 3.5 1. ]\n",
|
||
" [5.5 2.4 3.8 1.1]\n",
|
||
" [5.5 2.4 3.7 1. ]\n",
|
||
" [5.8 2.7 3.9 1.2]\n",
|
||
" [6. 2.7 5.1 1.6]\n",
|
||
" [5.4 3. 4.5 1.5]\n",
|
||
" [6. 3.4 4.5 1.6]\n",
|
||
" [6.7 3.1 4.7 1.5]\n",
|
||
" [6.3 2.3 4.4 1.3]\n",
|
||
" [5.6 3. 4.1 1.3]\n",
|
||
" [5.5 2.5 4. 1.3]\n",
|
||
" [5.5 2.6 4.4 1.2]\n",
|
||
" [6.1 3. 4.6 1.4]\n",
|
||
" [5.8 2.6 4. 1.2]\n",
|
||
" [5. 2.3 3.3 1. ]\n",
|
||
" [5.6 2.7 4.2 1.3]\n",
|
||
" [5.7 3. 4.2 1.2]\n",
|
||
" [5.7 2.9 4.2 1.3]\n",
|
||
" [6.2 2.9 4.3 1.3]\n",
|
||
" [5.1 2.5 3. 1.1]\n",
|
||
" [5.7 2.8 4.1 1.3]\n",
|
||
" [6.3 3.3 6. 2.5]\n",
|
||
" [5.8 2.7 5.1 1.9]\n",
|
||
" [7.1 3. 5.9 2.1]\n",
|
||
" [6.3 2.9 5.6 1.8]\n",
|
||
" [6.5 3. 5.8 2.2]\n",
|
||
" [7.6 3. 6.6 2.1]\n",
|
||
" [4.9 2.5 4.5 1.7]\n",
|
||
" [7.3 2.9 6.3 1.8]\n",
|
||
" [6.7 2.5 5.8 1.8]\n",
|
||
" [7.2 3.6 6.1 2.5]\n",
|
||
" [6.5 3.2 5.1 2. ]\n",
|
||
" [6.4 2.7 5.3 1.9]\n",
|
||
" [6.8 3. 5.5 2.1]\n",
|
||
" [5.7 2.5 5. 2. ]\n",
|
||
" [5.8 2.8 5.1 2.4]\n",
|
||
" [6.4 3.2 5.3 2.3]\n",
|
||
" [6.5 3. 5.5 1.8]\n",
|
||
" [7.7 3.8 6.7 2.2]\n",
|
||
" [7.7 2.6 6.9 2.3]\n",
|
||
" [6. 2.2 5. 1.5]\n",
|
||
" [6.9 3.2 5.7 2.3]\n",
|
||
" [5.6 2.8 4.9 2. ]\n",
|
||
" [7.7 2.8 6.7 2. ]\n",
|
||
" [6.3 2.7 4.9 1.8]\n",
|
||
" [6.7 3.3 5.7 2.1]\n",
|
||
" [7.2 3.2 6. 1.8]\n",
|
||
" [6.2 2.8 4.8 1.8]\n",
|
||
" [6.1 3. 4.9 1.8]\n",
|
||
" [6.4 2.8 5.6 2.1]\n",
|
||
" [7.2 3. 5.8 1.6]\n",
|
||
" [7.4 2.8 6.1 1.9]\n",
|
||
" [7.9 3.8 6.4 2. ]\n",
|
||
" [6.4 2.8 5.6 2.2]\n",
|
||
" [6.3 2.8 5.1 1.5]\n",
|
||
" [6.1 2.6 5.6 1.4]\n",
|
||
" [7.7 3. 6.1 2.3]\n",
|
||
" [6.3 3.4 5.6 2.4]\n",
|
||
" [6.4 3.1 5.5 1.8]\n",
|
||
" [6. 3. 4.8 1.8]\n",
|
||
" [6.9 3.1 5.4 2.1]\n",
|
||
" [6.7 3.1 5.6 2.4]\n",
|
||
" [6.9 3.1 5.1 2.3]\n",
|
||
" [5.8 2.7 5.1 1.9]\n",
|
||
" [6.8 3.2 5.9 2.3]\n",
|
||
" [6.7 3.3 5.7 2.5]\n",
|
||
" [6.7 3. 5.2 2.3]\n",
|
||
" [6.3 2.5 5. 1.9]\n",
|
||
" [6.5 3. 5.2 2. ]]\n",
|
||
"y_all (just labels) is \n",
|
||
" [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n",
|
||
" 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.\n",
|
||
" 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n",
|
||
" 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n",
|
||
" 1. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.\n",
|
||
" 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.\n",
|
||
" 2.]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 20: DEFINIING FEATURES & LABELS FOR kNN\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"print(\"+++ Start of data definitions +++\\n\")\n",
|
||
"\n",
|
||
"X_all = A[:,0:4] # X (features) ... is all rows, columns 0, 1, 2, 3\n",
|
||
"y_all = A[:,4] # y (labels) ... is all rows, column 4 only\n",
|
||
" # (look back at slide 20)\n",
|
||
"print(f\"X_all (just features) is \\n {X_all}\")\n",
|
||
"print(f\"y_all (just labels) is \\n {y_all}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 37,
|
||
"metadata": {
|
||
"id": "2ChEk2CDKPSC"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Weighting sepallen by 1.0\n",
|
||
"Weighting sepalwid by 1.0\n",
|
||
"Weighting petallen by 1.0\n",
|
||
"Weighting petalwid by 1.0\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 21: REWEIGHTING FEATURES\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# we can re-weight different features here...\n",
|
||
"#\n",
|
||
"\n",
|
||
"col_weights = { # could be called feature weight...\n",
|
||
" 'sepallen':1.0,\n",
|
||
" 'sepalwid':1.0,\n",
|
||
" 'petallen':1.0,\n",
|
||
" 'petalwid':1.0,\n",
|
||
"}\n",
|
||
"\n",
|
||
"for col_name in col_weights:\n",
|
||
" i = feature_name_to_index[col_name] # get the column index, i, of the column name\n",
|
||
" weight = col_weights[col_name] # from the dictionary above\n",
|
||
" print(f\"Weighting {col_name} by {weight}\")\n",
|
||
" # weighting == \"multiplying\"\n",
|
||
" X_all[:,i] *= weight # multiply by the weight to give this column (\"feature\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 38,
|
||
"metadata": {
|
||
"id": "sTDi2mFnKPSC"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"[[7.7 2.6 6.9 2.3]\n",
|
||
" [4.3 3. 1.1 0.1]\n",
|
||
" [5.4 3.7 1.5 0.2]\n",
|
||
" [7.2 3.6 6.1 2.5]\n",
|
||
" [6.3 3.3 6. 2.5]\n",
|
||
" [5.7 2.6 3.5 1. ]\n",
|
||
" [4.8 3.4 1.9 0.2]\n",
|
||
" [6.7 3.1 4.7 1.5]\n",
|
||
" [6.1 3. 4.9 1.8]\n",
|
||
" [6.9 3.1 5.4 2.1]\n",
|
||
" [5.4 3.4 1.7 0.2]\n",
|
||
" [7.3 2.9 6.3 1.8]\n",
|
||
" [6.6 2.9 4.6 1.3]\n",
|
||
" [6.3 2.5 5. 1.9]\n",
|
||
" [5.4 3.9 1.7 0.4]\n",
|
||
" [6.4 3.2 5.3 2.3]\n",
|
||
" [5.5 2.4 3.7 1. ]\n",
|
||
" [5.4 3.4 1.5 0.4]\n",
|
||
" [5.8 2.8 5.1 2.4]\n",
|
||
" [4.6 3.4 1.4 0.3]\n",
|
||
" [7.2 3. 5.8 1.6]\n",
|
||
" [4.6 3.2 1.4 0.2]\n",
|
||
" [6.9 3.1 4.9 1.5]\n",
|
||
" [5.1 3.3 1.7 0.5]\n",
|
||
" [5.3 3.7 1.5 0.2]\n",
|
||
" [5. 3.5 1.6 0.6]\n",
|
||
" [5.6 2.7 4.2 1.3]\n",
|
||
" [6.4 2.7 5.3 1.9]\n",
|
||
" [5.9 3.2 4.8 1.8]\n",
|
||
" [6.7 3.1 4.4 1.4]\n",
|
||
" [4.8 3. 1.4 0.1]\n",
|
||
" [6.3 2.7 4.9 1.8]\n",
|
||
" [5. 3.3 1.4 0.2]\n",
|
||
" [7.4 2.8 6.1 1.9]\n",
|
||
" [4.9 3.1 1.5 0.2]\n",
|
||
" [5.1 3.8 1.9 0.4]\n",
|
||
" [6.9 3.1 5.1 2.3]\n",
|
||
" [5.1 3.5 1.4 0.3]\n",
|
||
" [6.1 2.8 4.7 1.2]\n",
|
||
" [6.8 2.8 4.8 1.4]\n",
|
||
" [4.7 3.2 1.6 0.2]\n",
|
||
" [4.9 3.6 1.4 0.1]\n",
|
||
" [5.2 4.1 1.5 0.1]\n",
|
||
" [5.5 3.5 1.3 0.2]\n",
|
||
" [4.4 3. 1.3 0.2]\n",
|
||
" [5.2 3.5 1.5 0.2]\n",
|
||
" [5.7 3. 4.2 1.2]\n",
|
||
" [4.4 3.2 1.3 0.2]\n",
|
||
" [5.2 3.4 1.4 0.2]\n",
|
||
" [5.8 2.7 5.1 1.9]\n",
|
||
" [6.1 2.6 5.6 1.4]\n",
|
||
" [5.1 2.5 3. 1.1]\n",
|
||
" [4.9 2.5 4.5 1.7]\n",
|
||
" [6.5 3.2 5.1 2. ]\n",
|
||
" [5. 3.4 1.6 0.4]\n",
|
||
" [6.7 3.1 5.6 2.4]\n",
|
||
" [5. 3.6 1.4 0.2]\n",
|
||
" [5.7 2.9 4.2 1.3]\n",
|
||
" [5.4 3.9 1.3 0.4]\n",
|
||
" [5. 3.2 1.2 0.2]\n",
|
||
" [4.9 3. 1.4 0.2]\n",
|
||
" [5.7 2.8 4.1 1.3]\n",
|
||
" [6.8 3.2 5.9 2.3]\n",
|
||
" [7.9 3.8 6.4 2. ]\n",
|
||
" [6. 3.4 4.5 1.6]\n",
|
||
" [6.1 2.8 4. 1.3]\n",
|
||
" [5.5 2.4 3.8 1.1]\n",
|
||
" [6.3 2.5 4.9 1.5]\n",
|
||
" [5.7 2.8 4.5 1.3]\n",
|
||
" [6.7 3.3 5.7 2.1]\n",
|
||
" [6.3 2.3 4.4 1.3]\n",
|
||
" [4.7 3.2 1.3 0.2]\n",
|
||
" [6. 2.9 4.5 1.5]\n",
|
||
" [6. 2.7 5.1 1.6]\n",
|
||
" [4.8 3.4 1.6 0.2]\n",
|
||
" [5. 2. 3.5 1. ]\n",
|
||
" [4.5 2.3 1.3 0.3]\n",
|
||
" [4.6 3.1 1.5 0.2]\n",
|
||
" [6.7 3. 5.2 2.3]\n",
|
||
" [6.6 3. 4.4 1.4]\n",
|
||
" [6.8 3. 5.5 2.1]\n",
|
||
" [6.9 3.2 5.7 2.3]\n",
|
||
" [5.6 3. 4.5 1.5]\n",
|
||
" [6.7 3. 5. 1.7]\n",
|
||
" [6.7 2.5 5.8 1.8]\n",
|
||
" [6.5 2.8 4.6 1.5]\n",
|
||
" [5.8 2.6 4. 1.2]\n",
|
||
" [4.6 3.6 1. 0.2]\n",
|
||
" [5.1 3.8 1.5 0.3]\n",
|
||
" [5.5 4.2 1.4 0.2]\n",
|
||
" [6.4 3.2 4.5 1.5]\n",
|
||
" [5.7 4.4 1.5 0.4]\n",
|
||
" [4.8 3. 1.4 0.3]\n",
|
||
" [7.1 3. 5.9 2.1]\n",
|
||
" [6.4 3.1 5.5 1.8]\n",
|
||
" [6.1 2.9 4.7 1.4]\n",
|
||
" [6.5 3. 5.8 2.2]\n",
|
||
" [5.9 3. 4.2 1.5]\n",
|
||
" [4.9 3.1 1.5 0.1]\n",
|
||
" [7.6 3. 6.6 2.1]\n",
|
||
" [7.7 3.8 6.7 2.2]\n",
|
||
" [6.2 2.9 4.3 1.3]\n",
|
||
" [4.8 3.1 1.6 0.2]\n",
|
||
" [6. 2.2 4. 1. ]\n",
|
||
" [6.5 3. 5.5 1.8]\n",
|
||
" [6.1 3. 4.6 1.4]\n",
|
||
" [5.6 2.9 3.6 1.3]\n",
|
||
" [5.1 3.4 1.5 0.2]\n",
|
||
" [6.3 3.4 5.6 2.4]\n",
|
||
" [6.3 2.9 5.6 1.8]\n",
|
||
" [6.5 3. 5.2 2. ]\n",
|
||
" [5.8 4. 1.2 0.2]\n",
|
||
" [4.4 2.9 1.4 0.2]\n",
|
||
" [6.2 2.2 4.5 1.5]\n",
|
||
" [5.8 2.7 5.1 1.9]\n",
|
||
" [5.8 2.7 4.1 1. ]\n",
|
||
" [6. 3. 4.8 1.8]\n",
|
||
" [6. 2.2 5. 1.5]\n",
|
||
" [6.3 2.8 5.1 1.5]\n",
|
||
" [6.4 2.8 5.6 2.2]\n",
|
||
" [5.5 2.6 4.4 1.2]\n",
|
||
" [7.7 3. 6.1 2.3]\n",
|
||
" [5.6 2.8 4.9 2. ]\n",
|
||
" [5. 2.3 3.3 1. ]\n",
|
||
" [7.7 2.8 6.7 2. ]\n",
|
||
" [5.5 2.3 4. 1.3]\n",
|
||
" [5. 3.5 1.3 0.3]\n",
|
||
" [7. 3.2 4.7 1.4]\n",
|
||
" [4.9 2.4 3.3 1. ]\n",
|
||
" [5.1 3.7 1.5 0.4]\n",
|
||
" [5.5 2.5 4. 1.3]\n",
|
||
" [5.8 2.7 3.9 1.2]\n",
|
||
" [5.7 3.8 1.7 0.3]\n",
|
||
" [6.4 2.8 5.6 2.1]\n",
|
||
" [7.2 3.2 6. 1.8]\n",
|
||
" [6.3 3.3 4.7 1.6]\n",
|
||
" [6.4 2.9 4.3 1.3]\n",
|
||
" [5.6 2.5 3.9 1.1]\n",
|
||
" [6.2 2.8 4.8 1.8]\n",
|
||
" [5.4 3. 4.5 1.5]\n",
|
||
" [6.7 3.3 5.7 2.5]\n",
|
||
" [5.1 3.8 1.6 0.2]\n",
|
||
" [5.7 2.5 5. 2. ]\n",
|
||
" [5.2 2.7 3.9 1.4]\n",
|
||
" [5.6 3. 4.1 1.3]]\n",
|
||
"[2. 0. 0. 2. 2. 1. 0. 1. 2. 2. 0. 2. 1. 2. 0. 2. 1. 0. 2. 0. 2. 0. 1. 0.\n",
|
||
" 0. 0. 1. 2. 1. 1. 0. 2. 0. 2. 0. 0. 2. 0. 1. 1. 0. 0. 0. 0. 0. 0. 1. 0.\n",
|
||
" 0. 2. 2. 1. 2. 2. 0. 2. 0. 1. 0. 0. 0. 1. 2. 2. 1. 1. 1. 1. 1. 2. 1. 0.\n",
|
||
" 1. 1. 0. 1. 0. 0. 2. 1. 2. 2. 1. 1. 2. 1. 1. 0. 0. 0. 1. 0. 0. 2. 2. 1.\n",
|
||
" 2. 1. 0. 2. 2. 1. 0. 1. 2. 1. 1. 0. 2. 2. 2. 0. 0. 1. 2. 1. 2. 2. 2. 2.\n",
|
||
" 1. 2. 2. 1. 2. 1. 0. 1. 1. 0. 1. 1. 0. 2. 2. 1. 1. 1. 2. 1. 2. 0. 2. 1.\n",
|
||
" 1.]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 22: PERMUTING THE DATA\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"#\n",
|
||
"# we scramble the data, to give a different TRAIN/TEST split each time...\n",
|
||
"#\n",
|
||
"indices = np.random.permutation(len(y_all)) # indices is a permutation-list\n",
|
||
"\n",
|
||
"# we scramble both X and y, necessarily with the same permutation\n",
|
||
"X_labeled = X_all[indices] # we apply the _same_ permutation to each!\n",
|
||
"y_labeled = y_all[indices] # again...\n",
|
||
"print(X_labeled) # note that X_labeled and y_labeled are permuted identically\n",
|
||
"print(y_labeled)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 39,
|
||
"metadata": {
|
||
"id": "_pD7IZR1KPSC"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"total rows: 145; training with 116 rows; testing with 29 rows\n",
|
||
"\t(sanity check: 116 + 29 = 145)\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 23: DEFINING TRAIN VS TEST SETS\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# We next separate into test data and training data ...\n",
|
||
"# + We will train on the training data...\n",
|
||
"# + We will _not_ look at the testing data when building the model\n",
|
||
"#\n",
|
||
"# Then, afterward, we will test on the testing data -- and see how well we do!\n",
|
||
"#\n",
|
||
"\n",
|
||
"#\n",
|
||
"# a common convention: train on 80%, test on 20% Let's define the TEST_PERCENT\n",
|
||
"#\n",
|
||
"num_rows = X_labeled.shape[0] # the number of labeled rows\n",
|
||
"test_percent = 0.20\n",
|
||
"test_size = int(test_percent * num_rows) # no harm in rounding down\n",
|
||
"\n",
|
||
"X_test = X_labeled[:test_size] # first section are for testing\n",
|
||
"y_test = y_labeled[:test_size]\n",
|
||
"\n",
|
||
"X_train = X_labeled[test_size:] # all the rest are for training\n",
|
||
"y_train = y_labeled[test_size:]\n",
|
||
"\n",
|
||
"num_train_rows = len(y_train)\n",
|
||
"num_test_rows = len(y_test)\n",
|
||
"print(f\"total rows: {num_rows}; training with {num_train_rows} rows; testing with {num_test_rows} rows\" )\n",
|
||
"print(f\"\\t(sanity check: {num_train_rows} + {num_test_rows} = {num_train_rows + num_test_rows})\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 40,
|
||
"metadata": {
|
||
"id": "jvJMYC3eKPSD"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Created and trained a knn classifier with k = 84\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"#######################################################\n",
|
||
"# BLOCK 24: FIRST ATTEMPT TO BUILD & TRAIN A kNN MODEL\n",
|
||
"#######################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# +++ This is the \"Model-building and Model-training Cell\"\n",
|
||
"#\n",
|
||
"# Create a kNN model and train it!\n",
|
||
"#\n",
|
||
"from sklearn.neighbors import KNeighborsClassifier\n",
|
||
"\n",
|
||
"k = 84 # we don't know what k to use, so we guess for now! (this will _not_ be a good value)\n",
|
||
"knn_model = KNeighborsClassifier(n_neighbors = k) # here, k is the \"k\" in kNN\n",
|
||
"\n",
|
||
"# we train the model (it's one line!)\n",
|
||
"knn_model.fit(X_train, y_train) # yay! trained!\n",
|
||
"print(\"Created and trained a knn classifier with k =\", k)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 41,
|
||
"metadata": {
|
||
"id": "d3cB0xryKPSD"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Predicted labels: [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n",
|
||
" 1. 1. 1. 1. 1.]\n",
|
||
"Actual labels : [2. 0. 0. 2. 2. 1. 0. 1. 2. 2. 0. 2. 1. 2. 0. 2. 1. 0. 2. 0. 2. 0. 1. 0.\n",
|
||
" 0. 0. 1. 2. 1.]\n",
|
||
"\n",
|
||
"Results on test set: 7 correct out of 29 total.\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 25: TEST THE kNN MODEL\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# +++ This is the \"Model-testing Cell\"\n",
|
||
"#\n",
|
||
"# Now, let's see how well we did on our \"held-out data\" (the testing data)\n",
|
||
"#\n",
|
||
"\n",
|
||
"# We run our test set!\n",
|
||
"predicted_labels = knn_model.predict(X_test)\n",
|
||
"actual_labels = y_test\n",
|
||
"\n",
|
||
"# Let's print them so we can compare...\n",
|
||
"print(\"Predicted labels:\", predicted_labels)\n",
|
||
"print(\"Actual labels :\", actual_labels)\n",
|
||
"\n",
|
||
"# And, some overall results\n",
|
||
"num_correct = sum(predicted_labels == actual_labels)\n",
|
||
"total = len(actual_labels)\n",
|
||
"print(f\"\\nResults on test set: {num_correct} correct out of {total} total.\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 42,
|
||
"metadata": {
|
||
"id": "liXBT5-IKPSD"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"row 0 : versicolor virginica incorrect\n",
|
||
"row 1 : versicolor setosa incorrect\n",
|
||
"row 2 : versicolor setosa incorrect\n",
|
||
"row 3 : versicolor virginica incorrect\n",
|
||
"row 4 : versicolor virginica incorrect\n",
|
||
"row 5 : versicolor versicolor \n",
|
||
"row 6 : versicolor setosa incorrect\n",
|
||
"row 7 : versicolor versicolor \n",
|
||
"row 8 : versicolor virginica incorrect\n",
|
||
"row 9 : versicolor virginica incorrect\n",
|
||
"row 10 : versicolor setosa incorrect\n",
|
||
"row 11 : versicolor virginica incorrect\n",
|
||
"row 12 : versicolor versicolor \n",
|
||
"row 13 : versicolor virginica incorrect\n",
|
||
"row 14 : versicolor setosa incorrect\n",
|
||
"row 15 : versicolor virginica incorrect\n",
|
||
"row 16 : versicolor versicolor \n",
|
||
"row 17 : versicolor setosa incorrect\n",
|
||
"row 18 : versicolor virginica incorrect\n",
|
||
"row 19 : versicolor setosa incorrect\n",
|
||
"row 20 : versicolor virginica incorrect\n",
|
||
"row 21 : versicolor setosa incorrect\n",
|
||
"row 22 : versicolor versicolor \n",
|
||
"row 23 : versicolor setosa incorrect\n",
|
||
"row 24 : versicolor setosa incorrect\n",
|
||
"row 25 : versicolor setosa incorrect\n",
|
||
"row 26 : versicolor versicolor \n",
|
||
"row 27 : versicolor virginica incorrect\n",
|
||
"row 28 : versicolor versicolor \n",
|
||
"\n",
|
||
"Correct: 7 out of 29\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"7"
|
||
]
|
||
},
|
||
"execution_count": 42,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 26: PRETTY-PRINT PREDICTED LABELS\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# Let's print these more helpfully, in a vertical table\n",
|
||
"#\n",
|
||
"\n",
|
||
"def compareLabels(predicted_labels: np.ndarray, actual_labels: np.ndarray) -> int:\n",
|
||
" ''' a more neatly formatted comparison, returning the number correct '''\n",
|
||
" num_labels = len(predicted_labels)\n",
|
||
" num_correct = 0\n",
|
||
"\n",
|
||
" for i in range(num_labels):\n",
|
||
" predicted = int(round(predicted_labels[i])) # round-to-int protects from float imprecision\n",
|
||
" actual = int(round(actual_labels[i]))\n",
|
||
" result = \"incorrect\"\n",
|
||
" if predicted == actual: # if they match,\n",
|
||
" result = \"\" # no longer incorrect\n",
|
||
" num_correct += 1 # and we count a match!\n",
|
||
"\n",
|
||
" # note the justification formatting:\n",
|
||
" # :>3d right justifies integers (d) to width 3\n",
|
||
" # :<12s left justifies strings (s) to width 12\n",
|
||
" print(f\"row {i:>3d} : \", end = \"\")\n",
|
||
" print(f\"{species_names[predicted]:>12s} \", end = \"\")\n",
|
||
" print(f\"{species_names[actual]:<12s} {result}\")\n",
|
||
"\n",
|
||
" print()\n",
|
||
" print(f\"Correct: {num_correct} out of {num_labels}\")\n",
|
||
" return num_correct\n",
|
||
"\n",
|
||
"#\n",
|
||
"# let's try it out!\n",
|
||
"#\n",
|
||
"\n",
|
||
"compareLabels(predicted_labels,actual_labels)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 43,
|
||
"metadata": {
|
||
"id": "h_ZigXq2KPSE"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"predicted_species = [1.]\n",
|
||
"I predict versicolor (1) from features [6.7, 3.3, 5.7, 2.1]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 27: USE THE FIRST-ATTEMPT kNN MODEL\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# Ok! We have our knn model, we could just use it...\n",
|
||
"#\n",
|
||
"\n",
|
||
"#\n",
|
||
"# data-driven predictive model (k-nearest-neighbor), using scikit-learn\n",
|
||
"#\n",
|
||
"\n",
|
||
"def predictiveModel( features: list[float] ) -> str:\n",
|
||
" ''' input: a list of four features\n",
|
||
" [ sepallen, sepalwid, petallen, petalwid ]\n",
|
||
" output: the predicted species of iris, from\n",
|
||
" setosa (0), versicolor (1), virginica (2)\n",
|
||
" '''\n",
|
||
" our_features = np.asarray([features]) # extra brackets needed\n",
|
||
" predicted_species = knn_model.predict(our_features)\n",
|
||
" print(f\"predicted_species = {predicted_species}\")\n",
|
||
"\n",
|
||
" predicted_species = int(round(predicted_species[0])) # unpack one element\n",
|
||
" name = species_names[predicted_species]\n",
|
||
" return f\"{name} ({predicted_species})\"\n",
|
||
"\n",
|
||
"#\n",
|
||
"# Try it!\n",
|
||
"#\n",
|
||
"# features = eval(input(\"Enter new features: \"))\n",
|
||
"#\n",
|
||
"features = [6.7,3.3,5.7,2.1] # [5.8,2.7,4.1,1.0] [4.6,3.6,3.0,2.2] [6.7,3.3,5.7,2.1]\n",
|
||
"result = predictiveModel( features )\n",
|
||
"print(f\"I predict {result} from features {features}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 44,
|
||
"metadata": {
|
||
"id": "kPByHBBnKPSE"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 28: COMMENTS ON CHOICE OF BEST k\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# Except, we didn't really explore whether this was the BEST model we could build!\n",
|
||
"#\n",
|
||
"#\n",
|
||
"# We used k = 84 (a neighborhood size of 84 flowers)\n",
|
||
"# In a dataset of only 140ish flowers, with three species, this seems like a bad idea!\n",
|
||
"#\n",
|
||
"# Perhaps we should try ALL the neighborhood sizes in their own TRAIN/TEST split\n",
|
||
"# and see which neighborhood size works the best, for irises, at least...\n",
|
||
"#"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"id": "ZUmotr7hKPSE"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"k: 1 cv accuracy: 0.9482\n"
|
||
]
|
||
},
|
||
{
|
||
"ename": "NameError",
|
||
"evalue": "name 'best_accuracy' is not defined",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
||
"\u001b[31mNameError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[45]\u001b[39m\u001b[32m, line 28\u001b[39m\n\u001b[32m 24\u001b[39m cv_scores = cross_val_score(knn_cv_model, X_train, y_train, cv=\u001b[32m5\u001b[39m)\n\u001b[32m 25\u001b[39m this_cv_accuracy = cv_scores.mean()\n\u001b[32m 26\u001b[39m print(f\"k: {k:2d} cv accuracy: {this_cv_accuracy:7.4f}\")\n\u001b[32m 27\u001b[39m all_accuracies.append(this_cv_accuracy)\n\u001b[32m---> \u001b[39m\u001b[32m28\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m this_cv_accuracy > best_accuracy:\n\u001b[32m 29\u001b[39m best_accuracy = this_cv_accuracy\n\u001b[32m 30\u001b[39m best_k = k\n\u001b[32m 31\u001b[39m \u001b[38;5;66;03m# assign best value of k to best_k\u001b[39;00m\n",
|
||
"\u001b[31mNameError\u001b[39m: name 'best_accuracy' is not defined"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 29: USING CROSS VALIDATION\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# to do this, we use \"cross validation\"\n",
|
||
"# (see slide 45)\n",
|
||
"#\n",
|
||
"\n",
|
||
"import seaborn as sns\n",
|
||
"import matplotlib.pyplot as plt\n",
|
||
"from sklearn.model_selection import cross_val_score\n",
|
||
"\n",
|
||
"#\n",
|
||
"# cross-validation splits the training set into two pieces:\n",
|
||
"# + model-building and model-validation. We'll use \"build\" and \"validate\"\n",
|
||
"#\n",
|
||
"\n",
|
||
"max_k = 85\n",
|
||
"all_accuracies = []\n",
|
||
"\n",
|
||
"for k in range(1, max_k, 1):\n",
|
||
" knn_cv_model = KNeighborsClassifier(n_neighbors=k)\n",
|
||
" cv_scores = cross_val_score(knn_cv_model, X_train, y_train, cv=5)\n",
|
||
" this_cv_accuracy = cv_scores.mean()\n",
|
||
" print(f\"k: {k:2d} cv accuracy: {this_cv_accuracy:7.4f}\")\n",
|
||
" all_accuracies.append(this_cv_accuracy)\n",
|
||
" if this_cv_accuracy > best_accuracy:\n",
|
||
" best_accuracy = this_cv_accuracy\n",
|
||
" best_k = k\n",
|
||
"# assign best value of k to best_k\n",
|
||
"#best_k = k # *** AT THE MOMENT THIS IS INCORRECT ***\n",
|
||
"# you'll need to modify the loop above to find and remember the real best_k\n",
|
||
"\n",
|
||
"print(f\"best_k = {best_k} yields the highest average cv accuracy.\") # print the best one\n",
|
||
"\n",
|
||
"plt.figure(figsize=(10, 6))\n",
|
||
"sns.lineplot(x=range(1,len(all_accuracies)+1), y=all_accuracies)\n",
|
||
"plt.xlabel(\"k value (index)\")\n",
|
||
"plt.ylabel(\"Cross-validated accuracy\")\n",
|
||
"plt.title(\"kNN Accuracy vs k Value\")\n",
|
||
"plt.show()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 46,
|
||
"metadata": {
|
||
"id": "pJW6c8XdKPSF"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"ename": "NameError",
|
||
"evalue": "name 'best_k' is not defined",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
||
"\u001b[31mNameError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[46]\u001b[39m\u001b[32m, line 11\u001b[39m\n\u001b[32m 7\u001b[39m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[32m 8\u001b[39m \u001b[38;5;66;03m# Now, using best_k instead of the original, randomly-guessed value How does it do?!\u001b[39;00m\n\u001b[32m 9\u001b[39m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[32m 10\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m sklearn.neighbors \u001b[38;5;28;01mimport\u001b[39;00m KNeighborsClassifier\n\u001b[32m---> \u001b[39m\u001b[32m11\u001b[39m knn_model_tuned = KNeighborsClassifier(n_neighbors = best_k) \u001b[38;5;66;03m# here, we use the best_k\u001b[39;00m\n\u001b[32m 12\u001b[39m \n\u001b[32m 13\u001b[39m \u001b[38;5;66;03m# we train the model (one line!)\u001b[39;00m\n\u001b[32m 14\u001b[39m knn_model_tuned.fit(X_train, y_train) \u001b[38;5;66;03m# yay! trained!\u001b[39;00m\n",
|
||
"\u001b[31mNameError\u001b[39m: name 'best_k' is not defined"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 30: RE-BUILD & RE-TRAIN USING BEST k\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# Now, we re-create and re-run the \"Model-building and -training Cell\"\n",
|
||
"#\n",
|
||
"# Now, using best_k instead of the original, randomly-guessed value How does it do?!\n",
|
||
"#\n",
|
||
"from sklearn.neighbors import KNeighborsClassifier\n",
|
||
"knn_model_tuned = KNeighborsClassifier(n_neighbors = best_k) # here, we use the best_k\n",
|
||
"\n",
|
||
"# we train the model (one line!)\n",
|
||
"knn_model_tuned.fit(X_train, y_train) # yay! trained!\n",
|
||
"print(f\"Created + trained a knn classifier, now tuned with a (best) k of {best_k}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 47,
|
||
"metadata": {
|
||
"id": "9h5-1TukKPSF"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"ename": "NameError",
|
||
"evalue": "name 'knn_model_tuned' is not defined",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
||
"\u001b[31mNameError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[47]\u001b[39m\u001b[32m, line 8\u001b[39m\n\u001b[32m 4\u001b[39m \n\u001b[32m 5\u001b[39m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[32m 6\u001b[39m \u001b[38;5;66;03m# Re-create and re-run the \"Model-testing Cell\" How does it do with best_k?!\u001b[39;00m\n\u001b[32m 7\u001b[39m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m8\u001b[39m predicted_labels = knn_model_tuned.predict(X_test)\n\u001b[32m 9\u001b[39m actual_labels = y_test\n\u001b[32m 10\u001b[39m \n\u001b[32m 11\u001b[39m \u001b[38;5;66;03m# Let's print them so we can compare...\u001b[39;00m\n",
|
||
"\u001b[31mNameError\u001b[39m: name 'knn_model_tuned' is not defined"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 31: RE-TEST THE BEST-k MODEL\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# Re-create and re-run the \"Model-testing Cell\" How does it do with best_k?!\n",
|
||
"#\n",
|
||
"predicted_labels = knn_model_tuned.predict(X_test)\n",
|
||
"actual_labels = y_test\n",
|
||
"\n",
|
||
"# Let's print them so we can compare...\n",
|
||
"print(\"Predicted labels:\", predicted_labels)\n",
|
||
"print(\"Actual labels:\", actual_labels)\n",
|
||
"print()\n",
|
||
"# and, we'll print our nicer table...\n",
|
||
"compareLabels(predicted_labels,actual_labels)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"id": "8dIjchI0RQ57"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"################################################\n",
|
||
"# BLOCK 32: TRYING DIFFERENT PERMUTATIONS\n",
|
||
"################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# Before moving on, go back and choose a new permutation to give\n",
|
||
"# new testing and training sets, and go back through the steps\n",
|
||
"# for identifying the \"best\" k (starting at Block 22 and re-doing\n",
|
||
"# up through Block 31).\n",
|
||
"#\n",
|
||
"# Repeat this several times.\n",
|
||
"# Do you get the same value for k each time? Why or why not?\n",
|
||
"#"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"id": "h1fhLBYSKPSF"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"####################################################\n",
|
||
"# BLOCK 33: REBUILD & TRAIN USING BEST k & ALL DATA\n",
|
||
"####################################################\n",
|
||
"\n",
|
||
"# Ok! Now we have tuned knn to use the \"best\" value of k...\n",
|
||
"#\n",
|
||
"# And, we should really use ALL available data to train our final predictive model\n",
|
||
"# (not split into test and train as before)\n",
|
||
"#\n",
|
||
"\n",
|
||
"knn_model_final = KNeighborsClassifier(n_neighbors=best_k) # here, we use the best_k\n",
|
||
"knn_model_final.fit(X_all, y_all) # yay! trained!\n",
|
||
"print(f\"Created + trained a 'final' knn classifier, with a (best) k of {best_k}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"id": "AsC4oa2qKPSG"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"####################################################\n",
|
||
"# BLOCK 34: TRYING FINAL MODEL \"IN THE WILD\"\n",
|
||
"####################################################\n",
|
||
"\n",
|
||
"#\n",
|
||
"# final predictive model (k-nearest-neighbor), with tuned k + ALL data incorporated\n",
|
||
"#\n",
|
||
"\n",
|
||
"def predictiveModel( features: list[float] ) -> None:\n",
|
||
" ''' input: a list of four features\n",
|
||
" [ sepallen, sepalwid, petallen, petalwid ]\n",
|
||
" output: the predicted species of iris, from\n",
|
||
" setosa (0), versicolor (1), virginica (2)\n",
|
||
" '''\n",
|
||
" our_features = np.asarray([features]) # extra brackets needed\n",
|
||
" predicted_species = knn_model_final.predict(our_features)\n",
|
||
"\n",
|
||
" predicted_species = int(round(predicted_species[0])) # unpack one element\n",
|
||
" name = species_names[predicted_species]\n",
|
||
" return f\"{name} ({predicted_species})\"\n",
|
||
"\n",
|
||
"#\n",
|
||
"# Try it on several!\n",
|
||
"#\n",
|
||
"# features = eval(input(\"Enter new features: \"))\n",
|
||
"#\n",
|
||
"features = [6.7,3.3,5.7,2.1] # [5.8,2.7,4.1,1.0] [4.6,3.6,3.0,2.2] [6.7,3.3,5.7,2.1]\n",
|
||
"result = predictiveModel( features )\n",
|
||
"print(f\"I predict {result} from features {features}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"id": "UHNILKXiRQ58"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"################################################################\n",
|
||
"# BLOCK 35a: HOW DOES THE MODEL PERFORM ON MEAN OF EACH FLOWER?\n",
|
||
"################################################################\n",
|
||
"\n",
|
||
"# let's recall the species names and their order in the list\n",
|
||
"print(species_names)\n",
|
||
"print('=' * 70)\n",
|
||
"\n",
|
||
"# and let's recall what the final DataFrame looks like, noting that\n",
|
||
"# the irisname was converted to the corresponding index in species_names\n",
|
||
"print(df_final)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 48,
|
||
"metadata": {
|
||
"id": "MlnIrLPWRQ58"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
" sepallen sepalwid petallen petalwid irisname\n",
|
||
"50 7.0 3.2 4.7 1.4 1\n",
|
||
"51 6.4 3.2 4.5 1.5 1\n",
|
||
"52 6.9 3.1 4.9 1.5 1\n",
|
||
"53 5.5 2.3 4.0 1.3 1\n",
|
||
".. ... ... ... ... ...\n",
|
||
"96 5.7 2.9 4.2 1.3 1\n",
|
||
"97 6.2 2.9 4.3 1.3 1\n",
|
||
"98 5.1 2.5 3.0 1.1 1\n",
|
||
"99 5.7 2.8 4.1 1.3 1\n",
|
||
"\n",
|
||
"[50 rows x 5 columns]\n",
|
||
"======================================================================\n",
|
||
"sepallen 5.936\n",
|
||
"sepalwid 2.770\n",
|
||
"petallen 4.260\n",
|
||
"petalwid 1.326\n",
|
||
"irisname 1.000\n",
|
||
"dtype: float64\n",
|
||
"======================================================================\n",
|
||
"[5.936 2.77 4.26 1.326]\n",
|
||
"predicted_species = [1.]\n",
|
||
"Mean versicolor features [5.936 2.77 4.26 1.326] -> versicolor (1)\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"################################################################\n",
|
||
"# BLOCK 35b: HOW DOES THE MODEL PERFORM ON MEAN OF EACH FLOWER?\n",
|
||
"################################################################\n",
|
||
"\n",
|
||
"# let's grab the data from df_final corresponding to versicolor\n",
|
||
"versicolor_data = df_final[ df_final['irisname'] == convertSpecies('versicolor') ]\n",
|
||
"print(versicolor_data)\n",
|
||
"print('=' * 70)\n",
|
||
"\n",
|
||
"# let's print the mean of each column\n",
|
||
"print(versicolor_data.mean())\n",
|
||
"print('=' * 70)\n",
|
||
"\n",
|
||
"# and let's grab the features means only (don't need the label) for versicolor\n",
|
||
"versicolor_features_means = np.asarray(versicolor_data.mean()[:-1])\n",
|
||
"print(versicolor_features_means)\n",
|
||
"\n",
|
||
"# now run the predictive model (see Block 34 above) and print a corresponding\n",
|
||
"# message\n",
|
||
"\n",
|
||
"# >>> YOU ADD CODE HERE\n",
|
||
"result = predictiveModel(versicolor_features_means)\n",
|
||
"print(f\"Mean versicolor features {versicolor_features_means} -> {result}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"id": "twR2L9IRRQ58"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"################################################################\n",
|
||
"# BLOCK 35c: HOW DOES THE MODEL PERFORM ON MEAN OF EACH FLOWER?\n",
|
||
"################################################################\n",
|
||
"\n",
|
||
"# Automate the process used in Block 35b, across all species:\n",
|
||
"#\n",
|
||
"# Loop across species names, and for each species,\n",
|
||
"# (a) pull that corresponding data from df_final\n",
|
||
"# (b) compute the means of the features, storing as a numpy array\n",
|
||
"# (c) call the predictive model using those features\n",
|
||
"# (d) print a corresponding message\n",
|
||
"\n",
|
||
"# >> YOU ADD CODE HERE -- YOU SHOULD NEED NO MORE THAN 5 LINES OF CODE\n",
|
||
"for name in species_names:\n",
|
||
" species_data = df_final[df_final['irisname'] == convertSpecies(name)]\n",
|
||
" species_features_means = np.asarray(species_data.mean()[:-1])\n",
|
||
" result = predictiveModel(species_features_means)\n",
|
||
" print(f\"Mean {name} features {species_features_means} -> {result}\")"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"colab": {
|
||
"provenance": []
|
||
},
|
||
"kernelspec": {
|
||
"display_name": "Python 3",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.14.3"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 0
|
||
}
|