{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing\nimport re # pattern searching\nimport seaborn as sns # plots\nimport matplotlib as mpl # figure artists, attributes\nimport matplotlib.pyplot as plt # figures, axes\nfrom matplotlib.patches import Patch # artist manipulation\nfrom scipy import stats # distributions/quantile plots\nfrom datetime import datetime as dt #datetime manipulation\n%matplotlib inline\n\nfrom IPython.core.display import HTML\nHTML(\"\"\"\n<style>\n.output_png {\n    display: table-cell;\n    text-align: center;\n    vertical-align: middle;\n}\n</style>\n\"\"\")","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":1.282035,"end_time":"2022-02-24T17:15:36.878257","exception":false,"start_time":"2022-02-24T17:15:35.596222","status":"completed"},"tags":[],"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T00:36:33.445954Z","iopub.execute_input":"2022-07-12T00:36:33.446244Z","iopub.status.idle":"2022-07-12T00:36:33.460375Z","shell.execute_reply.started":"2022-07-12T00:36:33.446212Z","shell.execute_reply":"2022-07-12T00:36:33.459374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **First view of the data**\n\n<span style=\"font-size:18px\">\n    An overview of briefly conveys the features, corresponding datatypes, scale/range of values, missing values etc. Its helpful in planning the data preprocessing techniques\n</span>\n\n**Note: If reader is not viewing this notebook on kaggle, then downloading the datasets along with notebook is recommended. File paths to training and testing datasets should be modified accordingly**","metadata":{"papermill":{"duration":0.021109,"end_time":"2022-02-24T17:15:36.920574","exception":false,"start_time":"2022-02-24T17:15:36.899465","status":"completed"},"tags":[]}},{"cell_type":"code","source":"train_path = '../input/house-prices-advanced-regression-techniques/train.csv' # file path for training data\ntest_path = '../input/house-prices-advanced-regression-techniques/test.csv' #file path for testing data\n\n\npd.set_option('display.max_columns', 100)\ndf_train = pd.read_csv(train_path, index_col='Id')\ndf_test = pd.read_csv(test_path, index_col='Id')\nSalePrice = df_train['SalePrice']\ndf_train.drop('SalePrice', axis=1, inplace=True, errors='ignore')\ndf_train.head(20)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T00:36:46.839013Z","iopub.execute_input":"2022-07-12T00:36:46.839943Z","iopub.status.idle":"2022-07-12T00:36:46.986607Z","shell.execute_reply.started":"2022-07-12T00:36:46.839901Z","shell.execute_reply":"2022-07-12T00:36:46.985317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **A DataFrame with column info and description**\n<span style=\"font-size:18px\">\n             The DataFrame with column names, column descriptions, column datatype, column missing values should can be created to inspect the incorrect datatypes and missing values\n</span>","metadata":{"papermill":{"duration":0.022827,"end_time":"2022-02-24T17:15:37.105847","exception":false,"start_time":"2022-02-24T17:15:37.08302","status":"completed"},"tags":[]}},{"cell_type":"code","source":"txt = open('../input/house-prices-advanced-regression-techniques/data_description.txt', 'r')\nlines = txt.readlines()\n\ndescription=[]\nrow=None\nfor line in lines:\n    if len(re.findall(r\"^\\S.*:.*\", line, re.DOTALL)) is not 0:\n        if row is None:\n            row=line\n        else:\n            description.append(row)\n            row=line\n    else:\n        if line is lines[-1]:\n            row+=line\n            description.append(row)\n        else:\n            row+=line\n            \ndf_info = pd.DataFrame()\ndf_info['dtype'] = df_train.dtypes\ndf_info['nullValues'] = df_train.isnull().sum()\ndf_info['naValues'] = df_train.isna().sum()\ndf_info['columnDesc'] = description\ndf_info.to_csv('column_desc.csv')\ndf_info.head(20)","metadata":{"papermill":{"duration":0.035445,"end_time":"2022-02-24T17:15:37.16332","exception":false,"start_time":"2022-02-24T17:15:37.127875","status":"completed"},"tags":[],"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T00:36:50.930900Z","iopub.execute_input":"2022-07-12T00:36:50.932086Z","iopub.status.idle":"2022-07-12T00:36:50.981122Z","shell.execute_reply.started":"2022-07-12T00:36:50.932022Z","shell.execute_reply":"2022-07-12T00:36:50.979502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Changing  Datatypes**\n<span style=\"font-size:18px;\">\n    Some features have incorrect datatypes and lot of features have missing values. Feature set needs dtype conversion and imputation before it can be explored to derive insights\n</span>","metadata":{}},{"cell_type":"code","source":"##converting the numerical columns into object columns\ndf_train['GarageYrBlt'] = df_train['GarageYrBlt'].fillna(0).astype('int64').astype('object')\ndf_train['MSSubClass'] = df_train['MSSubClass'].astype('object')\ndf_train['YearBuilt'] = df_train['YearBuilt'].astype('object', copy=False)\ndf_train['YearRemodAdd'] = df_train['YearRemodAdd'].astype('object', copy=False)\ndf_train['MoSold'] = df_train['MoSold'].astype('object', copy=False)\ndf_train['YrSold'] = df_train['YrSold'].astype('object', copy=False)\ndf_train.info()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T00:36:59.274416Z","iopub.execute_input":"2022-07-12T00:36:59.274770Z","iopub.status.idle":"2022-07-12T00:36:59.316327Z","shell.execute_reply.started":"2022-07-12T00:36:59.274733Z","shell.execute_reply":"2022-07-12T00:36:59.314982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Primary Imputation**\n<p style=\"font-size:18px\">\n    Simple logical assumptions should be first approach to impute the missing data.\n</p>\n<ol style=\"font-size:18px; line-height:200%\">\n    <li>MS Zoning: It can be fairly assume that Houses in the same residential zone will possibly have same housing subclass and neighborhood. Based MSSubClass and Neighborhood of the record (with missing MSZoning value), the missing values will be replaced with/imputed as mode value for that combination of MSSubClass and Neighborhood e.g. For a record with missing MSZoning if MSSubClass and Neighborhood values are 150 and 'North Ames' respectively, the mode MSZoning value for all the records with the same pair of MSSubClass and Neighborhood values, Residential Low Density in this case, will be used for imputation.</li>\n    <li>LotFrontage: Similar strategy can be used for LotFrontage as well. For missing LotFrontage, median LotFrontage of all records with same MSZoning value will be imputed</li>\n    <li>Masonry Veneer Area and Type: No logical assumption can be leveraged for this feature. A simply imputation of missing Masonry Veneer Area value with 0 and missing Masonry Veneer Type value with None will be used here</li>\n    <li>Basement features: There are lot of basement features missing where the basement area is zero hence imputing these missing features as 'NA' (categorical) or '0'(numerical) will be the right approach</li>\n    <li>Garage features: There are lot of basement features missing where the garage area is zero and hence imputing these missing features as 'NA' (categorical) or '0'(numerical) will be the right approach</li>\n    <li>Utilities: All but one value is missing. And majority of the values are 'AllPub' (2916 out of 2919).'AllPub' will be used inplace of missing values</li>\n    <li>Exterior features (1st and 2nd): Mode Exterior features corresponding to same MSSubClass and Neighborhood will be used for imputation</li>\n    <li>Electrical, Functional, Kitchen features: Absolute mode values to impute the missing values seems the right way</li>  \n    <li>Fireplaces, Pool and Miscellenious features: Where fireplace/pool area/misc feature value is zero, the corresponding categorical features will be imputed as 'NA'. There are records where pool area is not zero but pool quality is missing. In that case mode pool quality value will be used. There are records where miscellenious feature value is non zero but the miscellenious feature value is missing. In that case we the 'Othr' value will be used for imputation</li>\n    <li>SaleType: Absolute mode value will be used to impute the missing values</li>  \n    <li>Alley and Fence: Most of the records have missing values for these two feature. These columns will be discarded from further preprocessing</li>\n\n</ol>\n","metadata":{}},{"cell_type":"code","source":"##MSZoning: Mode MSZoning values sharing same MSSubclass and Neighborhood \ndf_train['MSZoning']=df_train.groupby(['MSSubClass', 'Neighborhood'])['MSZoning'].transform(lambda x:x.fillna(x.mode()[0]))\n\n##Lot Features: For missing LotFrontage we use median LotFrontage values of same MSZoning properties\ndf_train['LotFrontage']=df_train.groupby(\"MSZoning\")['LotFrontage'].transform(lambda x:x.fillna(x.median()))\n\n##Masonry Veneer Features: There is no logical way to impute the Masonry Veneer type and area. The best way will be to be conservative and assume there is no Masonry Veneer\ndf_train['MasVnrArea'].where(df_train['MasVnrArea'].notna(), 0, inplace=True)\ndf_train['MasVnrType'].where(df_train['MasVnrType'].notna(), \"None\", inplace=True)\n\n##Basement Feautres: Whereever the total basement area is zero and other basement features are missing we can impute \"NA\" values\ndf_train['BsmtQual'].where(df_train['TotalBsmtSF']!=0, \"NA\", inplace=True)\ndf_train['BsmtCond'].where(df_train['TotalBsmtSF']!=0, \"NA\", inplace=True)\ndf_train['BsmtExposure'].where(df_train['TotalBsmtSF']!=0, \"NA\", inplace=True)\ndf_train['BsmtFinType1'].where(df_train['TotalBsmtSF']!=0, \"NA\", inplace=True)\ndf_train['BsmtFinType2'].where(df_train['TotalBsmtSF']!=0, \"NA\", inplace=True)\ndf_train['BsmtFullBath'].where(df_train['TotalBsmtSF']!=0, 0.0, inplace=True)\ndf_train['BsmtHalfBath'].where(df_train['TotalBsmtSF']!=0, 0.0, inplace=True)\ndf_train['BsmtFinSF1'].where(df_train['TotalBsmtSF']!=0, 0.0, inplace=True)\ndf_train['BsmtFinSF2'].where(df_train['TotalBsmtSF']!=0, 0.0, inplace=True)\ndf_train['BsmtUnfSF'].where(df_train['TotalBsmtSF']!=0, 0.0, inplace=True)\n\n##BsmtExposure and BsmtFinTyoe2 still have missing values where the basement area is non zero. In that case we impute the mode values\ndf_train['BsmtExposure']=df_train['BsmtExposure'].transform(lambda x: x.fillna(x.mode()[0]))\ndf_train['BsmtFinType2']=df_train['BsmtFinType2'].transform(lambda x: x.fillna(x.mode()[0]))\n\n##Garage Features: Whereever the garage area is zero and other garage features are missing we can impute \"NA\" values\ndf_train['GarageCond'].where(df_train['GarageArea']!=0, \"NA\", inplace=True)\ndf_train['GarageQual'].where(df_train['GarageArea']!=0, \"NA\", inplace=True)\ndf_train['GarageFinish'].where(df_train['GarageArea']!=0, \"NA\", inplace=True)\ndf_train['GarageType'].where(df_train['GarageArea']!=0, \"NA\", inplace=True)\n\n##Electrical\ndf_train['Electrical']=df_train['Electrical'].fillna(df_train['Electrical'].mode()[0])\n\n##Fireplace Features\ndf_train['FireplaceQu'].where(df_train['Fireplaces']!=0, \"NA\", inplace=True)\n\n##Pool Features\ndf_train['PoolQC'].where(df_train['PoolArea']!=0, \"NA\", inplace=True)\n\n##Miscellaneous Features\ndf_train['MiscFeature'].where(df_train['MiscVal']!=0, \"NA\", inplace=True)\n\n##Too many missing values in Alley and Fence feature and no logical step to impute. We will drop them. \ndf_train.drop(axis=1, columns=['Alley', 'Fence'], errors='ignore', inplace=True)\n\n##Missing values after primary imputation\ndf_train.info()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T00:37:04.859290Z","iopub.execute_input":"2022-07-12T00:37:04.859631Z","iopub.status.idle":"2022-07-12T00:37:05.001033Z","shell.execute_reply.started":"2022-07-12T00:37:04.859595Z","shell.execute_reply":"2022-07-12T00:37:05.000417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"font-size:18px\">\n    Some categorical columns like Fireplace, Garage etc will appear better as a binary columns since what is more important is presence or absence of those amenities than a qualitative/quantitative value of amenities present.\n</span>","metadata":{}},{"cell_type":"code","source":"##Creating boolean columns\ndf_train['HasFireplace'] = np.where(df_train['Fireplaces']==0, 'No', 'Yes')\ndf_train['HasGarage'] = np.where(df_train['GarageCars']==0, 'No', 'Yes')\ndf_train['HasBasement'] = np.where(df_train['BsmtQual']=='NA', 'No', 'Yes')\ndf_train['HasPool'] = np.where(df_train['PoolQC']=='NA', 'No', 'Yes')\ndf_train['HasAmenities']=np.where(df_train['MiscFeature']=='NA', 'No', 'Yes')\n\ndf_train['MoYrSold']= df_train['MoSold'].astype(str) +'-'+ df_train['YrSold'].astype(str)\ndf_train['MoYrSold'] = pd.to_datetime(df_train['MoYrSold'])\ndf_train['YearBuilt'] = pd.to_datetime(df_train['YearBuilt'], format=\"%Y\")\ndf_train['YearRemodAdd'] = pd.to_datetime(df_train['YearRemodAdd'], format=\"%Y\")\ndf_train['SalePrice']=SalePrice\ndf_train.head(10)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T00:37:10.264853Z","iopub.execute_input":"2022-07-12T00:37:10.265409Z","iopub.status.idle":"2022-07-12T00:37:10.372865Z","shell.execute_reply.started":"2022-07-12T00:37:10.265351Z","shell.execute_reply":"2022-07-12T00:37:10.371710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-size:18px\">\n    Now the data is ready to be explored.\n</p>\n<p style=\"font-size:18px\">\n    The time period of sales spans from January 2006 to July 2010 (fig 1a). The month-to-month (MoM) sales chart shows a pattern in the sales count after certain time periods. The annually decomposition of MoM chart confirms this fact; it shows strong annual seasonality (fig 1b). The monthly sales trend in this dataset roughly follows the national trend of March to July having highest sales and November, January and February having lowest.\n</p>","metadata":{}},{"cell_type":"code","source":"fig=plt.figure(figsize=(15,12), layout='tight', dpi=100)\ngrid=fig.add_gridspec(3,3)\nax1=fig.add_subplot(grid[0,:])\ndata=pd.crosstab(df_train['MoYrSold'], columns=1)\nsns.lineplot(x=data.index,y=data[1], ax=ax1);\nxticklabels=['Jan 06', 'Jul 06', 'Jan 07', 'Jul 07', 'Jan 08', 'Jul 08', 'Jan 09', 'Jul 09', 'Jan 10', 'Jul 10']\nyticklabels=[20,40,60]\nax1.set_ylim(0,70)\nax1.set_xticks(ticks=ax1.get_xticks(),labels=xticklabels, fontsize='x-large');\nax1.set_yticks(ticks=yticklabels, labels=yticklabels,fontsize='x-large');\nax1.set_xlabel('Month (MoM)', fontsize='xx-large', fontweight='bold');\nax1.set_ylabel('Sales Count', fontsize='xx-large', fontweight='bold');\n\nax1.text(-0.05,-0.15, r'(a)',transform=ax1.transAxes, fontsize='xx-large');\n\n\nplt.rcParams['legend.title_fontsize'] = 'x-large'\nax2=fig.add_subplot(grid[1:,:])\ndata=pd.crosstab(df_train['MoSold'], columns=df_train['YrSold'])\nsns.lineplot(data=data, palette=sns.color_palette(\"Set1\", n_colors=5), dashes=False, ax=ax2);\nxticks=[i for i in range(1,13)]\nxticklabels=['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\nyticks=[20,40,60]\nax2.set_ylim(0,70)\nax2.set_xticks(ticks=xticks,labels=xticklabels, fontsize='xx-large');\nax2.set_yticks(ticks=yticks, labels=yticks,fontsize='xx-large');\nax2.set_xlabel('Month', fontsize='xx-large', fontweight='bold');\nax2.set_ylabel('Sales Count', fontsize='xx-large', fontweight='bold');\nax2.legend(title='Year Sold', fontsize='xx-large');\nax2.text(-0.05,-0.1, r'(b)',transform=ax2.transAxes, fontsize='xx-large');\n\n\n#fig.savefig('B1.jpeg', dpi=100, bbox_inches='tight')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T00:37:14.176212Z","iopub.execute_input":"2022-07-12T00:37:14.176701Z","iopub.status.idle":"2022-07-12T00:37:14.868454Z","shell.execute_reply.started":"2022-07-12T00:37:14.176652Z","shell.execute_reply":"2022-07-12T00:37:14.867471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 1: a. Month-on-Month time series of sales count b. Seasonal decomposition of Month-on-Month sales count\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"markdown","source":"<span style=\"font-size:18px\">\n    Most of the sales were witnessed by very few neighbourhoods, mainly North Ames, College Creek, Old Town and Edwards followed by Somerset, Gilbert and Northridge Heights (fig 2)\n</span>","metadata":{}},{"cell_type":"code","source":"order=np.sort(df_train['Neighborhood'].unique())\nfig = sns.catplot(data=df_train, x='YrSold', kind='count', col='Neighborhood', col_wrap=5, col_order=order,color=(0.8,0.3,0.3), height=3, aspect=0.9);\ntitles=['Bloomington \\nHeights',\n        'Bluestem', \n        'Briardale',\n        'Brookside',\n        'Clear\\nCreek',\n        'College\\nCreek',\n        'Crawford',\n        'Edwards',\n        'Gilbert',\n        'IOWA DOT &\\nRail Road',\n        'Meadow\\nVillage',\n        'Mitchell',\n        'North\\nAmes',\n        'Northridge',\n        'Northpark\\nVilla',\n        'Northridge\\nHeights',\n        'Northwest\\nAmes',\n        'Old Town',\n        'South&West of\\nIowa State\\nUniversity',\n        'Sawyer',\n        'Sawyer\\nWest',\n        'Somerset',\n        'Stone\\nBrook',\n        'Timberland',\n        'Veenker']\nxticklabels=['\\'06', '\\'07', '\\'08', '\\'09', '\\'10']\nyticks=[0,20,40,60]\nfor i in fig.axes:\n    i.tick_params(axis='both', which='both', bottom=False, left=False, labelleft=False)\n    i.set_xticks(i.get_xticks(), labels=xticklabels, fontsize='xx-large')\n    for j in i.containers:\n        i.bar_label(j, fontsize='xx-large')\n    i.set_ylim(0,100)\n    #i.set_xticks(ticks=xticks, labels=xticklabels, fontsize='xx-large')\n    i.set_xlabel(\"Year Sold\", fontsize='xx-large', fontstretch='semi-expanded', fontweight='bold');\n    i.set_ylabel(\"Count\", fontsize='xx-large', fontweight='bold');\n    i.set_title(titles[list(fig.axes).index(i)],fontsize='xx-large', fontweight='bold', x=0.5, y=0.7);\n\n#fig.savefig('B2.jpeg', dpi=1200, bbox_inches='tight')","metadata":{"execution":{"iopub.status.busy":"2022-07-12T00:39:56.848723Z","iopub.execute_input":"2022-07-12T00:39:56.849585Z","iopub.status.idle":"2022-07-12T00:40:01.497277Z","shell.execute_reply.started":"2022-07-12T00:39:56.849529Z","shell.execute_reply":"2022-07-12T00:40:01.496461Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 2 : Histogram of annual sales decomposed by neighbourhood\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-size:18px\">\n    Ames, with population of 66,427 according to 2020 census, is more of a college town than a metropolitan area with very few industries/ institutions other than Iowa State University, Ames National Lab, USDA research centres [2][3]. These facts were also reflected in types of houses featured in the dataset. Out of 1460 houses, 1220 were single family detached and 157 were townhouse (fig 3a). Very few houses had more than 2 levels (fig 3b). More than half of the houses were one story and 3 out of every 4 houses were either one story or two story. More than 75 percent of the houses were in low-density residential zones and only around 15 percent of them were in medium or high-density residential zones (fig 3c). Only 10 properties were in commercial zone.\n</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(22,9),ncols=3, nrows=1)\n\n\n## Building Type\npalette = sns.color_palette('Set2', n_colors=len(df_train['BldgType'].unique()))\nhandles=[mpl.patches.Patch(color=i) for i in palette]\nlabels = ['Single family detached', \n          'Two family converted', \n          'Duplex', \n          'Townhouse end unit', \n          'Townhouse inside unit']\nax[0].tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)\nsns.countplot(data=df_train, x='BldgType', palette=palette, ax=ax[0]);\nfor i in ax[0].containers:\n    ax[0].bar_label(i, fontsize='xx-large', fontweight='bold');\n\nax[0].set_xlabel('Building Type',  fontsize='xx-large', fontweight='bold')\nax[0].set_ylabel('Count',  fontsize='xx-large', fontweight='bold')\nax[0].set_ylim(0,1400)\nax[0].legend(handles=handles, labels=labels, fontsize='xx-large');\nax[0].text(0,-0.05, r'(a)',transform=ax[0].transAxes, fontsize='xx-large');\n\n\n## House Style\npalette = sns.color_palette('Set2', n_colors=len(df_train['HouseStyle'].unique()))\nhandles=[mpl.patches.Patch(color=i) for i in palette]\nlabels = ['Two story', \n          'One story', \n          'One and half story \\n2nd level finished', \n          'One and half story \\n2nd level unfinished', \n          'Split Foyer', \n          'Split Level',\n          'Two and half story \\n2nd level unfinished', \n          'Two and half story \\n2nd level finished']\nax[1].tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)\nsns.countplot(data=df_train, x='HouseStyle', palette=palette, ax=ax[1]);\nfor i in ax[1].containers:\n    ax[1].bar_label(i, fontsize='xx-large', fontweight='bold');\n\nax[1].set_xlabel('House Style',  fontsize='xx-large', fontweight='bold')\nax[1].set_ylabel('Count',  fontsize='xx-large', fontweight='bold')\nax[1].set_ylim(0,900)\nax[1].legend(handles=handles, labels=labels, fontsize='xx-large');\nax[1].text(0,-0.05, r'(b)',transform=ax[1].transAxes, fontsize='xx-large');\n\n\n## Housing Zone\npalette = sns.color_palette('Set2', n_colors=len(df_train['BldgType'].unique()))\nhandles=[mpl.patches.Patch(color=i) for i in palette]\nlabels=['Residential \\nLow Density',\n        'Residential \\nMedium Density',\n        'Commercial',\n        'Floating Village \\nResidential',\n        'Residential \\nHigh Density']\nax[2].tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)\nsns.countplot(data=df_train, x='MSZoning', palette=palette, ax=ax[2]);\nfor i in ax[2].containers:\n    ax[2].bar_label(i, fontsize='xx-large', fontweight='bold');\n\nax[2].set_xlabel('Housing Zone',  fontsize='xx-large', fontweight='bold')\nax[2].set_ylabel('Count',  fontsize='xx-large', fontweight='bold')\nax[2].set_ylim(0,1400)\nax[2].legend(handles=handles, labels=labels, fontsize='xx-large');\nax[2].text(0,-0.05, r'(c)',transform=ax[2].transAxes, fontsize='xx-large');\n\n#fig.savefig('B3.jpeg', dpi=100, bbox_inches='tight')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T00:31:10.502211Z","iopub.execute_input":"2022-07-12T00:31:10.502513Z","iopub.status.idle":"2022-07-12T00:31:11.291130Z","shell.execute_reply.started":"2022-07-12T00:31:10.502482Z","shell.execute_reply":"2022-07-12T00:31:11.290159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 3 : Count plot of sales across a. building types b. House Style c. Housing Zone\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-size:18px\">\n    For most of the neighbourhoods the annual sales count was below 20 throughout the five-year period. Almost 90 percent of the properties had near flat land contour (fig 4a). The topographical map of Ames shows some hilly region with slight depression at central and southern parts of city [4]. This can be attributed to around 10 percent of the houses having either banked, hillside or depressed contour. More than 96 percent of the property lots had either regular shape or were slightly irregular (fig 4b). Less than a percent of lots were completely irregular (fig 4c). More than 70 percent property lots had inside locality, around 18 percent had corner locality and less than 4 percent had frontage exposure to 2 or 3 sides. Almost all the property had access to paved street (fig 4d).\n</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(16,16), ncols=2, nrows=2)\n\n##Contour piechart\ndata=df_train[\"LandContour\"].value_counts().values\nlabels=df_train[\"LandContour\"].value_counts().index\nexplode=(0, 0, 0, 0.3)\nax[0,0].pie(data, explode=explode, autopct='%1.2f%%', pctdistance=1.2, startangle=0,textprops={'fontsize':'xx-large'})\nax[0,0].set_title('Land Contour', fontsize='xx-large', y=0.9);\nax[0,0].legend(labels=['Near Flat', 'Hillside', 'Banked', 'Depression'], loc=1, bbox_to_anchor=(1.28,1), fontsize='xx-large');\nax[0,0].text(0.1,0.05,r'(a)',transform=ax[0,0].transAxes, fontsize='xx-large')\n\n\n##LotShape piechart\ndata=df_train[\"LotShape\"].value_counts().values\nlabels=df_train[\"LotShape\"].value_counts().index\nexplode=(0, 0, 0, 0.3)\nax[0,1].pie(data, explode=explode, autopct='%1.2f%%', pctdistance=1.2, startangle=210,textprops={'fontsize':'xx-large'})\nax[0,1].set_title('Lot Shape', fontsize='xx-large', y=0.9);\nax[0,1].legend(labels=['Regular', 'Slight\\nirregular', 'Moderately\\nirregular', 'Irregular'], loc=1, bbox_to_anchor=(1.35,1), fontsize='xx-large');\nax[0,1].text(0.1,0.05,r'(b)',transform=ax[0,1].transAxes, fontsize='xx-large')\n\n\n##LotConfig piechart \ndata=df_train[\"LotConfig\"].value_counts().values\nlabels=df_train[\"LotConfig\"].value_counts().index\nexplode=(0, 0, 0, 0.3, 0.4)\nax[1,0].pie(data, explode=explode, autopct='%1.2f%%', pctdistance=1.2, startangle=0,textprops={'fontsize':'xx-large'})\nax[1,0].set_title('Lot Configuration', fontsize='xx-large', y=0.9);\nax[1,0].legend(labels=['Inside', 'Corner', 'Cul-de-sac', '2-side\\nfrontage', '3-side\\nfrontage'], loc=1, bbox_to_anchor=(1.3,1.1), fontsize='xx-large');\nax[1,0].text(0.1,0.05,r'(c)',transform=ax[1,0].transAxes, fontsize='xx-large')\n\n\n##Street piechart\ndata=df_train[\"Street\"].value_counts().values\nlabels=df_train[\"Street\"].value_counts().index\nexplode=(0, 0.05)\nax[1,1].pie(data, explode=explode, autopct='%1.2f%%', pctdistance=1.2, startangle=30,textprops={'fontsize':'xx-large'})\nax[1,1].set_title('Paved Street?', fontsize='xx-large', y=0.9);\nax[1,1].legend(labels=['Paved', 'Gravel'], loc=1, bbox_to_anchor=(1.23,1.1), fontsize='xx-large');\nax[1,1].text(0.1,0.05,r'(d)',transform=ax[1,1].transAxes, fontsize='xx-large');\n\n#fig.savefig('B4.jpeg', dpi=1200, bbox_inches='tight')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T00:57:59.339245Z","iopub.execute_input":"2022-07-12T00:57:59.339595Z","iopub.status.idle":"2022-07-12T00:57:59.975483Z","shell.execute_reply.started":"2022-07-12T00:57:59.339563Z","shell.execute_reply":"2022-07-12T00:57:59.974451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 4: Pie chart of property features a. Land Contour b. Lot Shape c. Lot Configuration and d. Street Pavement\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-size:18px\">\n    It snows from Nov to Mar in Ames [3] and also, the tornado index is 337.09 [5]. This justifies the disproportionately high number of properties with Gable and Hip roofing style and shingled roofs (fig 5a, 5b) [6]. Furthermore, each and every house had heating system since this is an essential amenity in cold regions. Almost 98 percent of the houses were equipped with Gas forced warm air furnace.\n</p>","metadata":{}},{"cell_type":"code","source":"##Note: While plotting multiple seaborn subplots its better to use sns.countplot(ax=ax) than ax = sns.countplot() \n#the latter will plot all the subplots and their annotations in the last subplot figure\nfig, ax=plt.subplots(3,1,figsize=(12,13.5))\n\n##Roof Style countplot\npalette=sns.color_palette('Set2', n_colors=len(df_train['RoofStyle'].unique()))\nhandles=[Patch(color=i) for i in palette]\nlabels=['Gable','Hip','Gambrel','Mansard','Flat','Shed']\nax[0].tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False)\nsns.countplot(data=df_train, y='RoofStyle', palette=palette,ax=ax[0]);\nax[0].set_xlim(0,2000)\nax[0].set_yticks(ax[0].get_yticks(), ax[0].get_yticklabels(), fontsize='large')\nfor i in ax[0].containers:\n    ax[0].bar_label(i, fontsize='large', fontweight='bold');\n\nax[0].set_ylabel(\"Roofing Style\", fontsize='large', fontstretch='semi-expanded', fontweight='bold');\nax[0].set_xlabel(\"Count\", fontsize='large', fontweight='bold');\nax[0].legend(handles=handles, labels=labels, fontsize='large', bbox_to_anchor=(1,0.7))\nax[0].text(0,-0.05, r'(a)',transform=ax[0].transAxes, fontsize='large')\n\n\n##Roofing Materials countplot\npalette=sns.color_palette('Set2', n_colors=len(df_train['RoofMatl'].unique()))\nhandles=[Patch(color=i) for i in palette]\nlabels=['Standard (Composite) Shingle', 'Wood Shingles', 'Metal', 'Wood Shakes', 'Membrane', 'Tar & Gravel', 'Roll', 'Clay Tile']\nax[1].tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False)\nsns.countplot(data=df_train, y='RoofMatl', palette=palette, ax=ax[1]);\nax[1].set_xlim(0,2000)\nax[1].set_yticks(ax[1].get_yticks(), ax[1].get_yticklabels(), fontsize='large')\nfor i in ax[1].containers:\n    ax[1].bar_label(i, fontsize='large', fontweight='bold');\n\nax[1].set_ylabel(\"Roofing Material\", fontsize='large', fontstretch='semi-expanded', fontweight='bold');\nax[1].set_xlabel(\"Count\", fontsize='large', fontweight='bold');\nax[1].legend(handles=handles, labels=labels, fontsize='large', bbox_to_anchor=(1,0.8))\nax[1].text(0,-0.05, r'(b)',transform=ax[1].transAxes, fontsize='large')\n\n\n##Heating countplot\npalette=sns.color_palette('Set2',n_colors=len(df_train['Heating'].unique()))\nhandles=[Patch(color=i) for i in palette]\nlabels=['Gas forced warm air furnace', 'Gas hot water/ steam heat', 'Gravity furnace', 'Wall furnace', 'Hot water/ steam heat other than gas', 'Floor Furnace']\nax[2].tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False)\nsns.countplot(data=df_train, y='Heating', palette=palette, ax=ax[2]);\nax[2].set_xlim(0,2000)\nax[2].set_yticks(ax[2].get_yticks(), ax[2].get_yticklabels(), fontsize='large')\nfor i in ax[2].containers:\n    ax[2].bar_label(i, fontsize='large', fontweight='bold');\n\nax[2].set_ylabel(\"Heating Systems\", fontsize='large', fontstretch='semi-expanded', fontweight='bold');\nax[2].set_xlabel(\"Count\", fontsize='large', fontweight='bold');\n\nax[2].legend(handles=handles, labels=labels, fontsize='large', bbox_to_anchor=(1,0.7))\nax[2].text(0,-0.05, r'(c)',transform=ax[2].transAxes, fontsize='large');\n\n#fig.savefig('B5.jpeg', dpi=1200, bbox_inches='tight')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T00:59:40.992304Z","iopub.execute_input":"2022-07-12T00:59:40.992619Z","iopub.status.idle":"2022-07-12T00:59:42.036606Z","shell.execute_reply.started":"2022-07-12T00:59:40.992587Z","shell.execute_reply":"2022-07-12T00:59:42.035727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 5: Count plot representing distribution of a. Roofing Style b. Roofing Material c. Heating System\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-size:18px\">\n    More than half of the houses had fireplaces (fig 6a). Almost 95 percent of them had a garage and more than 97 percent had a basement (fig 6b, 6c). The overall weather and temperature profile of Ames is more characteristic of a tundra than a tropical region. This has translated in less than half a percent of homes having a pool (fig 6d). All the properties except one were equipped with all public utilities (fig 6e). Less than 4 percent of the properties had additional amenities like shed, 2nd garage and tennis court (fig 6f).\n</p>","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(8,12), ncols=2, nrows=3)\n\n\n##Fireplace\ndata=df_train[\"HasFireplace\"].value_counts().values\nlabels=df_train[\"HasFireplace\"].value_counts().index\nexplode=(0, 0.05)\nax[0,0].pie(data, explode=explode, labels=labels, labeldistance=1, autopct='%1.2f%%', pctdistance=0.6, startangle=90,textprops={'fontsize':'x-large'})\nax[0,0].set_title('Has Fireplace?', fontsize='xx-large', y=0.9);\nax[0,0].text(0,0,r'(a)',transform=ax[0,0].transAxes)\n\n\n##Garage\ndata=df_train[\"HasGarage\"].value_counts().values\nlabels=df_train[\"HasGarage\"].value_counts().index\nexplode=(0, 0.1)\nax[0,1].pie(data, explode=explode, labels=labels, labeldistance=1, autopct='%1.2f%%', pctdistance=0.6, textprops={'fontsize':'x-large'})\nax[0,1].set_title('Has Garage?', fontsize='xx-large', y=0.9);\nax[0,1].text(0,0,r'(b)',transform=ax[0,1].transAxes)\n\n\n##Basement\ndata=df_train[\"HasBasement\"].value_counts().values\nlabels=df_train[\"HasBasement\"].value_counts().index\nexplode=(0, 0.1)\nax[1,0].pie(data, explode=explode, labels=labels, labeldistance=1, autopct='%1.2f%%', pctdistance=0.6, textprops={'fontsize':'x-large'})\nax[1,0].set_title('Has Basement?', fontsize='xx-large', y=0.9);\nax[1,0].text(0,0,r'(c)',transform=ax[1,0].transAxes)\n\n\n##Pool\ndata=df_train[\"HasPool\"].value_counts().values\nlabels=df_train[\"HasPool\"].value_counts().index\nexplode=(0, 0.1)\nax[1,1].pie(data, explode=explode, labels=labels, labeldistance=1, autopct='%1.2f%%', pctdistance=0.6, textprops={'fontsize':'x-large'})\nax[1,1].set_title('Has Pool?', fontsize='xx-large', y=0.9);\nax[1,1].text(0,0,r'(d)',transform=ax[1,1].transAxes)\n\n\n##Utilities\ndata=df_train[\"Utilities\"].value_counts().values\nlabels=df_train[\"Utilities\"].value_counts().index\nexplode=(0, 0.2)\nax[2,0].pie(data, explode=explode, autopct='%1.2f%%', pctdistance=0.6, startangle=0,textprops={'fontsize':'x-large'})\nax[2,0].set_title('Has Utilities?', fontsize='xx-large', y=0.9);\nax[2,0].legend(labels=['All Utilities', 'Elec and Gas'], loc=4, bbox_to_anchor=(1.2,0))\nax[2,0].text(0,0,r'(e)',transform=ax[2,0].transAxes)\n\n\n##Misc Features\ndata=df_train[\"HasAmenities\"].value_counts().values\nlabels=df_train[\"HasAmenities\"].value_counts().index\nexplode=(0, 0.1)\nax[2,1].pie(data, labels=labels, labeldistance=1, explode=explode ,autopct='%1.2f%%', pctdistance=0.6, startangle=0,textprops={'fontsize':'x-large'})\nax[2,1].set_title('Has Amenities?', fontsize='xx-large', y=0.9);\nax[2,1].text(0,0,r'(f)',transform=ax[2,1].transAxes);\n\n#fig.savefig('B6.jpeg', dpi=1200, bbox_inches='tight')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T01:02:13.519484Z","iopub.execute_input":"2022-07-12T01:02:13.520118Z","iopub.status.idle":"2022-07-12T01:02:14.085849Z","shell.execute_reply.started":"2022-07-12T01:02:13.520061Z","shell.execute_reply":"2022-07-12T01:02:14.084957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 6: Pie chart representing present/absence of a. Fireplace b. Garage c. Basement d. Pool e. Utilities f. Amenities\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-size:18px\">\n    Average selling price of the dataset was 180921.2 US Dollars with a standard deviation of 79442.5 US Dollars (fig 7a). The distribution of sales price feature was close to normal distribution and was skewed to right. The skewness was reflected in the Quantile – Quantile plot where empirical values vs theoretical quantile graph was concaved upward; it was flatter than ideal line before median value and it became steeper after that (fig 7b). The skewness of this distribution was 1.88. The most common technique to remove skewness is to use log transform of the given feature values and observe the distribution of log values. To avoid the occurrence of inf or highly negative log values, log1p transform was used (p  log(1+p)). The distribution of the log values was much closer to the normal distribution than the regular scale values (fig 7c). The QQ plot also reflect the near normal distribution with right skewness reduced to 0.12 (fig 7d).  More than a percent of houses had selling price 3 standard deviations above mean which also contributed to the right skewness.\n</p>","metadata":{}},{"cell_type":"code","source":"gs_kw=dict(width_ratios=[1.5,1])\nfig, ax = plt.subplot_mosaic([['ul','ur'],['ll','lr']],\n                             figsize=(15,12), gridspec_kw=gs_kw)\n\n##SalesPrice Distribution\nyticks=[50,100,150]\nxticks=[200000,400000,600000]\nxticklabels=['200k', '400k', '600k']\ntext= f'Summary\\n\\u03BC : {np.round(SalePrice.mean(),2)} \\n\\u03C3 : {np.round(SalePrice.std(),2)}'\nax['ul'].tick_params(bottom=False, left=False)\nsns.histplot(SalePrice, ax=ax['ul'], kde=True);\nax['ul'].set_xticks(ticks=xticks, labels=xticklabels, fontsize='x-large')\nax['ul'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['ul'].set_xlabel('Sales Price', fontsize='x-large', fontweight='bold')\nax['ul'].set_ylabel('Sales Count', fontsize='x-large', fontweight='bold')\nax['ul'].text(0.7,0.8, text, transform=ax['ul'].transAxes, fontsize='x-large', fontweight='bold')\nax['ul'].text(-0.05,-0.05, r'(a)', transform=ax['ul'].transAxes, fontsize='x-large')\n\n\n\n##SalePrice QQ plot\nxticks=[-3,-2,-1,0,1,2,3]\nyticks=[200000,400000,600000]\nyticklabels=['200k','400k','600k']\ntext=f'Skewness : {np.round(stats.skew(SalePrice),2)}'\nax['ur'].tick_params(bottom=False, left=False)\nstats.probplot(SalePrice, plot=ax['ur']);\nax['ur'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['ur'].set_yticks(ticks=yticks, labels=yticklabels, fontsize='x-large');\nax['ur'].set_xlabel('Theoretical quantiles', fontsize='x-large', fontweight='bold')\nax['ur'].set_ylabel('Ordered Values', fontsize='x-large', fontweight='bold')\nax['ur'].text(0.1,0.9, text, transform=ax['ur'].transAxes, fontsize='x-large', fontweight='bold')\nax['ur'].set_title('')\nax['ur'].text(-0.05,-0.05, r'(b)', transform=ax['ur'].transAxes, fontsize='x-large')\n\n\n\n##Log SalesPrice Distribution\nxticks=[11.0,12.0,13.0]\nyticks=[40,80,120]\ntext= f'Summary\\n\\u03BC : {np.round(np.log(SalePrice).mean(),2)} \\n\\u03C3 : {np.round(np.log(SalePrice).std(),2)}'\nax['ll'].tick_params(bottom=False, left=False)\nsns.histplot(np.log(SalePrice), ax=ax['ll'], kde=True);\nax['ll'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['ll'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['ll'].set_xlabel('Sales Price (in log)', fontsize='x-large', fontweight='bold')\nax['ll'].set_ylabel('Sales Count', fontsize='x-large', fontweight='bold')\nax['ll'].text(0.75,0.8, text, transform=ax['ll'].transAxes, fontsize='x-large', fontweight='bold')\nax['ll'].text(-0.05,-0.05, r'(b)', transform=ax['ll'].transAxes, fontsize='x-large')\n\n\n\n##Log SalePrice QQ plot\nxticks=[-3,-2,-1,0,1,2,3]\nyticks=[11.0,12.0,13.0]\ntext=f'Skewness : {np.round(stats.skew(np.log(SalePrice)),2)}'\nax['lr'].tick_params(bottom=False, left=False)\nstats.probplot(np.log(SalePrice), plot=ax['lr']);\nax['lr'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['lr'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large');\nax['lr'].set_xlabel('Theoretical quantiles', fontsize='x-large', fontweight='bold');\nax['lr'].set_ylabel('Ordered Values', fontsize='x-large', fontweight='bold');\nax['lr'].text(0.1,0.9, text, transform=ax['lr'].transAxes, fontsize='x-large', fontweight='bold');\nax['lr'].set_title('');\nax['lr'].text(-0.05,-0.05, r'(d)', transform=ax['lr'].transAxes, fontsize='x-large');\n\n#fig.savefig('B7.jpeg', dpi=1200, bbox_inches='tight')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T01:03:54.702587Z","iopub.execute_input":"2022-07-12T01:03:54.702877Z","iopub.status.idle":"2022-07-12T01:03:55.611313Z","shell.execute_reply.started":"2022-07-12T01:03:54.702839Z","shell.execute_reply":"2022-07-12T01:03:55.610471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 7: a. Distribution of Sales Price b. Q - Q plot of distribution of Sales Price c. Distribution of Sales Price on log scale d. Q - Q plot of distribution of Sales Price on log scale\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-size:18px\">\n    If a numerical variable spans over a semi-infinite range, from 0 to ∞, it is more possible to have right skewness than left skewness. The analysis of other important numerical features like ground living area, lot size, basement area added evidence to this hypothesis. The ground living area, basement area had right skewness of 1.37 and 1.52 respectively (fig 8a, 8b, 8c, 8d). Since some of the houses did not had basement, the frequency count at 0 was high. Few houses had lot area greater than 40000 sq ft. These outliers spiked the right skewness of the lot size feature to 12.2 (fig 8d, 8f).\n</p>","metadata":{}},{"cell_type":"code","source":"gs_kw=dict(width_ratios=[1.2,1])\nfig, ax = plt.subplot_mosaic([['ul','ur'],['ml','mr'],['ll','lr']],\n                             figsize=(15,18), gridspec_kw=gs_kw)\n\n##Ground Living Area Distribution\ndata=df_train['GrLivArea']\nxticks=[1000,2000,3000,4000,5000]\nyticks=[40,80,120]\ntext= f'Summary\\n\\u03BC : {np.round(data.mean(),2)} \\n\\u03C3 : {np.round(data.std(),2)}'\nax['ul'].tick_params(bottom=False, left=False)\nsns.histplot(data=data,ax=ax['ul'], kde=True);\nax['ul'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['ul'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['ul'].set_xlabel('Ground Living Area (in Sq Ft)', fontsize='x-large', fontweight='bold')\nax['ul'].set_ylabel('Sales Count', fontsize='x-large', fontweight='bold')\nax['ul'].text(0.7,0.8, text, transform=ax['ul'].transAxes, fontsize='x-large', fontweight='bold')\nax['ul'].text(-0.05,-0.05, r'(a)', transform=ax['ul'].transAxes, fontsize='x-large')\n\n\n\n##Gross Living Area QQ plot\nxticks=[-3,-2,-1,0,1,2,3]\nyticks=[1000,2000,3000,4000,5000]\ntext=f'Skewness : {np.round(stats.skew(data),2)}'\nax['ur'].tick_params(bottom=False, left=False)\nstats.probplot(data, plot=ax['ur']);\nax['ur'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['ur'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['ur'].set_xlabel('Theoretical quantiles', fontsize='x-large', fontweight='bold')\nax['ur'].set_ylabel('Ordered Values', fontsize='x-large', fontweight='bold')\nax['ur'].text(0.1,0.9, text, transform=ax['ur'].transAxes, fontsize='x-large', fontweight='bold')\nax['ur'].set_title('')\nax['ur'].text(-0.05,-0.05, r'(b)', transform=ax['ur'].transAxes, fontsize='x-large')\n\n\n\n##Total Basement Area Distribution\ndata=df_train['TotalBsmtSF']\nxticks=[0,1000,2000,3000,4000,5000,6000]\nyticks=[40,80,120]\ntext= 'Summary\\n\\u03BC : {} \\n\\u03C3 : {}'.format(np.round(data.mean(),2), np.round(data.std(),2))\nax['ml'].tick_params(bottom=False, left=False)\nsns.histplot(data=data,ax=ax['ml'], kde=True)\nax['ml'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['ml'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['ml'].set_yticks(ticks=yticks, labels=yticks)\nax['ml'].set_xlabel('Basement Area (in Sq Ft)', fontsize='x-large', fontweight='bold')\nax['ml'].set_ylabel('Sales Count', fontsize='x-large', fontweight='bold')\nax['ml'].text(0.7,0.8, text, transform=ax['ml'].transAxes, fontsize='x-large', fontweight='bold')\nax['ml'].text(-0.05,-0.05, r'(c)', transform=ax['ml'].transAxes, fontsize='x-large')\n\n\n\n##Total Basement Area QQ plot\nxticks=[-3,-2,-1,0,1,2,3]\nyticks=[0,1000,2000,3000,4000,5000,6000]\ntext='Skewness : {}'.format(np.round(stats.skew(data),2))\nax['mr'].tick_params(bottom=False, left=False)\nstats.probplot(data, plot=ax['mr'])\nax['mr'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['mr'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['mr'].set_xlabel('Theoretical quantiles', fontsize='x-large', fontweight='bold')\nax['mr'].set_ylabel('Ordered Values', fontsize='x-large', fontweight='bold')\nax['mr'].text(0.1,0.9, text, transform=ax['mr'].transAxes, fontsize='x-large', fontweight='bold')\nax['mr'].set_title('')\nax['mr'].text(-0.05,-0.05, r'(d)', transform=ax['mr'].transAxes, fontsize='x-large')\n\n\n\n##Lot Area Distribution\ndata=df_train['LotArea']\nxticks=[0,10000,30000,50000,100000,150000,200000]\nxticklabels=['0','10k','30k','50k','100k','150k','200k']\nyticks=[40,80,120,160]\ntext= 'Summary\\n\\u03BC : {} \\n\\u03C3 : {}'.format(np.round(data.mean(),2), np.round(data.std(),2))\nax['ll'].tick_params(bottom=False, left=False)\nsns.histplot(data=data,ax=ax['ll'], kde=True);\nax['ll'].set_xticks(ticks=xticks, labels=xticklabels, fontsize='x-large')\nax['ll'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['ll'].set_xlabel('Lot Size (in Sq Ft)', fontsize='x-large', fontweight='bold')\nax['ll'].set_ylabel('Sales Count', fontsize='x-large', fontweight='bold')\nax['ll'].text(0.7,0.8, text, transform=ax['ll'].transAxes, fontsize='x-large', fontweight='bold')\nax['ll'].text(-0.05,-0.05, r'(e)', transform=ax['ll'].transAxes, fontsize='x-large');\n\n\n\n##Lot Area QQ plot\nxticks=[-3,-2,-1,0,1,2,3]\nyticks=[0,10000,30000,50000,100000,150000,200000]\nyticklabels=['0','10k','30k','50k','100k','150k','200k']\ntext='Skewness : {}'.format(np.round(stats.skew(data),2))\nax['lr'].tick_params(bottom=False, left=False)\nstats.probplot(data, plot=ax['lr'])\nax['lr'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['lr'].set_yticks(ticks=yticks, labels=yticklabels, fontsize='x-large')\nax['lr'].set_xlabel('Theoretical quantiles', fontsize='x-large', fontweight='bold')\nax['lr'].set_ylabel('Ordered Values', fontsize='x-large', fontweight='bold')\nax['lr'].text(0.1,0.9, text, transform=ax['lr'].transAxes, fontsize='x-large', fontweight='bold')\nax['lr'].set_title('')\nax['lr'].text(-0.05,-0.05, r'(f)', transform=ax['lr'].transAxes, fontsize='x-large');\n\n#fig.savefig('B8.jpeg', dpi=1200, bbox_inches='tight')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T01:04:50.728604Z","iopub.execute_input":"2022-07-12T01:04:50.728878Z","iopub.status.idle":"2022-07-12T01:04:53.000673Z","shell.execute_reply.started":"2022-07-12T01:04:50.728849Z","shell.execute_reply":"2022-07-12T01:04:52.999784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 8 : a. Distribution of Ground Living Area b. Q - Q plot of distribution of Ground Living Area c. Distribution of Basement Area d. Q - Q plot of distribution of Basement Area e. Distribution of Lot Size f. Q -Q plot of distribution of Lot Size\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-size:18px\">\n    Log1p transform made the ground living area distribution almost normal with small left skewness of 0.01 (fig 9a, 9b). However, the same transform brought about a huge shift from slight right skewness on normal scale to large left skewness on logscale (fig 9c, 9d). Careful inspection of the Q – Q plot of the basement area (normal scale) shows that the change of basement area from no-basement property to a property with basement is not smooth and gradual but rather abrupt and steep since no - basement property had zero basement area and most of the properties with basement had basement area similar to ground living area (which is quite obvious given ground being built on top of basement). Hence, in figure 8c, we see a tall bar at zero followed by really short bars eventually followed by taller ones. In log1p transform all the datapoints with zero basement area are clustered to zero and other data points form a near gaussian distribution centered around e6.75. This caused left skewness of 5.15 in the distribution. The lot size distribution had a slight left skewness of 0.14 after log1p transform (fig 9e, 9f). This is significant improvement.\n</p>","metadata":{}},{"cell_type":"code","source":"gs_kw=dict(width_ratios=[1.2,1])\nfig, ax = plt.subplot_mosaic([['ul','ur'],['ml','mr'],['ll','lr']],\n                             figsize=(15,18), gridspec_kw=gs_kw)\n\n##Ground Living Area Distribution\ndata=np.log1p(df_train['GrLivArea'])\nxticks=[6.0,6.5,7.0,7.5,8.0,8.5]\nyticks=[40,80,120,160]\ntext= f'Summary\\n\\u03BC : {np.round(data.mean(),2)} \\n\\u03C3 : {np.round(data.std(),2)}'\nax['ul'].tick_params(bottom=False, left=False)\nsns.histplot(data=data,ax=ax['ul'], kde=True);\nax['ul'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['ul'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['ul'].set_xlabel('Ground Living Area (in log Sq Ft)', fontsize='x-large', fontweight='bold')\nax['ul'].set_ylabel('Sales Count', fontsize='x-large', fontweight='bold')\nax['ul'].text(0.75,0.8, text, transform=ax['ul'].transAxes, fontsize='x-large', fontweight='bold')\nax['ul'].text(-0.05,-0.05, r'(a)', transform=ax['ul'].transAxes, fontsize='x-large')\n\n\n\n##Gross Living Area QQ plot\nxticks=[-3,-2,-1,0,1,2,3]\nyticks=[6.0,6.5,7.0,7.5,8.0,8.5]\ntext=f'Skewness : {np.round(stats.skew(data),2)}'\nax['ur'].tick_params(bottom=False, left=False)\nstats.probplot(data, plot=ax['ur']);\nax['ur'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['ur'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['ur'].set_xlabel('Theoretical quantiles', fontsize='x-large', fontweight='bold')\nax['ur'].set_ylabel('Ordered Values', fontsize='x-large', fontweight='bold')\nax['ur'].text(0.1,0.9, text, transform=ax['ur'].transAxes, fontsize='x-large', fontweight='bold')\nax['ur'].set_title('')\nax['ur'].text(-0.05,-0.05, r'(b)', transform=ax['ur'].transAxes, fontsize='x-large')\n\n\n\n##Total Basement Area Distribution\ndata=np.log1p(df_train['TotalBsmtSF'])\nxticks=[0,2,4,6,8]\nyticks=[40,80,120,160]\ntext= 'Summary\\n\\u03BC : {} \\n\\u03C3 : {}'.format(np.round(data.mean(),2), np.round(data.std(),2))\nax['ml'].tick_params(bottom=False, left=False)\nsns.histplot(data=data,ax=ax['ml'], kde=True)\nax['ml'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['ml'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['ml'].set_xlabel('Basement Area (in log Sq Ft)', fontsize='x-large', fontweight='bold')\nax['ml'].set_ylabel('Sales Count', fontsize='x-large', fontweight='bold')\nax['ml'].text(0.45,0.8, text, transform=ax['ml'].transAxes, fontsize='x-large', fontweight='bold')\nax['ml'].text(-0.05,-0.05, r'(c)', transform=ax['ml'].transAxes, fontsize='x-large')\n\n\n\n##Total Basement Area QQ plot\nxticks=[-3,-2,-1,0,1,2,3]\nyticks=[0,2,4,6,8]\ntext='Skewness : {}'.format(np.round(stats.skew(data),2))\nax['mr'].tick_params(bottom=False, left=False)\nstats.probplot(data, plot=ax['mr'])\nax['mr'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['mr'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['mr'].set_xlabel('Theoretical quantiles', fontsize='x-large', fontweight='bold')\nax['mr'].set_ylabel('Ordered Values', fontsize='x-large', fontweight='bold')\nax['mr'].text(0.1,0.9, text, transform=ax['mr'].transAxes, fontsize='x-large', fontweight='bold')\nax['mr'].set_title('')\nax['mr'].text(-0.05,-0.05, r'(d)', transform=ax['mr'].transAxes, fontsize='x-large')\n\n\n\n##Lot Area Distribution\ndata=np.log1p(df_train['LotArea'])\nxticks=[7,8,9,10,11,12]\nyticks=[40,80,120]\ntext= 'Summary\\n\\u03BC : {} \\n\\u03C3 : {}'.format(np.round(data.mean(),2), np.round(data.std(),2))\nax['ll'].tick_params(bottom=False, left=False)\nsns.histplot(data=data,ax=ax['ll'], kde=True)\nax['ll'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['ll'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['ll'].set_yticks(ticks=yticks, labels=yticks)\nax['ll'].set_xlabel('Lot Size (in log Sq Ft)', fontsize='x-large', fontweight='bold')\nax['ll'].set_ylabel('Sales Count', fontsize='x-large', fontweight='bold')\nax['ll'].text(0.75,0.8, text, transform=ax['ll'].transAxes, fontsize='x-large', fontweight='bold')\nax['ll'].text(-0.05,-0.05, r'(e)', transform=ax['ll'].transAxes, fontsize='x-large')\n\n\n\n##Lot Area QQ plot\nxticks=[-3,-2,-1,0,1,2,3]\nyticks=[7,8,9,10,11,12]\ntext='Skewness : {}'.format(np.round(stats.skew(data),2))\nax['lr'].tick_params(bottom=False, left=False)\nstats.probplot(data, plot=ax['lr'])\nax['lr'].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax['lr'].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax['lr'].set_xlabel('Theoretical quantiles', fontsize='x-large', fontweight='bold')\nax['lr'].set_ylabel('Ordered Values', fontsize='x-large', fontweight='bold')\nax['lr'].text(0.1,0.9, text, transform=ax['lr'].transAxes, fontsize='x-large', fontweight='bold')\nax['lr'].set_title('')\nax['lr'].text(-0.05,-0.05, r'(f)', transform=ax['lr'].transAxes, fontsize='x-large')\n\nplt.show()\n#fig.savefig('B9.jpeg', dpi=1200, bbox_inches='tight')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-12T01:07:25.724190Z","iopub.execute_input":"2022-07-12T01:07:25.725139Z","iopub.status.idle":"2022-07-12T01:07:27.119412Z","shell.execute_reply.started":"2022-07-12T01:07:25.725096Z","shell.execute_reply":"2022-07-12T01:07:27.118443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 9 : a. Distribution of Ground Living Area on log scale b. Q - Q plot of distribution of Ground Living Area on log scale c. Distribution of Basement Area d. Q - Q plot of distribution of Basement Area on log scale e. Distribution of Lot Size on log scale f. Q -Q plot of distribution of Lot Size on log scale\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-size:18px\">\n    Furthermore, some of the features, believed to be impacting sales, were studied. The regression plot of Sales Price vs Ground Living Area reveals partial monotonic behavior where the houses with larger \nground living area are more likely to be expensive than houses with smaller ground living area (fig 10a). The solid blue straight line represents the linear regression model that fits the data with light blue shaded region being the 95 percent confidence interval (CI). Since the spread of the data increases as we move in positive direction along both the variable axes, the confidence interval also gets wider simultaneously. When the same two features were plotted on log1p scale the extent of linearity increased considerably. Few datapoints had abnormally low selling price compared to datapoints with similar ground living area (fig 10b). Except for those points almost all the datapoints were clustered around the linear regression model. The CI of the regression model was also consistently narrow.\nAnother such feature, lot size was plotted against the sales price. Due to few irregularly shaped lots with exceptionally large size the linear regression model failed to accommodate the underlying data (fig 10c). Since these large lots had really low sales prices the CI of the regression model widened sharply in the positive direction of both axes. Log1p transform of the two did help in bringing more monotonous and linear relation between the variable but still the spread of datapoints was not consistent (fig 10d). Removing the datapoints with abnormal lot sizes and repeating the line fitting might reveal different results.\n</p>","metadata":{}},{"cell_type":"code","source":"fig, ax=plt.subplots(figsize=(16,16), ncols=2, nrows=2)\n\n\n##Sales Price vs Ground Living Area relation\nxticks=[1000,2000,3000,4000,5000]\nyticks=[100000,300000,500000,700000]\nyticklabels=['100k','300k','500k','700k']\nax[0,0].tick_params(bottom=False, left=False)\nsns.regplot(data=df_train, x='GrLivArea', y='SalePrice', ax=ax[0,0])\nax[0,0].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax[0,0].set_yticks(ticks=yticks, labels=yticklabels, fontsize='x-large')\nax[0,0].set_xlabel('Ground Living Area (in Sq Ft)', fontsize='x-large', fontweight='bold')\nax[0,0].set_ylabel('Sales Price', fontsize='x-large', fontweight='bold')\n\n##Sales Price vs Ground Living Area relation in log scale\nxticks=[6.0,6.5,7.0,7.5,8.0,8.5]\nyticks=[11,12,13]\ndata=pd.DataFrame()\ndata['GrLivArea']=np.log1p(df_train['GrLivArea'])\ndata['SalePrice']=np.log1p(df_train['SalePrice'])\nax[0,1].tick_params(bottom=False, left=False)\nsns.regplot(data=data, x='GrLivArea', y='SalePrice', ax=ax[0,1])\nax[0,1].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax[0,1].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax[0,1].set_xlabel('Ground Living Area (in log Sq Ft)', fontsize='x-large', fontweight='bold')\nax[0,1].set_ylabel('Sales Price (in logscale)', fontsize='x-large', fontweight='bold')\n\n\n\n##Sales Price vs Lot Size relation\nxticks=[5000,50000,100000,150000,200000]\nyticks=[200000,400000,600000,800000, 1000000]\nxticklabels=['5k','50k','100k','150k','200k']\nyticklabels=['200k','400k','600k','800k', '1M']\nax[1,0].tick_params(bottom=False, left=False)\nsns.regplot(data=df_train, x='LotArea', y='SalePrice', ax=ax[1,0])\nax[1,0].set_xticks(ticks=xticks, labels=xticklabels, fontsize='x-large')\nax[1,0].set_yticks(ticks=yticks, labels=yticklabels, fontsize='x-large')\nax[1,0].set_xlabel('Lot Size (in Sq Ft)', fontsize='x-large', fontweight='bold')\nax[1,0].set_ylabel('Sales Price', fontsize='x-large', fontweight='bold')\n\n\n##Sales Price vs Lot Size relation in log scale\nxticks=[7,8,9,10,11,12]\nyticks=[11,12,13]\ndata=pd.DataFrame()\ndata['LotArea']=np.log1p(df_train['LotArea'])\ndata['SalePrice']=np.log1p(df_train['SalePrice'])\nax[1,1].tick_params(bottom=False, left=False)\nsns.regplot(data=data, x='LotArea', y='SalePrice', ax=ax[1,1])\nax[1,1].set_xticks(ticks=xticks, labels=xticks, fontsize='x-large')\nax[1,1].set_yticks(ticks=yticks, labels=yticks, fontsize='x-large')\nax[1,1].set_xlabel('Lot Size (in log Sq Ft)', fontsize='x-large', fontweight='bold')\nax[1,1].set_ylabel('Sales Price (in logscale)', fontsize='x-large', fontweight='bold')\n\nplt.show()\n\n#fig.savefig('B10.jpeg', dpi=1200, bbox_inches='tight')","metadata":{"execution":{"iopub.status.busy":"2022-03-24T21:06:11.028066Z","iopub.execute_input":"2022-03-24T21:06:11.028518Z","iopub.status.idle":"2022-03-24T21:06:27.57717Z","shell.execute_reply.started":"2022-03-24T21:06:11.028474Z","shell.execute_reply":"2022-03-24T21:06:27.57616Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 10: a. Regression plot between Sales Price and Ground Living Area b. Regression plot between log of Sale Price and log Ground Living Area c. Regression plot between Sales Price and Lot Size d. Regression plot between log of Sale Price and log Lot Size\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"markdown","source":"<p style=\"font-size:18px\">\n    The regression plot between sales price and ground living area was further decomposed by neighborhoods (fig 11). In almost all the neighborhood datapoints were clustered around a small range of sales price and ground living area and rendered linear behavior. However, the extent of linearity and gradient of the regression line varied across the neighborhood. In Brookside, College Creek, Meadow Village, South & West of Iowa State University the Sales Price was more sensitive to the ground living area than in other neighborhoods. For all the neighborhoods the gradient of regression line was almost similar when fitted on log1p scale (fig 12). The CI of all the regression line improved for majority of the neighborhoods except the places where sales prices and ground living 2area were very low.\n</p>    ","metadata":{}},{"cell_type":"code","source":"data=df_train\nfig=sns.lmplot(data=data, x='GrLivArea', y='SalePrice', col='Neighborhood', col_wrap=5, height=3, aspect=0.9)\ntitles=['Bloomington \\nHeights',\n        'Bluestem', \n        'Briardale',\n        'Brookside',\n        'Clear \\nCreek',\n        'College \\nCreek',\n        'Crawford',\n        'Edwards',\n        'Gilbert',\n        'IOWA DOT & \\nRail Road',\n        'Meadow \\nVillage',\n        'Mitchell',\n        'North \\nAmes',\n        'Northridge',\n        'Northpark \\nVilla',\n        'Northridge \\nHeights',\n        'Northwest \\nAmes',\n        'Old Town',\n        'South&West\\nof ISU',\n        'Sawyer',\n        'Sawyer \\nWest',\n        'Somerset',\n        'Stone \\nBrook',\n        'Timberland',\n        'Veenker']\nxticks=[1000, 3000, 5000]\nxticklabels=['1k','3k','5k']\nyticks=[200000,400000,600000]\nyticklabels=['200k','400k','600k']\nfor i in fig.axes:\n    i.tick_params(axis='both', which='both', bottom=False, left=False)\n    i.set_xlabel(\"Ground Living \\nArea (in Sq Ft)\", fontsize='x-large', fontstretch='semi-expanded', fontweight='bold')\n    i.set_xticks(ticks=xticks, labels=xticklabels, fontsize='xx-large')\n    i.set_ylim(0,800000)\n    i.set_yticks(ticks=yticks, labels=yticklabels, fontsize='xx-large')\n    i.set_ylabel(\"Sales Price\", fontsize='large', fontweight='bold')\n    i.set_title(titles[list(fig.axes).index(i)],fontsize='large', fontweight='bold', x=0.4, y=0.8)\n\nplt.show()\n#fig.savefig('B11.jpeg', dpi=1200, bbox_inches='tight')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-03-25T17:53:05.963062Z","iopub.execute_input":"2022-03-25T17:53:05.963601Z","iopub.status.idle":"2022-03-25T17:53:30.440458Z","shell.execute_reply.started":"2022-03-25T17:53:05.96355Z","shell.execute_reply":"2022-03-25T17:53:30.439391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 11 : Regression plot between Sales Price and Ground Living Area decomposed by Neighbourhoods\n    </i></b>    \n</center>","metadata":{}},{"cell_type":"code","source":"data=pd.DataFrame()\ndata['GrLivArea']=np.log1p(df_train['GrLivArea'])\ndata['SalePrice']=np.log1p(df_train['SalePrice'])\ndata['Neighborhood']=df_train['Neighborhood']\nfig=sns.lmplot(data=data, x='GrLivArea', y='SalePrice', col='Neighborhood', col_wrap=5, height=3, aspect=0.9)\ntitles=['Bloomington \\nHeights',\n        'Bluestem', \n        'Briardale',\n        'Brookside',\n        'Clear \\nCreek',\n        'College \\nCreek',\n        'Crawford',\n        'Edwards',\n        'Gilbert',\n        'IOWA DOT & \\nRail Road',\n        'Meadow \\nVillage',\n        'Mitchell',\n        'North \\nAmes',\n        'Northridge',\n        'Northpark \\nVilla',\n        'Northridge \\nHeights',\n        'Northwest \\nAmes',\n        'Old Town',\n        'South&West\\nof ISU',\n        'Sawyer',\n        'Sawyer \\nWest',\n        'Somerset',\n        'Stone \\nBrook',\n        'Timberland',\n        'Veenker']\nxticks=[6, 7, 8]\nyticks=[11,12,13]\nfor i in fig.axes:\n    i.tick_params(axis='both', which='both', bottom=False, left=False)\n    i.set_xlabel(\"Ground Living \\nArea (in log Sq Ft)\", fontsize='x-large', fontstretch='semi-expanded', fontweight='bold')\n    i.set_xticks(ticks=xticks, labels=xticks, fontsize='xx-large')\n    i.set_yticks(ticks=yticks, labels=yticks, fontsize='xx-large')\n    i.set_ylabel(\"Sales Price (in logscale)\", fontsize='large', fontweight='bold')\n    i.set_title(titles[list(fig.axes).index(i)],fontsize='x-large', fontweight='bold', x=0.4, y=0.8)\n\nplt.show()\n#fig.savefig('B12.jpeg', dpi=1200, bbox_inches='tight')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-03-25T17:54:00.114007Z","iopub.execute_input":"2022-03-25T17:54:00.114246Z","iopub.status.idle":"2022-03-25T17:54:24.545648Z","shell.execute_reply.started":"2022-03-25T17:54:00.114216Z","shell.execute_reply":"2022-03-25T17:54:24.544699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<center style=\"font-size:15px;font-style:italics\">\n    <b><i>\n    Figure 12 : Regression plot between log of Sales Price and log of Ground Living Area decomposed by Neighbourhoods\n    </i></b>    \n</center>","metadata":{}}]}