{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "8ced3efa-401b-4b60-bc1b-4e861aecc71e",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"D:\\LUTFI\\Anacnda\\Lib\\site-packages\\dask\\dataframe\\_pyarrow_compat.py:23: UserWarning: You are using pyarrow version 11.0.0 which is known to be insecure. See https://www.cve.org/CVERecord?id=CVE-2023-47248 for further details. Please upgrade to pyarrow>=14.0.1 or install pyarrow-hotfix to patch your current version.\n",
" warnings.warn(\n"
]
}
],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from sklearn.compose import ColumnTransformer\n",
"from sklearn.pipeline import Pipeline\n",
"from sklearn.impute import SimpleImputer\n",
"from sklearn.preprocessing import MinMaxScaler, OneHotEncoder, StandardScaler\n",
"\n",
"from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV, StratifiedKFold\n",
"\n",
"from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet\n",
"from sklearn.tree import DecisionTreeRegressor\n",
"from sklearn.ensemble import GradientBoostingRegressor, RandomForestRegressor\n",
"from lightgbm import LGBMRegressor\n",
"\n",
"from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "ffc3b3cd-b9dd-47f8-8827-58aec39a6309",
"metadata": {},
"outputs": [],
"source": [
"df = pd.read_excel('Real_estate_valuation _data_set.xlsx')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "d5857eae-ef7b-4b17-a12b-d2b9e4bdc22e",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" No \n",
" X1 transaction date \n",
" X2 house age \n",
" X3 distance to the nearest MRT station \n",
" X4 number of convenience stores \n",
" X5 latitude \n",
" X6 longitude \n",
" Y house price of unit area \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 1 \n",
" 2012.916667 \n",
" 32.0 \n",
" 84.87882 \n",
" 10 \n",
" 24.98298 \n",
" 121.54024 \n",
" 37.9 \n",
" \n",
" \n",
" 1 \n",
" 2 \n",
" 2012.916667 \n",
" 19.5 \n",
" 306.59470 \n",
" 9 \n",
" 24.98034 \n",
" 121.53951 \n",
" 42.2 \n",
" \n",
" \n",
" 2 \n",
" 3 \n",
" 2013.583333 \n",
" 13.3 \n",
" 561.98450 \n",
" 5 \n",
" 24.98746 \n",
" 121.54391 \n",
" 47.3 \n",
" \n",
" \n",
" 3 \n",
" 4 \n",
" 2013.500000 \n",
" 13.3 \n",
" 561.98450 \n",
" 5 \n",
" 24.98746 \n",
" 121.54391 \n",
" 54.8 \n",
" \n",
" \n",
" 4 \n",
" 5 \n",
" 2012.833333 \n",
" 5.0 \n",
" 390.56840 \n",
" 5 \n",
" 24.97937 \n",
" 121.54245 \n",
" 43.1 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" No X1 transaction date X2 house age \\\n",
"0 1 2012.916667 32.0 \n",
"1 2 2012.916667 19.5 \n",
"2 3 2013.583333 13.3 \n",
"3 4 2013.500000 13.3 \n",
"4 5 2012.833333 5.0 \n",
"\n",
" X3 distance to the nearest MRT station X4 number of convenience stores \\\n",
"0 84.87882 10 \n",
"1 306.59470 9 \n",
"2 561.98450 5 \n",
"3 561.98450 5 \n",
"4 390.56840 5 \n",
"\n",
" X5 latitude X6 longitude Y house price of unit area \n",
"0 24.98298 121.54024 37.9 \n",
"1 24.98034 121.53951 42.2 \n",
"2 24.98746 121.54391 47.3 \n",
"3 24.98746 121.54391 54.8 \n",
"4 24.97937 121.54245 43.1 "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.head()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "7de11b8e-963d-432f-9246-5595fcdc6461",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" No \n",
" Date \n",
" Age \n",
" Distance_MRT \n",
" Total_Sotres \n",
" Latitude \n",
" longitude \n",
" price \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 1 \n",
" 2012.916667 \n",
" 32.0 \n",
" 84.87882 \n",
" 10 \n",
" 24.98298 \n",
" 121.54024 \n",
" 37.9 \n",
" \n",
" \n",
" 1 \n",
" 2 \n",
" 2012.916667 \n",
" 19.5 \n",
" 306.59470 \n",
" 9 \n",
" 24.98034 \n",
" 121.53951 \n",
" 42.2 \n",
" \n",
" \n",
" 2 \n",
" 3 \n",
" 2013.583333 \n",
" 13.3 \n",
" 561.98450 \n",
" 5 \n",
" 24.98746 \n",
" 121.54391 \n",
" 47.3 \n",
" \n",
" \n",
" 3 \n",
" 4 \n",
" 2013.500000 \n",
" 13.3 \n",
" 561.98450 \n",
" 5 \n",
" 24.98746 \n",
" 121.54391 \n",
" 54.8 \n",
" \n",
" \n",
" 4 \n",
" 5 \n",
" 2012.833333 \n",
" 5.0 \n",
" 390.56840 \n",
" 5 \n",
" 24.97937 \n",
" 121.54245 \n",
" 43.1 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" No Date Age Distance_MRT Total_Sotres Latitude longitude \\\n",
"0 1 2012.916667 32.0 84.87882 10 24.98298 121.54024 \n",
"1 2 2012.916667 19.5 306.59470 9 24.98034 121.53951 \n",
"2 3 2013.583333 13.3 561.98450 5 24.98746 121.54391 \n",
"3 4 2013.500000 13.3 561.98450 5 24.98746 121.54391 \n",
"4 5 2012.833333 5.0 390.56840 5 24.97937 121.54245 \n",
"\n",
" price \n",
"0 37.9 \n",
"1 42.2 \n",
"2 47.3 \n",
"3 54.8 \n",
"4 43.1 "
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.columns = ['No', 'Date', 'Age', 'Distance_MRT', 'Total_Sotres', 'Latitude', 'longitude', 'price']\n",
"df.head()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "fe195964-c5b7-420e-8601-21603a6f092a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"RangeIndex: 414 entries, 0 to 413\n",
"Data columns (total 8 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 No 414 non-null int64 \n",
" 1 Date 414 non-null float64\n",
" 2 Age 414 non-null float64\n",
" 3 Distance_MRT 414 non-null float64\n",
" 4 Total_Sotres 414 non-null int64 \n",
" 5 Latitude 414 non-null float64\n",
" 6 longitude 414 non-null float64\n",
" 7 price 414 non-null float64\n",
"dtypes: float64(6), int64(2)\n",
"memory usage: 26.0 KB\n"
]
}
],
"source": [
"df.info()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "753d0b20-6bdb-4ccc-94e9-1f1374d9502b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"((331, 5), (83, 5))"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_train, X_test, y_train, y_test = train_test_split(\n",
" df.drop(['No', 'Date', 'price'], axis=1),\n",
" df['price'],\n",
" test_size= 0.2,\n",
" random_state= 1)\n",
"\n",
"for i in [X_train, X_test, y_train, y_test]:\n",
" i.reset_index(drop=True, inplace=True)\n",
"\n",
"X_train.shape, X_test.shape"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "6cf510bb-b381-4db0-ae7a-604c0677039f",
"metadata": {},
"outputs": [],
"source": [
"target = 'price'"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "c00c5283-e461-484a-85ad-ecf92b1e8cbb",
"metadata": {},
"outputs": [],
"source": [
"preprocessor_numerik = Pipeline([\n",
" ('imputasi', SimpleImputer(strategy='mean')),\n",
" ('scaling', StandardScaler())\n",
"])"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "45d5fa0f-87b1-49be-a974-af1923bdda8c",
"metadata": {},
"outputs": [],
"source": [
"lr = LinearRegression()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "d8e0088d-f50f-4e9e-9ef8-44311579c78d",
"metadata": {},
"outputs": [],
"source": [
"model_rfr = Pipeline(steps=[\n",
" ('preprocessor_numerik', preprocessor_numerik),\n",
" ('lr', LinearRegression())\n",
"])"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "440d9f9f-69ba-48d5-a362-e29951a6a771",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"Pipeline(steps=[('preprocessor_numerik',\n",
" Pipeline(steps=[('imputasi', SimpleImputer()),\n",
" ('scaling', StandardScaler())])),\n",
" ('lr', LinearRegression())]) In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org. "
],
"text/plain": [
"Pipeline(steps=[('preprocessor_numerik',\n",
" Pipeline(steps=[('imputasi', SimpleImputer()),\n",
" ('scaling', StandardScaler())])),\n",
" ('lr', LinearRegression())])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model_rfr.fit(X_train, y_train)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "fdc8e212-c98c-48c6-9130-7cfe1c4c85b1",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([42.36886682, 45.64027105, 52.29266724, 47.85322975, 36.37229111,\n",
" 48.6702964 , 14.93141372, 33.87830336, 50.24625987, 40.83238223,\n",
" 30.49859064, 48.37004246, 41.02486147, 30.02306706, 42.31075147,\n",
" 48.68694663, 43.018887 , 33.55347608, 46.22563127, 30.17706976,\n",
" 33.50593387, 39.85433842, 42.16108976, 48.58127858, 34.80094567,\n",
" 38.57058392, 47.18117225, 43.19310668, 52.31761086, 48.39034417,\n",
" 41.99035299, 30.55918299, 46.41177644, 46.74944722, 42.26086423,\n",
" 41.74468415, 15.12079501, 43.30531335, 15.25954788, 38.78936601,\n",
" 41.59188631, 41.71778768, 43.15499811, 45.4240889 , 46.17574403,\n",
" 47.12788362, 40.15448785, 38.5988199 , 48.63116581, 44.90988295,\n",
" 46.61340685, 47.80869225, 41.33640095, 42.23592061, 42.31075147,\n",
" 43.18050194, 52.24278 , 32.59440108, 12.11104337, 41.57404166,\n",
" 25.52390374, 43.12497981, 48.58127858, 38.63804119, 34.88185988,\n",
" 48.4199297 , 50.24625987, 44.30833569, 50.59052451, 43.018887 ,\n",
" 38.95202107, 43.48870434, 24.17314066, 32.96000097, 34.07440683,\n",
" 37.54660931, 50.24625987, 42.77620817, 49.15749083, 50.24625987,\n",
" 15.10601904, 45.43093643, 34.85691627, 52.21783639, 46.76306855,\n",
" 40.66134485, 41.75515061, 45.51555296, 44.63257306, 29.564124 ,\n",
" 30.67319596, 28.96317173, 47.3550611 , 46.97822192, 35.91936611,\n",
" 48.50402977, 47.00656693, 25.52140291, 55.02824079, 47.56351028,\n",
" 49.60416586, 38.25881687, 44.27422511, 44.60861129, 21.74705316,\n",
" 49.0289474 , 41.02870932, 43.50749428, 49.59477177, 44.2440042 ,\n",
" 45.61532743, 37.03020189, 42.23592061, 32.03787491, 31.37854073,\n",
" 14.90647011, 50.09306532, 40.78097996, 46.3067255 , 44.81932843,\n",
" 45.40123786, 30.49859064, 46.79592195, 33.84897425, 35.7180079 ,\n",
" 47.80869225, 29.01034861, 28.72708906, 39.51915647, 14.95813635,\n",
" 44.79438481, 8.06008617, 47.80869225, 52.26772362, 41.39333093,\n",
" 52.44232894, 45.69015828, 41.44786325, 43.36428147, 41.29029531,\n",
" 25.54030676, 42.63096076, 33.71831813, 37.12219623, 11.72440659,\n",
" 27.63427469, 39.05816358, 45.41797523, 46.27599136, 38.62376352,\n",
" 30.48435213, 31.92913805, 37.28357107, 45.42618148, 42.21920511,\n",
" 38.36378677, 45.69440684, 40.41059826, 47.83363586, 32.32744468,\n",
" 45.69015828, 9.59230461, 33.9596696 , 31.2187193 , 46.17574403,\n",
" 43.59583988, 40.69807579, 50.41225954, 37.850607 , 48.4042553 ,\n",
" 36.14274813, 42.60954866, 45.84398876, 45.17474763, 40.19023373,\n",
" 48.27026799, 32.0129313 , 45.29937081, 43.85615123, 36.53482197,\n",
" 23.22432109, 38.1440882 , 39.81826002, 2.60500519, 37.28397053,\n",
" 30.1670043 , 42.22381852, 50.09306532, 14.8916758 , 43.22629538,\n",
" 42.71298657, 36.48338363, 46.22563127, 32.30099697, 51.88100313,\n",
" 38.69818738, 46.62193807, 45.85682942, 32.83323107, 43.018887 ,\n",
" 12.25831833, 26.41259239, 46.25057488, 14.8991769 , 14.23656569,\n",
" 40.98340745, 32.51221627, 34.60492182, 45.85682942, 44.78386047,\n",
" 45.05003285, 25.21885406, 33.12828125, 37.04911653, 47.28142775,\n",
" 46.22563127, 13.71602892, 35.52616731, 30.54847787, 49.75480868,\n",
" 34.91127456, 33.17903829, 52.26772362, 47.90311699, 34.19818489,\n",
" 47.15622863, 32.42426584, 54.17874571, 32.24139297, 41.00835106,\n",
" 34.233986 , 27.65952669, 30.47364702, 32.36565073, 30.65895745,\n",
" 34.9068035 , 26.51236686, 43.45004022, 31.88896929, 46.92833468,\n",
" 33.68055385, 46.30046212, 29.38972347, 33.15409468, 43.65715598,\n",
" 14.46135214, 53.03558127, 33.34343735, 30.10223891, 42.90491934,\n",
" 54.25357656, 46.05593105, 41.71660439, 14.90647011, 33.05432021,\n",
" 42.16108976, 8.88637881, 34.09935045, 46.25122495, 46.35661273,\n",
" 50.24625987, 26.51953997, 30.7337883 , 15.25954788, 39.60771879,\n",
" 36.54236185, 39.25656155, 42.31897958, 14.58295082, 38.52786553,\n",
" 43.02107389, 32.37496591, 14.58607022, 33.32974487, 38.89565721,\n",
" 32.34070711, 36.64551078, 36.23607094, 34.88185988, 39.60806735,\n",
" 46.17574403, 48.7558839 , 36.61556644, 43.04768545, 47.57748049,\n",
" 46.92833468, 53.81962905, 12.57057948, 41.67597908, 12.03621252,\n",
" 42.16108976, 39.27535277, 43.018887 , 32.76304058, 40.4377969 ,\n",
" 43.47923892, 45.62214993, 49.52155362, 45.5654402 , 29.87500021,\n",
" 40.20166259, 35.66740059, 45.98900716, 39.40297485, 32.42485315,\n",
" 28.59929244, 45.52237546, 45.97392447, 42.60214485, 40.97535553,\n",
" 25.11907959, 52.39244171, 51.29462089, 49.90447038, 38.28376049,\n",
" 44.45894959, 53.0854685 , 43.65312151, 38.73947878, 36.24252259,\n",
" 43.02368574, 30.57342149, 40.27550731, 49.89341066, 46.37529297,\n",
" 43.64572711, 8.1099734 , 43.57063735, 30.97876525, 45.7219244 ,\n",
" 30.54847787])"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model_rfr.predict(X_train)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "81805032-a2b8-41ac-b435-83ec09dbdf1b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"38.71299093655648\n",
"[-2.85545772 -5.80314009 3.25790289 2.9053199 -0.525551 ]\n"
]
}
],
"source": [
"print(model_rfr['lr'].intercept_)\n",
"print(model_rfr['lr'].coef_)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "0be85203-cc12-42a1-b9a5-2075bfb9212b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['Age' 'Distance_MRT' 'Total_Sotres' 'Latitude' 'longitude']\n"
]
}
],
"source": [
"print(model_rfr['preprocessor_numerik'].get_feature_names_out())"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "425b2679-ea37-49a0-ae29-476b7258a9a7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"price = 38.71299093655648 + -2.8554577169465 * Age +\n",
"-5.803140091732102 * Distance_MRT +\n",
"3.2579028917683615 * Total_Sotres +\n",
"2.905319902108692 * Latitude +\n",
"-0.5255509950918564 * longitude\n"
]
}
],
"source": [
"# Looping untuk mencetak persamaan regresi linear\n",
"for i,j in enumerate(model_rfr['lr'].coef_):\n",
" if i == 0:\n",
" print(str(target),'=',model_rfr['lr'].intercept_,'+',model_rfr['lr'].coef_[i],'*',model_rfr['preprocessor_numerik'].get_feature_names_out()[i],'+')\n",
" elif i != len(model_rfr['lr'].coef_)-1:\n",
" print(model_rfr['lr'].coef_[i],'*',model_rfr['preprocessor_numerik'].get_feature_names_out()[i],'+')\n",
" else:\n",
" print(model_rfr['lr'].coef_[i],'*',model_rfr['preprocessor_numerik'].get_feature_names_out()[i])"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "7a575181-f99a-4405-b6ed-399c824366fc",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"price = 38.71299093655648 + -2.8554577169465 * Age + -5.803140091732102 * Distance_MRT + 3.2579028917683615 * Total_Sotres + 2.905319902108692 * Latitude + -0.5255509950918564 * longitude\n"
]
}
],
"source": [
"# Menulis secara runut model regresi secara manual\n",
"print('price = ', model_rfr['lr'].intercept_,'+',\n",
" model_rfr['lr'].coef_[0],'*',model_rfr['preprocessor_numerik'].get_feature_names_out()[0],'+',\n",
" model_rfr['lr'].coef_[1],'*',model_rfr['preprocessor_numerik'].get_feature_names_out()[1],'+',\n",
" model_rfr['lr'].coef_[2],'*',model_rfr['preprocessor_numerik'].get_feature_names_out()[2],'+',\n",
" model_rfr['lr'].coef_[3],'*',model_rfr['preprocessor_numerik'].get_feature_names_out()[3],'+',\n",
" model_rfr['lr'].coef_[4],'*',model_rfr['preprocessor_numerik'].get_feature_names_out()[4])"
]
},
{
"cell_type": "markdown",
"id": "54f1c07c-6060-4765-b752-0c0a87167e2d",
"metadata": {},
"source": [
"Dengan melihay rumus diatas kita, para pebisnis Real estate bisa menggunakan rumus diatas dengancara mengisi setiap featuresnya."
]
},
{
"cell_type": "markdown",
"id": "514dc104-9d23-470b-b6ac-e37351f3e844",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"id": "07ae22fc-3960-4864-b200-6864b7f4e663",
"metadata": {},
"source": [
"### Evaluasi Model"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "a6543e2f-4130-4319-9de9-e8b44ed37439",
"metadata": {},
"outputs": [],
"source": [
"#memprediksi X_train dan membandingkannya dengan y_train\n",
"predik_train = model_rfr.predict(X_train)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "c735c2af-80c8-4536-86d2-cfc9c3e5fe2d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" price \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 42.368867 \n",
" \n",
" \n",
" 1 \n",
" 45.640271 \n",
" \n",
" \n",
" 2 \n",
" 52.292667 \n",
" \n",
" \n",
" 3 \n",
" 47.853230 \n",
" \n",
" \n",
" 4 \n",
" 36.372291 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" price\n",
"0 42.368867\n",
"1 45.640271\n",
"2 52.292667\n",
"3 47.853230\n",
"4 36.372291"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#melihat hasil prediksi training \n",
"predik_train = pd.DataFrame(predik_train, columns=[target])\n",
"predik_train.head()"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "d3a7528d-046a-47e5-9f6d-c6039933a1c2",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Prediksi X_train \n",
" Asli \n",
" Eror \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 42.368867 \n",
" 37.4 \n",
" 4.968867 \n",
" \n",
" \n",
" 1 \n",
" 45.640271 \n",
" 51.8 \n",
" 6.159729 \n",
" \n",
" \n",
" 2 \n",
" 52.292667 \n",
" 58.1 \n",
" 5.807333 \n",
" \n",
" \n",
" 3 \n",
" 47.853230 \n",
" 49.5 \n",
" 1.646770 \n",
" \n",
" \n",
" 4 \n",
" 36.372291 \n",
" 30.6 \n",
" 5.772291 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Prediksi X_train Asli Eror\n",
"0 42.368867 37.4 4.968867\n",
"1 45.640271 51.8 6.159729\n",
"2 52.292667 58.1 5.807333\n",
"3 47.853230 49.5 1.646770\n",
"4 36.372291 30.6 5.772291"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#Membandingkan 2 hasil prediksi dan asli\n",
"compareXy_train = pd.DataFrame(np.column_stack((predik_train, pd.DataFrame(y_train), abs(predik_train - pd.DataFrame(y_train)))), columns=['Prediksi X_train', 'Asli', 'Eror'])\n",
"compareXy_train.head()\n",
" "
]
},
{
"cell_type": "markdown",
"id": "b783d750-588c-4a2a-9584-b4cc4dc26dda",
"metadata": {},
"source": [
"kolom bertuliskan eror merupakan selisih antara prediksi ke nilai asli "
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "ce43d8c8-b069-4936-9217-9e40af307d29",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Prediksi X_train \n",
" Asli \n",
" Eror \n",
" \n",
" \n",
" \n",
" \n",
" count \n",
" 331.000000 \n",
" 331.000000 \n",
" 331.000000 \n",
" \n",
" \n",
" mean \n",
" 38.712991 \n",
" 38.712991 \n",
" 6.468697 \n",
" \n",
" \n",
" std \n",
" 10.125296 \n",
" 13.814414 \n",
" 6.807759 \n",
" \n",
" \n",
" min \n",
" 2.605005 \n",
" 7.600000 \n",
" 0.025631 \n",
" \n",
" \n",
" 25% \n",
" 33.166566 \n",
" 28.450000 \n",
" 2.395571 \n",
" \n",
" \n",
" 50% \n",
" 41.447863 \n",
" 39.300000 \n",
" 5.058957 \n",
" \n",
" \n",
" 75% \n",
" 45.981466 \n",
" 47.300000 \n",
" 8.315330 \n",
" \n",
" \n",
" max \n",
" 55.028241 \n",
" 117.500000 \n",
" 75.509647 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Prediksi X_train Asli Eror\n",
"count 331.000000 331.000000 331.000000\n",
"mean 38.712991 38.712991 6.468697\n",
"std 10.125296 13.814414 6.807759\n",
"min 2.605005 7.600000 0.025631\n",
"25% 33.166566 28.450000 2.395571\n",
"50% 41.447863 39.300000 5.058957\n",
"75% 45.981466 47.300000 8.315330\n",
"max 55.028241 117.500000 75.509647"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"compareXy_train.describe()"
]
},
{
"cell_type": "markdown",
"id": "22ba490d-183e-47ee-a4cf-04cefc49e0d7",
"metadata": {},
"source": [
"nilai MAE adalah 6.03"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "f319564f-31a1-42de-92bd-88d13fc0cbca",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAHFCAYAAAAUpjivAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABvb0lEQVR4nO3deVxUVf8H8M+ACIqIgsgipGiamZZblpqJS5q5hibumi2WbWRp2gb2MzXzcSkfNcutFEUDpcVMLHBJfdTU3MqycCMJV3BlGc7vj9sMDMxyZ+bOdvm8X695KXc9987A/c4533OORgghQERERKRSXq4uABEREZEjMdghIiIiVWOwQ0RERKrGYIeIiIhUjcEOERERqRqDHSIiIlI1BjtERESkagx2iIiISNUY7BAREZGqMdgh1VqxYgU0Go3+VaVKFURGRuLJJ59Edna2U8rQoEEDjBkzRv9zZmYmNBoNMjMz9cvGjBmDGjVqKHI+jUaDxMRERY6lhCNHjkCj0cDHxwfnz583uk2DBg3Qp08fs8e5efMmEhMTDe6bI40ZMwYNGjSQvX23bt3w3HPPAZCup+znztRrxYoVdpVR9/k+deqU1fueOnVKkTLY6uzZsxg/fjyaNGmCatWqISgoCC1atMAzzzyDs2fPWn2848ePIzEx0ei9GDlyJAYMGGB/ocmjVXF1AYgcbfny5WjatClu3bqF7du3Y8aMGdi2bRuOHDkCf39/p5aldevW2L17N5o1a+aQ4+/evRuRkZEOObYtPvvsMwBAcXExPv/8c7zxxhs2HefmzZuYOnUqACAmJkap4ikiLS0NP/30Ez7//HMAwIYNG1BQUKBf/9lnn2Hp0qXYvHkzAgMD9csbNWpk13l79+6N3bt3Izw83Op9w8PDsXv3brvLYItz586hdevWqFWrFl577TXcddddyMvLw/Hjx7Fu3Tr89ddfiIqKsuqYx48fx9SpUxETE1MhSE1MTETTpk3x448/omvXrgpeCXkSBjukes2bN0fbtm0BAF26dIFWq8X//d//YePGjRg+fLjRfW7evInq1asrXpaaNWviwQcfVPy4Oo48trUKCgqwevVq3Hfffbh48SKWLVtmc7DjzqZPn47HH38c9erVAwC0atXKYP3mzZsBAG3atEGdOnVMHsfaz1xISAhCQkJsKDHg6+vrss/Kp59+iosXL2Lv3r2Ijo7WLx8wYADefPNNlJSUKHq+Ro0a4dFHH8XMmTMZ7FRibMaiSkf3R/706dMASpuRjhw5gh49eiAgIADdunUDABQWFmLatGlo2rQpfH19ERISgieffBIXLlwwOGZRUREmTZqEsLAwVK9eHQ899BD27t1b4dzGmrGM+emnn1CnTh306dMHN27cAAD8+OOPiImJQXBwMKpVq4Y77rgDAwcOxM2bN/X7WWrGKioqQt26dTFy5MgK665evYpq1aphwoQJAICSkhJMmzYNd911F6pVq4ZatWrh3nvvxfz5882WXWfjxo24dOkSnn76aYwePRq///47du7cKWvfhQsXokqVKkhISMCpU6f0D/WpU6fqm4F0zYOmmpwSExOh0WgMlv33v//Fww8/jLp168Lf3x8tWrTArFmzUFRUJKtc5R08eBB79+41ej/NMfeZS09PR//+/REZGQk/Pz/ceeedGDduHC5evGhwDGPNWDExMWjevDn27duHTp06oXr16mjYsCFmzpxpEEQYa8bS3a9jx45h6NChCAwMRGhoKMaOHYu8vDyDc1+9ehVPPfUUgoKCUKNGDfTu3Rt//fWXrGbUS5cuwcvLC3Xr1jW63svL8LG0f/9+9OvXD0FBQfDz80OrVq2wbt06g/vwxBNPAJC+zBhrJhw5ciS2bt2KP//802zZSL0Y7FClc/LkSQAw+FZcWFiIfv36oWvXrkhLS8PUqVNRUlKC/v37Y+bMmRg2bBi+/fZbzJw5E+np6YiJicGtW7f0+z/zzDOYPXs2Ro0ahbS0NAwcOBCxsbG4cuWK1eVbt24dunXrhsGDByMtLQ3+/v44deoUevfujapVq2LZsmXYvHkzZs6cCX9/fxQWFso+to+PD0aMGIGUlBTk5+cbrFuzZg1u376NJ598EgAwa9YsJCYmYujQofj222+RnJyMp556ClevXpV1rqVLl8LX1xfDhw/H2LFjodFosHTpUrP7CCHw+uuvIz4+Hp999hmmTp2K8PBwfe3IU089hd27d2P37t145513ZF+3zp9//olhw4bhiy++wDfffIOnnnoKH374IcaNG2f1sQDgm2++gbe3Nx5++GGr9zX2mdOVsX379li0aBG2bNmCd999F//73//w0EMPyQrKcnJyMHz4cIwYMQJfffUVevXqhSlTpmDVqlWyyjVw4EA0adIEKSkpmDx5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v3Yicgw2YxGR29i7dy+SkpLQrVs3AEBhYSG++OILhISEAAB+/PFHHDlyBLm5ufD19QUAzJ49Gxs3bsSXX36JZ599FvPmzcPYsWPx9NNPAwCmTZuGrVu3VqjdMWbhwoV48803kZaWhi5dugAA8vPzkZeXhz59+qBRo0YAgLvvvlvxaycix2HNDhG51DfffIMaNWrAz88P7du3x8MPP4yPP/4YAFC/fn19oAMAP//8M65fv47g4GB9rkyNGjWQlZWFP//8EwDw66+/on379gbnKP+zMSkpKYiPj8eWLVv0gQ4ABAUFYcyYMejZsyf69u2L+fPn4/z580pcOhE5CWt2iMilunTpgkWLFsHHxwcREREGScj+/v4G25aUlCA8PByZmZkVjlOrVi27ytGyZUscOHAAy5cvx/3332/QTLV8+XK8/PLL2Lx5M5KTk/H2228jPT0dDz74oF3nJCLnYM0OEbmUv78/7rzzTtSvX99ib6vWrVsjJycHVapUwZ133mnwqlOnDgCpiWnPnj0G+5X/2ZhGjRohIyMDaWlpeOmllyqsb9WqFaZMmYJdu3ahefPmSEpKsuIqiciVGOwQkcfo3r072rdvjwEDBuD777/HqVOnsGvXLrz99tvYv38/AOCVV17BsmXLsGzZMvz+++9ISEjAsWPHZB2/SZMmyMjI0DdpAUBWVhamTJmC3bt34/Tp09iyZQt+//135u0QeRA2YxGRx9BoNNi0aRPeeustjB07FhcuXEBYWBgefvhhhIaGAgDi4uLw559/4o033sDt27cxcOBAPP/88/j+++9lneOuu+7Cjz/+iJiYGHh7e2PSpEn47bffsHLlSly6dAnh4eF48cUXMW7cOEdeKhEpSCOEEK4uBBEREZGjsBmLiIiIVI3BDhEREakagx0iIiJSNQY7REREpGoMdoiIiEjVGOwQERGRqjHYISIiIlVjsENERESqxmCHiIiIVI3BDhEREakagx0iIiJSNQY7REREpGr/D8KLjeXwWA9hAAAAAElFTkSuQmCC",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.scatter(predik_train, y_train, color = 'red')\n",
"plt.plot(predik_train, model_rfr.predict(X_train), color = 'blue')\n",
"plt.title('Prediksi vs Aktual (Training Set)')\n",
"plt.xlabel('Prediksi')\n",
"plt.ylabel('Aktual')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "fea197cb-d29a-4782-8505-d79ac9de0a17",
"metadata": {},
"source": [
"membandingkan prediksi X_train dan y_train tampaknya sangat bagus, namun perlu menghitung nilai eror sekaligus coeficient."
]
},
{
"cell_type": "markdown",
"id": "4be13d82-a298-408f-b92a-fcd95249e3b2",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"id": "01c73dda-8087-456d-834d-75cabb92feab",
"metadata": {},
"source": [
"### Menghitung *Metrics* di *Training Set*"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "63963a93-02fe-4618-b7a4-80ffd0193e64",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MAE = 6.47\n",
"MSE = 88.05\n",
"RMSE = 9.38\n",
"R2 = 0.54\n"
]
}
],
"source": [
"# Menghitung nilai error (MAE, MSE, RMSE) di Training Set\n",
"from sklearn import metrics\n",
"print('MAE = {0:.2f}'.format(metrics.mean_absolute_error(y_train, predik_train))) # MAE adalah nilai error rata-rata seperti yang ada di tabel banding_train\n",
"print('MSE = {0:.2f}'.format(metrics.mean_squared_error(y_train, predik_train))) # penulisan {0:.2f} adalah untuk menuliskan 2 angka di belakang koma\n",
"print('RMSE = {0:.2f}'.format(np.sqrt(metrics.mean_squared_error(y_train, predik_train))))\n",
"print('R2 = {0:.2f}'.format(metrics.r2_score(y_train, predik_train)))"
]
},
{
"cell_type": "markdown",
"id": "0381e21e-d02f-41ae-8c3d-f7078b4a6ca7",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"id": "12209067-2739-49cd-be1a-d1af06eeee0c",
"metadata": {},
"source": [
"### Evaluasi di Test Set"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "ddc0b4cd-e25b-4dec-974c-e3db25c17188",
"metadata": {},
"outputs": [],
"source": [
"predik_test = model_rfr.predict(X_test)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "b237b634-557b-4d5a-a943-71c66ece358b",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" price \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 33.079962 \n",
" \n",
" \n",
" 1 \n",
" 47.808692 \n",
" \n",
" \n",
" 2 \n",
" 22.113738 \n",
" \n",
" \n",
" 3 \n",
" 15.130963 \n",
" \n",
" \n",
" 4 \n",
" 44.625942 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" price\n",
"0 33.079962\n",
"1 47.808692\n",
"2 22.113738\n",
"3 15.130963\n",
"4 44.625942"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"predik_test = pd.DataFrame(predik_test, columns=[target])\n",
"predik_test.head()"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "96aeb226-e964-4cdb-acf6-06cb1fff3efb",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Prediksi X_test \n",
" Asli \n",
" Eror \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 33.079962 \n",
" 27.3 \n",
" 5.779962 \n",
" \n",
" \n",
" 1 \n",
" 47.808692 \n",
" 54.4 \n",
" 6.591308 \n",
" \n",
" \n",
" 2 \n",
" 22.113738 \n",
" 22.0 \n",
" 0.113738 \n",
" \n",
" \n",
" 3 \n",
" 15.130963 \n",
" 11.6 \n",
" 3.530963 \n",
" \n",
" \n",
" 4 \n",
" 44.625942 \n",
" 45.4 \n",
" 0.774058 \n",
" \n",
" \n",
" ... \n",
" ... \n",
" ... \n",
" ... \n",
" \n",
" \n",
" 78 \n",
" 41.626092 \n",
" 33.1 \n",
" 8.526092 \n",
" \n",
" \n",
" 79 \n",
" 46.125857 \n",
" 59.6 \n",
" 13.474143 \n",
" \n",
" \n",
" 80 \n",
" 44.362550 \n",
" 40.8 \n",
" 3.562550 \n",
" \n",
" \n",
" 81 \n",
" 43.018887 \n",
" 52.2 \n",
" 9.181113 \n",
" \n",
" \n",
" 82 \n",
" 48.926995 \n",
" 47.1 \n",
" 1.826995 \n",
" \n",
" \n",
"
\n",
"
83 rows × 3 columns
\n",
"
"
],
"text/plain": [
" Prediksi X_test Asli Eror\n",
"0 33.079962 27.3 5.779962\n",
"1 47.808692 54.4 6.591308\n",
"2 22.113738 22.0 0.113738\n",
"3 15.130963 11.6 3.530963\n",
"4 44.625942 45.4 0.774058\n",
".. ... ... ...\n",
"78 41.626092 33.1 8.526092\n",
"79 46.125857 59.6 13.474143\n",
"80 44.362550 40.8 3.562550\n",
"81 43.018887 52.2 9.181113\n",
"82 48.926995 47.1 1.826995\n",
"\n",
"[83 rows x 3 columns]"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"compareXX_test = pd.DataFrame(np.column_stack((predik_test, pd.DataFrame(y_test), abs(predik_test - pd.DataFrame(y_test)))), columns=['Prediksi X_test', 'Asli', 'Eror'])\n",
"compareXX_test"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "508c6985-e77c-45d1-a9e7-5b542681f6e0",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Prediksi X_test \n",
" Asli \n",
" Eror \n",
" \n",
" \n",
" \n",
" \n",
" count \n",
" 83.000000 \n",
" 83.000000 \n",
" 83.000000 \n",
" \n",
" \n",
" mean \n",
" 37.118491 \n",
" 35.057831 \n",
" 5.380155 \n",
" \n",
" \n",
" std \n",
" 11.005341 \n",
" 12.395043 \n",
" 4.084077 \n",
" \n",
" \n",
" min \n",
" 12.275686 \n",
" 11.600000 \n",
" 0.113738 \n",
" \n",
" \n",
" 25% \n",
" 33.211700 \n",
" 23.800000 \n",
" 2.231576 \n",
" \n",
" \n",
" 50% \n",
" 40.503114 \n",
" 36.900000 \n",
" 4.200462 \n",
" \n",
" \n",
" 75% \n",
" 44.625942 \n",
" 42.900000 \n",
" 8.163311 \n",
" \n",
" \n",
" max \n",
" 52.588151 \n",
" 59.600000 \n",
" 17.777806 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Prediksi X_test Asli Eror\n",
"count 83.000000 83.000000 83.000000\n",
"mean 37.118491 35.057831 5.380155\n",
"std 11.005341 12.395043 4.084077\n",
"min 12.275686 11.600000 0.113738\n",
"25% 33.211700 23.800000 2.231576\n",
"50% 40.503114 36.900000 4.200462\n",
"75% 44.625942 42.900000 8.163311\n",
"max 52.588151 59.600000 17.777806"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"compareXX_test.describe()"
]
},
{
"cell_type": "markdown",
"id": "3cb48f8a-8784-4fef-b19a-21823a72cd64",
"metadata": {},
"source": [
"Nimali MAE di test set adalah 6.5"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "f629bbe5-de60-4189-9f84-4eebf39d3b86",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjMAAAHFCAYAAAAHcXhbAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABXRUlEQVR4nO3deVxU9f4/8NeRZQRE3JBFENRQK9e03ELBrUy7GNkiLS4ttsvXW3ZtuWLfEvNXXi1LW1y7LvVN0q63TEsgS71iaZpWaqEhSpoLEAro8Pn9ce5MDHMG5gwzc86ZeT0fDx7EOWfOfM4c8rz5fN6f90cSQggQERERGVQTrRtARERE1BgMZoiIiMjQGMwQERGRoTGYISIiIkNjMENERESGxmCGiIiIDI3BDBERERkagxkiIiIyNAYzREREZGgMZsgvLV++HJIkWb8CAwMRFxeHSZMmobi42CttSExMxMSJE60/5+XlQZIk5OXlWbdNnDgRzZo1c8v7SZKErKwst5zLHfbv3w9JkhAUFISTJ08qHpOYmIgxY8bUe54LFy4gKyvL5nPzpIkTJyIxMdHp44cNG4aHHnoIgHw9tX/vHH0tX77cLW2dPXs21q9f7/TxZ86cwYwZM3DVVVchLCwMERER6Nq1K+655x7s27dP9fufOHECWVlZ2Lt3r92+559/Htdccw1qampUn5eorkCtG0CkpWXLlqFr1664ePEivvzyS2RnZyM/Px/79+9HWFiYV9tyzTXXYMeOHbjqqqs8cv4dO3YgLi7OI+d2xbvvvgsAuHz5MlauXImnn37apfNcuHABs2bNAgCkpKS4q3lusWHDBnz99ddYuXIlAOCjjz5CVVWVdf+7776LJUuWYNOmTYiIiLBu79Spk1vef/bs2Rg3bhzGjh3b4LF//PEH+vfvjz/++ANPPfUUevbsiYsXL+LQoUPIycnB3r170aNHD1Xvf+LECcyaNQuJiYno1auXzb4nn3wSCxcuxIoVKzBp0iRV5yWqi8EM+bVu3bqhb9++AIDU1FSYzWb87//+L9avX4+77rpL8TUXLlxAaGio29vSvHlz9O/f3+3ntfDkudWqqqrCqlWr0LNnT/z+++9YunSpy8GMns2ePRu33HIL2rVrBwDo3bu3zf5NmzYBAPr06YM2bdp4vX21/d///R+OHDmCrVu3IjU11WbftGnT3N6DEhERgbvvvhtz5szBxIkTIUmSW89P/oXDTES1WB74x44dA/DnMM/+/fsxcuRIhIeHY9iwYQCA6upqvPjii+jatStMJhMiIyMxadIknD592uacly5dwvTp0xEdHY3Q0FBcf/312LVrl917Kw0zKfn666/Rpk0bjBkzBhUVFQCArVu3IiUlBa1bt0ZISAjat2+PW2+9FRcuXLC+rqFhpkuXLqFt27a455577PadP38eISEhmDZtGgCgpqYGL774Irp06YKQkBC0aNECPXr0wIIFC+ptu8X69etx5swZ3H///ZgwYQIOHTqEr776yqnXvvnmmwgMDMTMmTNx9OhRREZGAgBmzZplHaaxDN85GhLKysqye3i+8cYbGDx4MNq2bYuwsDB0794dc+fOxaVLl5xqV1179uzBrl27FD/P+ggh8Oabb6JXr14ICQlBy5YtMW7cOPzyyy925x8zZgzatm0Lk8mE2NhYjB49GsePHwcg3++KigqsWLHC+rnU13N15swZAEBMTIzi/iZNbB8Xhw8fRkZGhvX9r7zySrzxxhvW/Xl5ebj22msBAJMmTbK2ofbv4D333INDhw4hNzfX6c+HSAl7ZohqOXLkCABYH5CAHLT85S9/wZQpU/C3v/0Nly9fRk1NDdLS0rBt2zZMnz4dAwcOxLFjxzBz5kykpKRg9+7dCAkJAQA88MADWLlyJZ588kmMGDEC33//PdLT01FeXq66fR988AHuvfdeTJ48Ga+//joCAgJw9OhRjB49GsnJyVi6dClatGiB4uJibNq0CdXV1U73IgUFBeHuu+/G4sWL8cYbb6B58+bWfWvWrEFlZaV1OGDu3LnIysrCc889h8GDB+PSpUv48ccfcf78eafea8mSJTCZTLjrrrtw9uxZZGdnY8mSJbj++usdvkYIgaeeegqvvfYa3n33XUycOBFVVVXYtGkTbrzxRtx33324//77AdjeP2f9/PPPyMjIQIcOHRAcHIzvvvsOL730En788UcsXbpU9fk2btyIgIAADB48WNXrpkyZguXLl+OJJ57Ayy+/jLNnz+KFF17AwIED8d133yEqKgoVFRUYMWIEOnTogDfeeANRUVEoKSlBbm6u9fdqx44dGDp0KFJTU/H8888DgM09rWvAgAEAgHvvvRfPPPMMkpOT0bp1a8VjDx48iIEDB6J9+/Z49dVXER0djc8+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",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Visualisasi hasil Test Set\n",
"plt.scatter(predik_test, y_test, color = 'red')\n",
"plt.plot(predik_test, model_rfr.predict(X_test), color = 'blue')\n",
"plt.title('Prediksi vs Aktual (Test Set)')\n",
"plt.xlabel('Prediksi')\n",
"plt.ylabel('Aktual')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "25fdef67-50d9-46b9-a70a-b766c10c17d0",
"metadata": {},
"source": [
"dari visual diatas, terlihat jelas bahwa nilai prediksi test set dngan nilai asli hapir sama, itu ditandai dengan titik merah sangat dekat dengan garis biru, namun ada juga yang sangat jauh, itu menandakan oulier"
]
},
{
"cell_type": "markdown",
"id": "a34fcd1b-216c-4f40-bd4e-fc0013dd9014",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"id": "cf899d16-3aac-4766-8fa6-12dea1f7bdb8",
"metadata": {},
"source": [
"Menghitung Metric hasil dari test set"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "7d5ad535-20c1-48f7-b877-043ac653b6e5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MAE = 5.38\n",
"MSE = 45.42\n",
"RMSE = 6.74\n",
"R2 = 0.70\n"
]
}
],
"source": [
"# Menghitung nilai error (MAE, MSE, RMSE) di Test Set\n",
"print('MAE = {0:.2f}'.format(metrics.mean_absolute_error(y_test, predik_test))) # MAE adalah nilai error rata-rata seperti yang ada di tabel banding_train\n",
"print('MSE = {0:.2f}'.format(metrics.mean_squared_error(y_test, predik_test))) # penulisan {0:.2f} adalah untuk menuliskan 2 angka di belakang koma\n",
"print('RMSE = {0:.2f}'.format(np.sqrt(metrics.mean_squared_error(y_test, predik_test))))\n",
"print('R2 = {0:.2f}'.format(metrics.r2_score(y_test, predik_test)))"
]
},
{
"cell_type": "markdown",
"id": "25442c62-caa1-4f10-aa26-eb9723cba1a8",
"metadata": {},
"source": [
"bisa dilihat dari hasil X_train dan X_test dari 0.65 dan 0.70 sangat rendah hampir 50% dari sini peneliti masih kurang puas dengan hasil, untuk itu peneliti akan mencoba lagi dengan pemilihan model terbaik, cross validasi dan hyper paramter tuning."
]
},
{
"cell_type": "markdown",
"id": "32886b77-425d-49f4-b99d-5eb9bd6ba84b",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "c0ee7d9f-5b7f-4ad6-90e7-85dda37779ca",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"((331, 5), (83, 5))"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_train, X_test, y_train, y_test = train_test_split(\n",
" df.drop(['No', 'Date', 'price'], axis=1),\n",
" df['price'],\n",
" test_size= 0.2,\n",
" random_state= 1)\n",
"\n",
"for i in [X_train, X_test, y_train, y_test]:\n",
" i.reset_index(drop=True, inplace=True)\n",
"\n",
"X_train.shape, X_test.shape"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "436eb2b1-2ba3-4206-b26a-14e8472d9bd9",
"metadata": {},
"outputs": [],
"source": [
"preprocessor_numerik = Pipeline([\n",
" ('imputasi', SimpleImputer(strategy='mean')),\n",
" ('scaling', StandardScaler())\n",
"])"
]
},
{
"cell_type": "markdown",
"id": "71dfb628-a6ca-43b0-9687-b62920425850",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "025bfdda-5353-4b4d-8ff9-f7e9f179733f",
"metadata": {},
"outputs": [],
"source": [
"# Model regresi Linear\n",
"linreg = LinearRegression()\n",
"\n",
"# Pipeline model regresi linear\n",
"mod_linreg = Pipeline([\n",
" ('preprocessor_numerik', preprocessor_numerik),\n",
" ('linear', linreg)\n",
"])\n",
"\n",
"# Hyperparameter tuning Linear Regression\n",
"param_linreg = {}"
]
},
{
"cell_type": "markdown",
"id": "a24143e5-8387-416f-b21e-28acd4154f42",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "3cd0ae91-0c65-453e-be0a-3855023d647d",
"metadata": {},
"outputs": [],
"source": [
"# Model regresi Lasso\n",
"lasso = Lasso(alpha=0.001, random_state=0)\n",
"\n",
"# Pipeline model regresi lasso\n",
"mod_lasso = Pipeline([\n",
" ('preprocessor_numerikg', preprocessor_numerik),\n",
" ('lasso', lasso)\n",
"])\n",
"\n",
"# Hyperparameter tuning regresi Lasso\n",
"param_lasso = {'lasso__alpha': np.arange(0.01, 1.0, 0.01)}"
]
},
{
"cell_type": "markdown",
"id": "3eea9575-a218-469e-a9ec-0bf922e5d3ea",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "432dde8e-acd9-4478-b5dd-f31358ea367a",
"metadata": {},
"outputs": [],
"source": [
"# Model regresi Ridge\n",
"ridge = Ridge(alpha=0.5)\n",
"\n",
"# Pipeline model regresi Ridge\n",
"mod_ridge = Pipeline([\n",
" ('preprocessor_numerik', preprocessor_numerik),\n",
" ('ridge', ridge)\n",
"])\n",
"\n",
"# Hyperparameter tuning regresi Lasso\n",
"param_ridge = {'ridge__alpha': np.arange(0.01, 1.0, 0.01),\n",
" 'ridge__solver': ['auto','svd', 'lsqr']\n",
" }"
]
},
{
"cell_type": "markdown",
"id": "7f552dff-18b3-43ab-98f3-9bcf5c7f97d3",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "d0f2e3fa-299a-439e-a2a1-70e66635ebde",
"metadata": {},
"outputs": [],
"source": [
"# Model regresi ElasticNet\n",
"enet = ElasticNet(random_state=0)\n",
"\n",
"# Pipeline model regresi Elastic Net\n",
"mod_enet = Pipeline([\n",
" ('preprocessor_numerik', preprocessor_numerik),\n",
" ('enet', enet)\n",
"])\n",
"\n",
"# Hyperparameter tuning Elastic Net\n",
"param_enet = {\n",
" 'enet__alpha': [0.01, 0.1, 0.5],\n",
" 'enet__l1_ratio': [0.01, 0.1, 0.5, 0.9, 1]\n",
" }"
]
},
{
"cell_type": "markdown",
"id": "77de2a4e-c787-40c8-9bf9-fc7aa25e2eaf",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "0ae77193-f6c9-4ae3-89d2-3b7be253286c",
"metadata": {},
"outputs": [],
"source": [
"# Model regresi Decision Tree\n",
"dt = DecisionTreeRegressor(random_state=0)\n",
"\n",
"# Pipeline model regresi Decision Tree\n",
"mod_dt = Pipeline([\n",
" ('preprocessor_numerik', preprocessor_numerik),\n",
" ('dt', dt)\n",
"])\n",
"\n",
"# Hyperparameter tuning regresi Decision Tree\n",
"param_dt = {\n",
" 'dt__splitter': ['best','random'],\n",
" 'dt__max_depth': np.arange(1,10), \n",
" 'dt__min_samples_split': np.arange(2,10),\n",
" 'dt__min_samples_leaf': np.arange(1,5)\n",
" }"
]
},
{
"cell_type": "markdown",
"id": "5bdee382-37ee-427e-9cc2-400f3d5596d6",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "c65a4a44-ea0b-41e8-a997-d6c3762ce9b0",
"metadata": {},
"outputs": [],
"source": [
"# Model regresi Random Forest\n",
"rf = RandomForestRegressor(random_state=0)\n",
"\n",
"# Pipeline model regresi Random Forest\n",
"mod_rf = Pipeline([\n",
" ('preprocessor_numerik', preprocessor_numerik),\n",
" ('rf', rf)\n",
"])\n",
"\n",
"# Hyperparameter tuning regresi Random Forest\n",
"param_rf = {\n",
" 'rf__criterion': ['squared_error', 'absolute_error', 'friedman_mse', 'poisson'], \n",
" 'rf__min_samples_split': np.arange(2,10),\n",
" 'rf__min_samples_leaf': np.arange(1,5)\n",
" }"
]
},
{
"cell_type": "markdown",
"id": "66f38cd9-0130-4dd9-8ed9-f0cbcf235100",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "c89cecb6-bab3-4c31-a0c3-e5f622c1abaa",
"metadata": {},
"outputs": [],
"source": [
"# Model regresi Gradient Boosting\n",
"gboost = GradientBoostingRegressor(loss='huber',criterion='squared_error',random_state=0)\n",
"\n",
"# Pipeline model regresi Gradient Boosting\n",
"mod_gboost = Pipeline([\n",
" ('preprocessor_numerik', preprocessor_numerik),\n",
" ('gboost', gboost)\n",
" ])\n",
"\n",
"# Hyperparameter tuning Gradient Boosting\n",
"param_gboost = {\n",
" 'gboost__n_estimators':[200, 250, 350, 400], #default 100\n",
" 'gboost__learning_rate':[0.75, 0.1, 1.25], #default 0.1\n",
" 'gboost__max_depth':[2], #default 3\n",
" 'gboost__min_samples_split':[5, 6, 7, 8], #default 2\n",
" 'gboost__min_samples_leaf':[1, 2, 3] # default 1\n",
" }"
]
},
{
"cell_type": "markdown",
"id": "c50dc4f0-af06-41d2-9011-c50bb6065293",
"metadata": {},
"source": [
"Sekarang kita akan mentraining semua model di atas dan mengevaluasinya langsung menggunakan 3-fold cross validation."
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "ef048a5b-82b4-423f-a2f9-1a276ba062a5",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 3.3s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 1.5s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.0s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.0s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.0s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.0s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.0s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.0s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.0s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.0s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.6s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.4s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.4s finished\n",
"[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n",
"[Parallel(n_jobs=-1)]: Done 3 out of 3 | elapsed: 0.3s finished\n"
]
}
],
"source": [
"# Model training dengan cross validation\n",
"daftar_model = [mod_linreg, mod_lasso, mod_ridge, mod_enet, mod_dt, mod_rf, mod_gboost]\n",
"daftar_nama_model = ['linreg', 'lasso', 'ridge', 'elastic', 'dt', 'rf', 'gboost']\n",
"mean_mae = []\n",
"mean_r2 = []\n",
"std_mae = []\n",
"std_r2 = []\n",
"test_score_mae = []\n",
"test_score_r2 = []\n",
"\n",
"# Setting parameter jika permasalahannya adalah klasifikasi\n",
"# skf = StratifiedKFold(n_splits=5, random_state=0, shuffle=True)\n",
"# tentukan cv = skf jika ingin stratified cross validation\n",
"\n",
"# Looping untuk setiap model yang sudah disiapkan \n",
"for i in daftar_model:\n",
" \n",
" # Melakukan cross validation dan menggunakan kriteria berdasarkan skor MAE dan R2\n",
" cv_mae = -cross_val_score(i, X_train, y_train, cv=3, scoring='neg_mean_absolute_error', verbose=1, n_jobs=-1) # kita kalikan dengan -1 karena scoring menggunakan nilai negatif\n",
" cv_r2 = cross_val_score(i, X_train, y_train, cv=3, scoring='r2', verbose=1, n_jobs=-1) # n_jobs=-1 artinya kita gunakan semua prerocessor\n",
" \n",
" # Menghitung nilai rata-rata MAE dan R2 dan menambahkannya ke variabel mean_mae dan mean_r2\n",
" mean_mae.append(round(cv_mae.mean(),2)) # round(nilai,2) untuk membulatkan nilai 2 angka di belakang koma\n",
" mean_r2.append(round(cv_r2.mean(),2))\n",
" \n",
" # Menghitung nilai standar deviasi MAE dan R2 dan menambahkannya ke variabel std_mae dan std_r2\n",
" std_mae.append(round(cv_mae.std(),2))\n",
" std_r2.append(round(cv_r2.std(),2))\n",
" \n",
" # Melakukan fitting training set kemudian melakukan prediksi di test set\n",
" i.fit(X_train, y_train)\n",
" i_predict = i.predict(X_test)\n",
" \n",
" # Menghitung nilai rata-rata MAE dan R2 di test set dan menambahkannya ke variabel test_score_mae dan test_core_r2\n",
" test_score_mae.append(round(mean_absolute_error(y_test, i_predict),2))\n",
" test_score_r2.append(round(r2_score(y_test, i_predict),2))"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "a52c3f8e-f293-4600-b4b4-5d89bed282f2",
"metadata": {},
"outputs": [],
"source": [
"# Membuat DataFrame\n",
"cv_mae = pd.DataFrame({'model':daftar_nama_model, 'Train_Mean':mean_mae, 'std':std_mae, 'Test_Score':test_score_mae})\n",
"cv_r2 = pd.DataFrame({'model':daftar_nama_model, 'Train_Mean':mean_r2, 'std':std_r2, 'Test_Score':test_score_r2})"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "475df902-1956-44f1-815f-323339ce244d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" model \n",
" Train_Mean \n",
" std \n",
" Test_Score \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" linreg \n",
" 6.85 \n",
" 0.88 \n",
" 5.38 \n",
" \n",
" \n",
" 1 \n",
" lasso \n",
" 6.85 \n",
" 0.88 \n",
" 5.38 \n",
" \n",
" \n",
" 2 \n",
" ridge \n",
" 6.85 \n",
" 0.88 \n",
" 5.38 \n",
" \n",
" \n",
" 3 \n",
" elastic \n",
" 7.19 \n",
" 1.11 \n",
" 5.80 \n",
" \n",
" \n",
" 4 \n",
" dt \n",
" 6.52 \n",
" 1.11 \n",
" 5.60 \n",
" \n",
" \n",
" 5 \n",
" rf \n",
" 5.07 \n",
" 0.57 \n",
" 5.37 \n",
" \n",
" \n",
" 6 \n",
" gboost \n",
" 5.02 \n",
" 0.58 \n",
" 5.25 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" model Train_Mean std Test_Score\n",
"0 linreg 6.85 0.88 5.38\n",
"1 lasso 6.85 0.88 5.38\n",
"2 ridge 6.85 0.88 5.38\n",
"3 elastic 7.19 1.11 5.80\n",
"4 dt 6.52 1.11 5.60\n",
"5 rf 5.07 0.57 5.37\n",
"6 gboost 5.02 0.58 5.25"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cv_mae"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "ee2e5334-b984-4637-a273-765b7ee64136",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" model \n",
" Train_Mean \n",
" std \n",
" Test_Score \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" gboost \n",
" 5.02 \n",
" 0.58 \n",
" 5.25 \n",
" \n",
" \n",
" 1 \n",
" rf \n",
" 5.07 \n",
" 0.57 \n",
" 5.37 \n",
" \n",
" \n",
" 2 \n",
" dt \n",
" 6.52 \n",
" 1.11 \n",
" 5.60 \n",
" \n",
" \n",
" 3 \n",
" linreg \n",
" 6.85 \n",
" 0.88 \n",
" 5.38 \n",
" \n",
" \n",
" 4 \n",
" lasso \n",
" 6.85 \n",
" 0.88 \n",
" 5.38 \n",
" \n",
" \n",
" 5 \n",
" ridge \n",
" 6.85 \n",
" 0.88 \n",
" 5.38 \n",
" \n",
" \n",
" 6 \n",
" elastic \n",
" 7.19 \n",
" 1.11 \n",
" 5.80 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" model Train_Mean std Test_Score\n",
"0 gboost 5.02 0.58 5.25\n",
"1 rf 5.07 0.57 5.37\n",
"2 dt 6.52 1.11 5.60\n",
"3 linreg 6.85 0.88 5.38\n",
"4 lasso 6.85 0.88 5.38\n",
"5 ridge 6.85 0.88 5.38\n",
"6 elastic 7.19 1.11 5.80"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Mengurutkan skor dari kecil ke besar\n",
"cv_mae_urut = cv_mae.sort_values(by=['Train_Mean','Test_Score'], ignore_index=True)\n",
"cv_mae_urut"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "37be7061-cc95-4abd-aa30-90fbb8bdf958",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" model \n",
" Train_Mean \n",
" std \n",
" Test_Score \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" linreg \n",
" 0.49 \n",
" 0.11 \n",
" 0.70 \n",
" \n",
" \n",
" 1 \n",
" lasso \n",
" 0.49 \n",
" 0.11 \n",
" 0.70 \n",
" \n",
" \n",
" 2 \n",
" ridge \n",
" 0.49 \n",
" 0.11 \n",
" 0.70 \n",
" \n",
" \n",
" 3 \n",
" elastic \n",
" 0.47 \n",
" 0.12 \n",
" 0.66 \n",
" \n",
" \n",
" 4 \n",
" dt \n",
" 0.38 \n",
" 0.24 \n",
" 0.57 \n",
" \n",
" \n",
" 5 \n",
" rf \n",
" 0.67 \n",
" 0.06 \n",
" 0.61 \n",
" \n",
" \n",
" 6 \n",
" gboost \n",
" 0.66 \n",
" 0.06 \n",
" 0.65 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" model Train_Mean std Test_Score\n",
"0 linreg 0.49 0.11 0.70\n",
"1 lasso 0.49 0.11 0.70\n",
"2 ridge 0.49 0.11 0.70\n",
"3 elastic 0.47 0.12 0.66\n",
"4 dt 0.38 0.24 0.57\n",
"5 rf 0.67 0.06 0.61\n",
"6 gboost 0.66 0.06 0.65"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cv_r2"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "83e3e6a0-ae39-44df-bb64-43826c083f44",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" model \n",
" Train_Mean \n",
" std \n",
" Test_Score \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" rf \n",
" 0.67 \n",
" 0.06 \n",
" 0.61 \n",
" \n",
" \n",
" 1 \n",
" gboost \n",
" 0.66 \n",
" 0.06 \n",
" 0.65 \n",
" \n",
" \n",
" 2 \n",
" linreg \n",
" 0.49 \n",
" 0.11 \n",
" 0.70 \n",
" \n",
" \n",
" 3 \n",
" lasso \n",
" 0.49 \n",
" 0.11 \n",
" 0.70 \n",
" \n",
" \n",
" 4 \n",
" ridge \n",
" 0.49 \n",
" 0.11 \n",
" 0.70 \n",
" \n",
" \n",
" 5 \n",
" elastic \n",
" 0.47 \n",
" 0.12 \n",
" 0.66 \n",
" \n",
" \n",
" 6 \n",
" dt \n",
" 0.38 \n",
" 0.24 \n",
" 0.57 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" model Train_Mean std Test_Score\n",
"0 rf 0.67 0.06 0.61\n",
"1 gboost 0.66 0.06 0.65\n",
"2 linreg 0.49 0.11 0.70\n",
"3 lasso 0.49 0.11 0.70\n",
"4 ridge 0.49 0.11 0.70\n",
"5 elastic 0.47 0.12 0.66\n",
"6 dt 0.38 0.24 0.57"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Mengurutkan skor dari besar ke kecil\n",
"cv_r2_urut = cv_r2.sort_values(by=['Train_Mean','Test_Score'], ascending=False, ignore_index=True)\n",
"cv_r2_urut"
]
},
{
"cell_type": "markdown",
"id": "075b952b-8732-4d3f-9ee9-a76cf22434ef",
"metadata": {},
"source": [
"Bisa dilihat pada skor di atas bahwa model terbaik berdasarkan skor MAE terendah adalah menggunakan gradient boost, namun untuk R2 tertinggi oleh random forest.\n",
"\n",
"Selain itu kita bisa lihat juga performa di *test set* lebih baik daripada di *training set*, artinya modelnya sudah fit."
]
},
{
"cell_type": "markdown",
"id": "930bdddc-41d3-49d9-acea-1d855832af53",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"id": "e1846257-b1d8-4b7c-bd8d-0912866a102c",
"metadata": {},
"source": [
"untuk lebih lebih optimal menggunakan hyper parameter tuning"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "1457ece4-7575-4b32-8da5-c3d41f585c83",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Fitting 5 folds for each of 1 candidates, totalling 5 fits\n",
"Fitting 5 folds for each of 99 candidates, totalling 495 fits\n",
"Fitting 5 folds for each of 297 candidates, totalling 1485 fits\n",
"Fitting 5 folds for each of 15 candidates, totalling 75 fits\n",
"Fitting 5 folds for each of 576 candidates, totalling 2880 fits\n",
"Fitting 5 folds for each of 128 candidates, totalling 640 fits\n",
"Fitting 5 folds for each of 144 candidates, totalling 720 fits\n"
]
}
],
"source": [
"# Model training dengan GridSearchCV\n",
"daftar_model = [mod_linreg, mod_lasso, mod_ridge, mod_enet, mod_dt, mod_rf, mod_gboost]\n",
"daftar_nama_model = ['linreg', 'lasso', 'ridge', 'elastic', 'dt', 'rf', 'gboost']\n",
"daftar_param_model = [param_linreg, param_lasso, param_ridge, param_enet, param_dt, \n",
" param_rf, param_gboost]\n",
"\n",
"# Nilai yang akan diisikan\n",
"mae_tuning = []\n",
"mae_tuning_test = []\n",
"r2_tuning = []\n",
"r2_tuning_test = []\n",
"best_param = []\n",
"best_estimator = []\n",
"\n",
"for i in range(len(daftar_model)):\n",
" \n",
" # Menjalankan GridSearchCV\n",
" model_grid_cv = GridSearchCV(\n",
" daftar_model[i],\n",
" daftar_param_model[i],\n",
" cv=5,\n",
" verbose=1,\n",
" n_jobs=-1\n",
" ).fit(X_train,y_train)\n",
" \n",
" # Mencoba memprediksi training dan test set setelah fitting di training set, kemudian dikemas dalam format DataFrame\n",
" pred_train = pd.DataFrame(model_grid_cv.predict(X_train), columns=[target])\n",
" pred_test = pd.DataFrame(model_grid_cv.predict(X_test), columns=[target])\n",
"\n",
" # Mencatat skor MAE training dan test set\n",
" mae_tuning.append(mean_absolute_error(y_train, pred_train))\n",
" mae_tuning_test.append(mean_absolute_error(y_test, pred_test))\n",
"\n",
" # Mencatat skor R2 training dan test set\n",
" r2_tuning.append(r2_score(y_train, pred_train))\n",
" r2_tuning_test.append(r2_score(y_test, pred_test)) \n",
" \n",
" # Mencatat parameter terbaik di setiap model\n",
" best_param.append(model_grid_cv.best_params_)\n",
" \n",
" # Merekam settingan modelnya\n",
" best_estimator.append(model_grid_cv.best_estimator_)"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "6215f70f-dc2a-438d-bf6c-c1e8e67e9e51",
"metadata": {},
"outputs": [],
"source": [
"# Membuat DataFrame sekaligus kita urutkan\n",
"grid_mae = pd.DataFrame({'model':daftar_nama_model, 'Training':mae_tuning, 'Testing':mae_tuning_test})\n",
"grid_mae_urut = grid_mae.sort_values(by='Testing', ignore_index=True)\n",
"\n",
"grid_r2 = pd.DataFrame({'model':daftar_nama_model, 'Training':r2_tuning, 'Testing':r2_tuning_test})\n",
"grid_r2_urut = grid_r2.sort_values(by='Testing', ascending=False, ignore_index=True)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "f4b8c07c-53b2-4333-ad11-1f1d58e95f3d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" model \n",
" Training \n",
" Testing \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" rf \n",
" 3.173157 \n",
" 4.840727 \n",
" \n",
" \n",
" 1 \n",
" dt \n",
" 4.659948 \n",
" 5.122358 \n",
" \n",
" \n",
" 2 \n",
" gboost \n",
" 3.000884 \n",
" 5.129114 \n",
" \n",
" \n",
" 3 \n",
" elastic \n",
" 6.495830 \n",
" 5.367278 \n",
" \n",
" \n",
" 4 \n",
" lasso \n",
" 6.504837 \n",
" 5.377494 \n",
" \n",
" \n",
" 5 \n",
" ridge \n",
" 6.469763 \n",
" 5.378675 \n",
" \n",
" \n",
" 6 \n",
" linreg \n",
" 6.468697 \n",
" 5.380155 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" model Training Testing\n",
"0 rf 3.173157 4.840727\n",
"1 dt 4.659948 5.122358\n",
"2 gboost 3.000884 5.129114\n",
"3 elastic 6.495830 5.367278\n",
"4 lasso 6.504837 5.377494\n",
"5 ridge 6.469763 5.378675\n",
"6 linreg 6.468697 5.380155"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Melihat performa tuning berdasarkan MAE\n",
"grid_mae_urut"
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "640bdfd5-b3a2-4ae9-96b5-dae1e2fecf61",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" model \n",
" Training \n",
" Testing \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" rf \n",
" 0.852686 \n",
" 0.725545 \n",
" \n",
" \n",
" 1 \n",
" elastic \n",
" 0.535994 \n",
" 0.704105 \n",
" \n",
" \n",
" 2 \n",
" lasso \n",
" 0.536011 \n",
" 0.702151 \n",
" \n",
" \n",
" 3 \n",
" ridge \n",
" 0.537212 \n",
" 0.701203 \n",
" \n",
" \n",
" 4 \n",
" linreg \n",
" 0.537218 \n",
" 0.700731 \n",
" \n",
" \n",
" 5 \n",
" gboost \n",
" 0.829408 \n",
" 0.700595 \n",
" \n",
" \n",
" 6 \n",
" dt \n",
" 0.723694 \n",
" 0.688717 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" model Training Testing\n",
"0 rf 0.852686 0.725545\n",
"1 elastic 0.535994 0.704105\n",
"2 lasso 0.536011 0.702151\n",
"3 ridge 0.537212 0.701203\n",
"4 linreg 0.537218 0.700731\n",
"5 gboost 0.829408 0.700595\n",
"6 dt 0.723694 0.688717"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Melihat performa tuning berdasarkan R2\n",
"grid_r2_urut"
]
},
{
"cell_type": "markdown",
"id": "aa17dd53-86b2-4044-931f-d0b4076c1239",
"metadata": {},
"source": [
"Dari model di atas dapat kita lihat bahwa model terbaik adalah menggunakan random forest yang menemapti urutan 1 pada nilai r2 dan mae.\n",
"\n",
"Sekarang kita bisa menyimpam parameter dan estimator dari setiap model dalam format DataFrame."
]
},
{
"cell_type": "code",
"execution_count": 48,
"id": "623db2d2-7146-417a-a8f3-dd9c590bbe8d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" model \n",
" Param \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" linreg \n",
" {} \n",
" \n",
" \n",
" 1 \n",
" lasso \n",
" {'lasso__alpha': 0.23} \n",
" \n",
" \n",
" 2 \n",
" ridge \n",
" {'ridge__alpha': 0.99, 'ridge__solver': 'svd'} \n",
" \n",
" \n",
" 3 \n",
" elastic \n",
" {'enet__alpha': 0.1, 'enet__l1_ratio': 0.5} \n",
" \n",
" \n",
" 4 \n",
" dt \n",
" {'dt__max_depth': 7, 'dt__min_samples_leaf': 2... \n",
" \n",
" \n",
" 5 \n",
" rf \n",
" {'rf__criterion': 'squared_error', 'rf__min_sa... \n",
" \n",
" \n",
" 6 \n",
" gboost \n",
" {'gboost__learning_rate': 0.1, 'gboost__max_de... \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" model Param\n",
"0 linreg {}\n",
"1 lasso {'lasso__alpha': 0.23}\n",
"2 ridge {'ridge__alpha': 0.99, 'ridge__solver': 'svd'}\n",
"3 elastic {'enet__alpha': 0.1, 'enet__l1_ratio': 0.5}\n",
"4 dt {'dt__max_depth': 7, 'dt__min_samples_leaf': 2...\n",
"5 rf {'rf__criterion': 'squared_error', 'rf__min_sa...\n",
"6 gboost {'gboost__learning_rate': 0.1, 'gboost__max_de..."
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"level_parameter = pd.DataFrame({'model': daftar_nama_model, 'Param' :best_param})\n",
"level_parameter"
]
},
{
"cell_type": "code",
"execution_count": 49,
"id": "285e6eaa-5dcb-4aa0-9bd7-644c20028d31",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" model \n",
" Param \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" linreg \n",
" ((SimpleImputer(), StandardScaler()), LinearRe... \n",
" \n",
" \n",
" 1 \n",
" lasso \n",
" ((SimpleImputer(), StandardScaler()), Lasso(al... \n",
" \n",
" \n",
" 2 \n",
" ridge \n",
" ((SimpleImputer(), StandardScaler()), Ridge(al... \n",
" \n",
" \n",
" 3 \n",
" elastic \n",
" ((SimpleImputer(), StandardScaler()), ElasticN... \n",
" \n",
" \n",
" 4 \n",
" dt \n",
" ((SimpleImputer(), StandardScaler()), Decision... \n",
" \n",
" \n",
" 5 \n",
" rf \n",
" ((SimpleImputer(), StandardScaler()), (Decisio... \n",
" \n",
" \n",
" 6 \n",
" gboost \n",
" ((SimpleImputer(), StandardScaler()), ([Decisi... \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" model Param\n",
"0 linreg ((SimpleImputer(), StandardScaler()), LinearRe...\n",
"1 lasso ((SimpleImputer(), StandardScaler()), Lasso(al...\n",
"2 ridge ((SimpleImputer(), StandardScaler()), Ridge(al...\n",
"3 elastic ((SimpleImputer(), StandardScaler()), ElasticN...\n",
"4 dt ((SimpleImputer(), StandardScaler()), Decision...\n",
"5 rf ((SimpleImputer(), StandardScaler()), (Decisio...\n",
"6 gboost ((SimpleImputer(), StandardScaler()), ([Decisi..."
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Estimator terbaik dari model terbaik\n",
"level_estimator = pd.DataFrame({'model':daftar_nama_model, 'Param':best_estimator})\n",
"level_estimator"
]
},
{
"cell_type": "code",
"execution_count": 50,
"id": "9c04f669-d8e2-4c41-aca3-f0546c9bd22a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'rf__criterion': 'squared_error',\n",
" 'rf__min_samples_leaf': 3,\n",
" 'rf__min_samples_split': 2}"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Parameter terbaik Random Forest Regression (model kelima)\n",
"level_parameter['Param'][5]"
]
},
{
"cell_type": "code",
"execution_count": 51,
"id": "fbf9120e-39a8-4e26-9119-ac9f8568c824",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"Pipeline(steps=[('preprocessor_numerik',\n",
" Pipeline(steps=[('imputasi', SimpleImputer()),\n",
" ('scaling', StandardScaler())])),\n",
" ('rf',\n",
" RandomForestRegressor(min_samples_leaf=3, random_state=0))]) In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org. Pipeline Pipeline(steps=[('preprocessor_numerik',\n",
" Pipeline(steps=[('imputasi', SimpleImputer()),\n",
" ('scaling', StandardScaler())])),\n",
" ('rf',\n",
" RandomForestRegressor(min_samples_leaf=3, random_state=0))]) "
],
"text/plain": [
"Pipeline(steps=[('preprocessor_numerik',\n",
" Pipeline(steps=[('imputasi', SimpleImputer()),\n",
" ('scaling', StandardScaler())])),\n",
" ('rf',\n",
" RandomForestRegressor(min_samples_leaf=3, random_state=0))])"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"level_estimator['Param'][5]"
]
},
{
"cell_type": "code",
"execution_count": 52,
"id": "cd6d52c9-b224-4f25-ad91-e7ac9c924fa5",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" model \n",
" Param \n",
" Testing \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" rf \n",
" {'rf__criterion': 'squared_error', 'rf__min_sa... \n",
" 0.725545 \n",
" \n",
" \n",
" 1 \n",
" elastic \n",
" {'enet__alpha': 0.1, 'enet__l1_ratio': 0.5} \n",
" 0.704105 \n",
" \n",
" \n",
" 2 \n",
" lasso \n",
" {'lasso__alpha': 0.23} \n",
" 0.702151 \n",
" \n",
" \n",
" 3 \n",
" ridge \n",
" {'ridge__alpha': 0.99, 'ridge__solver': 'svd'} \n",
" 0.701203 \n",
" \n",
" \n",
" 4 \n",
" linreg \n",
" {} \n",
" 0.700731 \n",
" \n",
" \n",
" 5 \n",
" gboost \n",
" {'gboost__learning_rate': 0.1, 'gboost__max_de... \n",
" 0.700595 \n",
" \n",
" \n",
" 6 \n",
" dt \n",
" {'dt__max_depth': 7, 'dt__min_samples_leaf': 2... \n",
" 0.688717 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" model Param Testing\n",
"0 rf {'rf__criterion': 'squared_error', 'rf__min_sa... 0.725545\n",
"1 elastic {'enet__alpha': 0.1, 'enet__l1_ratio': 0.5} 0.704105\n",
"2 lasso {'lasso__alpha': 0.23} 0.702151\n",
"3 ridge {'ridge__alpha': 0.99, 'ridge__solver': 'svd'} 0.701203\n",
"4 linreg {} 0.700731\n",
"5 gboost {'gboost__learning_rate': 0.1, 'gboost__max_de... 0.700595\n",
"6 dt {'dt__max_depth': 7, 'dt__min_samples_leaf': 2... 0.688717"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Kita gabungkan semua dan urutkan berdasarkan nilai R2 di test set sebagai 'model_best_param'\n",
"model_best_param = pd.DataFrame({'model':daftar_nama_model, 'Param':best_param, 'Testing':r2_tuning_test})\n",
"model_best_param = model_best_param.sort_values(by='Testing', ascending=False, ignore_index=True)\n",
"model_best_param"
]
},
{
"cell_type": "code",
"execution_count": 53,
"id": "4f05ade9-0beb-40ba-a14f-aff9fe9432dc",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" model \n",
" Param \n",
" Testing \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" rf \n",
" ((SimpleImputer(), StandardScaler()), (Decisio... \n",
" 0.725545 \n",
" \n",
" \n",
" 1 \n",
" elastic \n",
" ((SimpleImputer(), StandardScaler()), ElasticN... \n",
" 0.704105 \n",
" \n",
" \n",
" 2 \n",
" lasso \n",
" ((SimpleImputer(), StandardScaler()), Lasso(al... \n",
" 0.702151 \n",
" \n",
" \n",
" 3 \n",
" ridge \n",
" ((SimpleImputer(), StandardScaler()), Ridge(al... \n",
" 0.701203 \n",
" \n",
" \n",
" 4 \n",
" linreg \n",
" ((SimpleImputer(), StandardScaler()), LinearRe... \n",
" 0.700731 \n",
" \n",
" \n",
" 5 \n",
" gboost \n",
" ((SimpleImputer(), StandardScaler()), ([Decisi... \n",
" 0.700595 \n",
" \n",
" \n",
" 6 \n",
" dt \n",
" ((SimpleImputer(), StandardScaler()), Decision... \n",
" 0.688717 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" model Param Testing\n",
"0 rf ((SimpleImputer(), StandardScaler()), (Decisio... 0.725545\n",
"1 elastic ((SimpleImputer(), StandardScaler()), ElasticN... 0.704105\n",
"2 lasso ((SimpleImputer(), StandardScaler()), Lasso(al... 0.702151\n",
"3 ridge ((SimpleImputer(), StandardScaler()), Ridge(al... 0.701203\n",
"4 linreg ((SimpleImputer(), StandardScaler()), LinearRe... 0.700731\n",
"5 gboost ((SimpleImputer(), StandardScaler()), ([Decisi... 0.700595\n",
"6 dt ((SimpleImputer(), StandardScaler()), Decision... 0.688717"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# menggabungkan semua dan urutkan berdasarkan nilai R2 di test set sebagai 'model_best_estimator'\n",
"model_best_estimator = pd.DataFrame({'model':daftar_nama_model, 'Param':best_estimator, 'Testing':r2_tuning_test})\n",
"model_best_estimator = model_best_estimator.sort_values(by='Testing', ascending=False, ignore_index=True)\n",
"model_best_estimator"
]
},
{
"cell_type": "markdown",
"id": "cb4b8a22-3093-4c9c-8517-6975fe7f3fd4",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"id": "d1a67760-4840-4e84-8fc0-8df37648e63d",
"metadata": {},
"source": [
"## Menggunakan Model Terbaik"
]
},
{
"cell_type": "markdown",
"id": "44678a08-51df-41bb-991f-e912f138fff1",
"metadata": {},
"source": [
"mentraining parameter model terbaik denga dataset penuh"
]
},
{
"cell_type": "markdown",
"id": "bb5bdfd0-e7a9-4194-8dcb-0e97ace61ad6",
"metadata": {},
"source": [
"### memanggil data awal proses tadi"
]
},
{
"cell_type": "code",
"execution_count": 54,
"id": "3d58c279-75ad-4497-bf0d-2b6d7aec0514",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" No \n",
" Date \n",
" Age \n",
" Distance_MRT \n",
" Total_Sotres \n",
" Latitude \n",
" longitude \n",
" price \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 1 \n",
" 2012.916667 \n",
" 32.0 \n",
" 84.87882 \n",
" 10 \n",
" 24.98298 \n",
" 121.54024 \n",
" 37.9 \n",
" \n",
" \n",
" 1 \n",
" 2 \n",
" 2012.916667 \n",
" 19.5 \n",
" 306.59470 \n",
" 9 \n",
" 24.98034 \n",
" 121.53951 \n",
" 42.2 \n",
" \n",
" \n",
" 2 \n",
" 3 \n",
" 2013.583333 \n",
" 13.3 \n",
" 561.98450 \n",
" 5 \n",
" 24.98746 \n",
" 121.54391 \n",
" 47.3 \n",
" \n",
" \n",
" 3 \n",
" 4 \n",
" 2013.500000 \n",
" 13.3 \n",
" 561.98450 \n",
" 5 \n",
" 24.98746 \n",
" 121.54391 \n",
" 54.8 \n",
" \n",
" \n",
" 4 \n",
" 5 \n",
" 2012.833333 \n",
" 5.0 \n",
" 390.56840 \n",
" 5 \n",
" 24.97937 \n",
" 121.54245 \n",
" 43.1 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" No Date Age Distance_MRT Total_Sotres Latitude longitude \\\n",
"0 1 2012.916667 32.0 84.87882 10 24.98298 121.54024 \n",
"1 2 2012.916667 19.5 306.59470 9 24.98034 121.53951 \n",
"2 3 2013.583333 13.3 561.98450 5 24.98746 121.54391 \n",
"3 4 2013.500000 13.3 561.98450 5 24.98746 121.54391 \n",
"4 5 2012.833333 5.0 390.56840 5 24.97937 121.54245 \n",
"\n",
" price \n",
"0 37.9 \n",
"1 42.2 \n",
"2 47.3 \n",
"3 54.8 \n",
"4 43.1 "
]
},
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.head()"
]
},
{
"cell_type": "code",
"execution_count": 55,
"id": "8bb4ca42-78d8-43a7-a090-00574bf24483",
"metadata": {},
"outputs": [],
"source": [
"# Kita bagi variabel independen dan dependen-nya\n",
"X = df.iloc[:,2:-1]\n",
"y = df.iloc[:,-1]"
]
},
{
"cell_type": "code",
"execution_count": 56,
"id": "a187a519-df74-41f0-943e-3d609b1148de",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Age \n",
" Distance_MRT \n",
" Total_Sotres \n",
" Latitude \n",
" longitude \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 32.0 \n",
" 84.87882 \n",
" 10 \n",
" 24.98298 \n",
" 121.54024 \n",
" \n",
" \n",
" 1 \n",
" 19.5 \n",
" 306.59470 \n",
" 9 \n",
" 24.98034 \n",
" 121.53951 \n",
" \n",
" \n",
" 2 \n",
" 13.3 \n",
" 561.98450 \n",
" 5 \n",
" 24.98746 \n",
" 121.54391 \n",
" \n",
" \n",
" 3 \n",
" 13.3 \n",
" 561.98450 \n",
" 5 \n",
" 24.98746 \n",
" 121.54391 \n",
" \n",
" \n",
" 4 \n",
" 5.0 \n",
" 390.56840 \n",
" 5 \n",
" 24.97937 \n",
" 121.54245 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Age Distance_MRT Total_Sotres Latitude longitude\n",
"0 32.0 84.87882 10 24.98298 121.54024\n",
"1 19.5 306.59470 9 24.98034 121.53951\n",
"2 13.3 561.98450 5 24.98746 121.54391\n",
"3 13.3 561.98450 5 24.98746 121.54391\n",
"4 5.0 390.56840 5 24.97937 121.54245"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X.head()"
]
},
{
"cell_type": "code",
"execution_count": 57,
"id": "0b93dd3a-e435-4561-96ea-291d3eec90b6",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 37.9\n",
"1 42.2\n",
"2 47.3\n",
"3 54.8\n",
"4 43.1\n",
"Name: price, dtype: float64"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y.head()"
]
},
{
"cell_type": "markdown",
"id": "e0625540-1ce4-4cf2-a880-6c541fcddeac",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"id": "6b3745e4-1ac5-4339-8a11-f9db9244f941",
"metadata": {},
"source": [
"### Training Ulang Model Akhir Dengan Dataset Utuh"
]
},
{
"cell_type": "code",
"execution_count": 58,
"id": "529af8c3-1c3e-4d3a-acb7-1c6c7810a7a8",
"metadata": {},
"outputs": [],
"source": [
"model_akhir_otomastis = model_best_estimator['Param'][0].fit(X,y)"
]
},
{
"cell_type": "code",
"execution_count": 59,
"id": "de6d6f87-7666-4f85-bc5c-6073ded5250f",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"Pipeline(steps=[('preprocessor_numerik',\n",
" Pipeline(steps=[('imputasi', SimpleImputer()),\n",
" ('scaling', StandardScaler())])),\n",
" ('rf',\n",
" RandomForestRegressor(min_samples_leaf=3, random_state=0))]) In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org. Pipeline Pipeline(steps=[('preprocessor_numerik',\n",
" Pipeline(steps=[('imputasi', SimpleImputer()),\n",
" ('scaling', StandardScaler())])),\n",
" ('rf',\n",
" RandomForestRegressor(min_samples_leaf=3, random_state=0))]) "
],
"text/plain": [
"Pipeline(steps=[('preprocessor_numerik',\n",
" Pipeline(steps=[('imputasi', SimpleImputer()),\n",
" ('scaling', StandardScaler())])),\n",
" ('rf',\n",
" RandomForestRegressor(min_samples_leaf=3, random_state=0))])"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model_akhir_otomastis"
]
},
{
"cell_type": "code",
"execution_count": 60,
"id": "708690c5-3451-42a1-953c-83ec8a8da42a",
"metadata": {},
"outputs": [],
"source": [
"# Mencoba memprediksi training dan test set setelah fitting di training set, kemudian dikemas dalam format DataFrame\n",
"pred_train_otomatis = pd.DataFrame(model_akhir_otomastis.predict(X_train), columns=[target])\n",
"pred_test_otomatis = pd.DataFrame(model_akhir_otomastis.predict(X_test), columns=[target])"
]
},
{
"cell_type": "code",
"execution_count": 61,
"id": "35bce141-56eb-4e10-8702-cb7845b3fd5a",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Prediksi \n",
" Asli \n",
" Error \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 37.956955 \n",
" 37.4 \n",
" 0.556955 \n",
" \n",
" \n",
" 1 \n",
" 50.387571 \n",
" 51.8 \n",
" 1.412429 \n",
" \n",
" \n",
" 2 \n",
" 58.550618 \n",
" 58.1 \n",
" 0.450618 \n",
" \n",
" \n",
" 3 \n",
" 48.731643 \n",
" 49.5 \n",
" 0.768357 \n",
" \n",
" \n",
" 4 \n",
" 28.899963 \n",
" 30.6 \n",
" 1.700037 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Prediksi Asli Error\n",
"0 37.956955 37.4 0.556955\n",
"1 50.387571 51.8 1.412429\n",
"2 58.550618 58.1 0.450618\n",
"3 48.731643 49.5 0.768357\n",
"4 28.899963 30.6 1.700037"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Membandingkan 2 numpy array (kita gunakan np.column_stack untuk menggabungkan kedua array ini)\n",
"banding_train_otomatis = pd.DataFrame(np.column_stack((pred_train_otomatis, pd.DataFrame(y_train), abs(pred_train_otomatis - pd.DataFrame(y_train)))), columns=['Prediksi', 'Asli', 'Error'])\n",
"banding_train_otomatis.head()"
]
},
{
"cell_type": "code",
"execution_count": 62,
"id": "ada4228b-1f1d-4bc9-a4d8-3da838797114",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Prediksi \n",
" Asli \n",
" Error \n",
" \n",
" \n",
" \n",
" \n",
" count \n",
" 331.000000 \n",
" 331.000000 \n",
" 331.000000 \n",
" \n",
" \n",
" mean \n",
" 38.544127 \n",
" 38.712991 \n",
" 3.134446 \n",
" \n",
" \n",
" std \n",
" 12.090960 \n",
" 13.814414 \n",
" 4.203389 \n",
" \n",
" \n",
" min \n",
" 14.603233 \n",
" 7.600000 \n",
" 0.001991 \n",
" \n",
" \n",
" 25% \n",
" 27.909553 \n",
" 28.450000 \n",
" 0.904570 \n",
" \n",
" \n",
" 50% \n",
" 39.585019 \n",
" 39.300000 \n",
" 2.021594 \n",
" \n",
" \n",
" 75% \n",
" 47.106554 \n",
" 47.300000 \n",
" 3.943572 \n",
" \n",
" \n",
" max \n",
" 67.117270 \n",
" 117.500000 \n",
" 50.743411 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Prediksi Asli Error\n",
"count 331.000000 331.000000 331.000000\n",
"mean 38.544127 38.712991 3.134446\n",
"std 12.090960 13.814414 4.203389\n",
"min 14.603233 7.600000 0.001991\n",
"25% 27.909553 28.450000 0.904570\n",
"50% 39.585019 39.300000 2.021594\n",
"75% 47.106554 47.300000 3.943572\n",
"max 67.117270 117.500000 50.743411"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"banding_train_otomatis.describe()"
]
},
{
"cell_type": "code",
"execution_count": 63,
"id": "aa309118-7caf-4ec6-8677-9ffb2ec09d29",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Prediksi \n",
" Asli \n",
" Error \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 25.365133 \n",
" 27.3 \n",
" 1.934867 \n",
" \n",
" \n",
" 1 \n",
" 49.588137 \n",
" 54.4 \n",
" 4.811863 \n",
" \n",
" \n",
" 2 \n",
" 23.537696 \n",
" 22.0 \n",
" 1.537696 \n",
" \n",
" \n",
" 3 \n",
" 15.091492 \n",
" 11.6 \n",
" 3.491492 \n",
" \n",
" \n",
" 4 \n",
" 53.596848 \n",
" 45.4 \n",
" 8.196848 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Prediksi Asli Error\n",
"0 25.365133 27.3 1.934867\n",
"1 49.588137 54.4 4.811863\n",
"2 23.537696 22.0 1.537696\n",
"3 15.091492 11.6 3.491492\n",
"4 53.596848 45.4 8.196848"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\n",
"banding_test_otomatis = pd.DataFrame(np.column_stack((pred_test_otomatis, pd.DataFrame(y_test), abs(pred_test_otomatis - pd.DataFrame(y_test)))), columns=['Prediksi', 'Asli', 'Error'])\n",
"banding_test_otomatis.head()"
]
},
{
"cell_type": "code",
"execution_count": 64,
"id": "8ab31797-2d61-4732-80b7-d289f1c55215",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Prediksi \n",
" Asli \n",
" Error \n",
" \n",
" \n",
" \n",
" \n",
" count \n",
" 83.000000 \n",
" 83.000000 \n",
" 83.000000 \n",
" \n",
" \n",
" mean \n",
" 36.250759 \n",
" 35.057831 \n",
" 2.812076 \n",
" \n",
" \n",
" std \n",
" 12.365585 \n",
" 12.395043 \n",
" 2.521332 \n",
" \n",
" \n",
" min \n",
" 15.091492 \n",
" 11.600000 \n",
" 0.009281 \n",
" \n",
" \n",
" 25% \n",
" 26.505429 \n",
" 23.800000 \n",
" 0.901083 \n",
" \n",
" \n",
" 50% \n",
" 37.825870 \n",
" 36.900000 \n",
" 1.934867 \n",
" \n",
" \n",
" 75% \n",
" 45.366317 \n",
" 42.900000 \n",
" 4.188026 \n",
" \n",
" \n",
" max \n",
" 59.661956 \n",
" 59.600000 \n",
" 10.897020 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Prediksi Asli Error\n",
"count 83.000000 83.000000 83.000000\n",
"mean 36.250759 35.057831 2.812076\n",
"std 12.365585 12.395043 2.521332\n",
"min 15.091492 11.600000 0.009281\n",
"25% 26.505429 23.800000 0.901083\n",
"50% 37.825870 36.900000 1.934867\n",
"75% 45.366317 42.900000 4.188026\n",
"max 59.661956 59.600000 10.897020"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"banding_test_otomatis.describe()"
]
},
{
"cell_type": "code",
"execution_count": 65,
"id": "d1e227b2-5b8c-4db1-8a31-70368be52a41",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Error train set 3.134\n",
"Error test set 2.812\n"
]
}
],
"source": [
"# Melihat skor MAE setelah tuning\n",
"print(f'Error train set {mean_absolute_error(y_train, pred_train_otomatis):.3f}')\n",
"print(f'Error test set {mean_absolute_error(y_test, pred_test_otomatis):.3f}')"
]
},
{
"cell_type": "code",
"execution_count": 66,
"id": "98b3d4e8-d29f-4f4b-9fc5-e457c179cf92",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"R2 train set = 0.856\n",
"R2 test set = 0.907\n"
]
}
],
"source": [
"# Melihat skor R2 setelah tuning\n",
"print(f'R2 train set = {r2_score(y_train, pred_train_otomatis):.3f}')\n",
"print(f'R2 test set = {r2_score(y_test, pred_test_otomatis):.3f}')"
]
},
{
"cell_type": "code",
"execution_count": 67,
"id": "3ee46963-7fdb-4103-9230-b11f48b07fb3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.856\n",
"0.907\n"
]
}
],
"source": [
"# Melihat R2 dengan menggunakan method 'score'\n",
"print(round(model_akhir_otomastis.score(X_train, y_train),3))\n",
"print(round(model_akhir_otomastis.score(X_test, y_test),3))"
]
},
{
"cell_type": "markdown",
"id": "105af1d2-b011-48a6-8f33-151a7aeb4470",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"id": "1985fe84-7f01-4667-a947-707579a3b2a9",
"metadata": {},
"source": [
"### Menyimpan Model"
]
},
{
"cell_type": "code",
"execution_count": 68,
"id": "409525c6-8d7d-4ab2-b56c-cf0547b92ea7",
"metadata": {},
"outputs": [],
"source": [
"import pickle"
]
},
{
"cell_type": "code",
"execution_count": 69,
"id": "f2090b0a-fb3f-47a4-bbdb-a9e90ddd56aa",
"metadata": {},
"outputs": [],
"source": [
"# Menyimpan model dengan nama 'model_regresi_terbaik.pkl'\n",
"pickle.dump(model_akhir_otomastis, open('model_regresi_realestate.pkl', 'wb'))"
]
},
{
"cell_type": "code",
"execution_count": 70,
"id": "39d4f558-5b16-4065-984b-ccc8a214d3bd",
"metadata": {},
"outputs": [],
"source": [
"best_model = pickle.load(open('model_regresi_realestate.pkl', 'rb'))"
]
},
{
"cell_type": "code",
"execution_count": 71,
"id": "a4c9fd28-fa77-4d6d-b45b-0f7b2571a9a6",
"metadata": {},
"outputs": [],
"source": [
"prediksi = best_model.predict(X_test)"
]
},
{
"cell_type": "code",
"execution_count": 72,
"id": "9a33eb60-b4e0-4c49-a786-04642e863f51",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([25.36513312, 49.58813707, 23.53769632, 15.09149192, 53.5968484 ,\n",
" 26.62990923, 24.92314482, 33.47161876, 38.99839109, 18.41769968,\n",
" 17.40928084, 37.14860224, 23.57370049, 44.16059913, 54.79656104,\n",
" 22.36188506, 53.5968484 , 43.39913588, 27.41186374, 48.52032763,\n",
" 46.1403558 , 23.97747107, 37.8747926 , 59.12870727, 51.22921429,\n",
" 26.3939 , 29.4381557 , 51.67359258, 47.2277215 , 17.16195631,\n",
" 30.20013785, 37.47691944, 41.48889206, 50.94102314, 46.70533535,\n",
" 17.7374671 , 37.82586962, 37.58559887, 42.259326 , 17.1534004 ,\n",
" 39.74715667, 16.25023175, 59.66195558, 30.57614654, 29.44505325,\n",
" 26.61695768, 22.80101331, 42.93427837, 38.04899524, 37.82812385,\n",
" 17.7374671 , 55.19701974, 43.05059957, 16.0955438 , 49.28513763,\n",
" 40.71226944, 53.5968484 , 38.95569908, 36.69922615, 40.08712758,\n",
" 15.79309127, 34.49000397, 27.89192287, 17.7374671 , 41.94553939,\n",
" 37.25059571, 51.28433846, 41.46778748, 16.12176154, 41.67784149,\n",
" 48.8599261 , 16.93294358, 33.99375173, 29.11361454, 54.81626342,\n",
" 36.84870188, 33.30433813, 38.91979075, 34.03963373, 51.47944844,\n",
" 43.48584838, 49.82051014, 44.59227832])"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"prediksi"
]
},
{
"cell_type": "code",
"execution_count": 73,
"id": "d4df069b-2893-4eaa-b938-9beae29d9a51",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" price \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 25.365133 \n",
" \n",
" \n",
" 1 \n",
" 49.588137 \n",
" \n",
" \n",
" 2 \n",
" 23.537696 \n",
" \n",
" \n",
" 3 \n",
" 15.091492 \n",
" \n",
" \n",
" 4 \n",
" 53.596848 \n",
" \n",
" \n",
" ... \n",
" ... \n",
" \n",
" \n",
" 78 \n",
" 34.039634 \n",
" \n",
" \n",
" 79 \n",
" 51.479448 \n",
" \n",
" \n",
" 80 \n",
" 43.485848 \n",
" \n",
" \n",
" 81 \n",
" 49.820510 \n",
" \n",
" \n",
" 82 \n",
" 44.592278 \n",
" \n",
" \n",
"
\n",
"
83 rows × 1 columns
\n",
"
"
],
"text/plain": [
" price\n",
"0 25.365133\n",
"1 49.588137\n",
"2 23.537696\n",
"3 15.091492\n",
"4 53.596848\n",
".. ...\n",
"78 34.039634\n",
"79 51.479448\n",
"80 43.485848\n",
"81 49.820510\n",
"82 44.592278\n",
"\n",
"[83 rows x 1 columns]"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"prediksi = pd.DataFrame(prediksi, columns=[target])\n",
"prediksi"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ff09aa4d-26b5-4d04-b0f1-52adf1765a6c",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.11.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}