import%20marimo%0A%0A__generated_with%20%3D%20%220.17.7%22%0Aapp%20%3D%20marimo.App(width%3D%22full%22%2C%20auto_download%3D%5B%22ipynb%22%5D)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20I%20was%20searching%20for%20interesting%20datasets%20and%20in%20Reddit%20I%20found%20https%3A%2F%2Fwww.airroi.com%2F%2C%20a%20page%20focused%20in%20Airbnb%20data%20analytics.%20It%20has%20some%20little%20sample%20datasets%2C%20and%20I%20decided%20to%20predict%20the%20*Number%20of%20booked%2Freserved%20days%20in%20trailing%20twelve%20months*%20for%20the%20available%20datasets%20of%20mexican%20cities%20with%20beaches%3A%0A%20%20%20%201.%20Acapulco.%0A%20%20%20%202.%20Bacalar.%0A%20%20%20%203.%20Cabo%20San%20Lucas.%0A%20%20%20%204.%20Cancun.%0A%20%20%20%205.%20Ensenada.%0A%20%20%20%206.%20Isla%20Mujeres.%0A%20%20%20%207.%20La%20Paz.%0A%20%20%20%208.%20Manzanillo.%0A%20%20%20%209.%20Mazatlan.%0A%20%20%20%2010.%20Playa%20del%20Carmen.%0A%20%20%20%2011.%20Puerto%20Escondido.%0A%20%20%20%2012.%20Puerto%20Morelos.%0A%20%20%20%2013.%20Puerto%20Vallarta.%0A%20%20%20%2014.%20Rosarito.%0A%20%20%20%2015.%20San%20Jose%20del%20Cabo.%0A%20%20%20%2016.%20San%20Miguel%20de%20Cozumel.%0A%20%20%20%2017.%20Sayulita.%0A%20%20%20%2018.%20Tulum.%0A%0A%20%20%20%20One%20csv%20file%20for%20each%20city.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20holoviews%20as%20hv%0A%20%20%20%20from%20holoviews%20import%20opts%0A%20%20%20%20from%20holoviews.operation%20import%20gridmatrix%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20glob%0A%20%20%20%20return%20glob%2C%20gridmatrix%2C%20hv%2C%20mo%2C%20np%2C%20opts%2C%20pd%0A%0A%0A%40app.cell%0Adef%20_(glob%2C%20mo%2C%20pd)%3A%0A%20%20%20%20%23%20Get%20a%20list%20of%20all%20csv%20files%20in%20the%20'.%2Fdata'%20directory%0A%20%20%20%20csv_files%20%3D%20glob.glob('.%2Fdata%2F*.csv')%0A%0A%20%20%20%20%23%20Check%20if%20any%20files%20were%20found%20before%20proceeding%0A%20%20%20%20if%20csv_files%3A%0A%20%20%20%20%20%20%20%20%23%20Read%20all%20CSVs%20into%20a%20list%20of%20DataFrames%20and%20then%20concatenate%20them.%0A%20%20%20%20%20%20%20%20%23%20We%20use%20on_bad_lines%3D'skip'%20to%20handle%20potential%20malformed%20rows.%0A%20%20%20%20%20%20%20%20combined_df%20%3D%20pd.concat(%0A%20%20%20%20%20%20%20%20%20%20%20%20%5Bpd.read_csv(file%2C%20on_bad_lines%3D'skip')%20for%20file%20in%20csv_files%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ignore_index%3DTrue%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20mo.md(%22No%20CSV%20files%20found%20in%20the%20%60.%2Fdata%60%20directory.%22)%0A%20%20%20%20%20%20%20%20combined_df%20%3D%20pd.DataFrame()%20%23%20Create%20an%20empty%20dataframe%0A%20%20%20%20combined_df%0A%20%20%20%20return%20(combined_df%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%204484%20samples%20and%2062%20features.%20Lets%20do%20the%20EDA.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20EDA%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Data%20cleaning%20and%20%22feature%20engineering%22%20%F0%9F%A5%B8%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20First%20of%20all%20I%20will%20see%20the%20data%20types%20of%20the%20dataset%20and%20its%20descriptive%20statistics%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(combined_df)%3A%0A%20%20%20%20combined_df.info()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(combined_df)%3A%0A%20%20%20%20combined_df.describe()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20A%20lot%20of%20features%20are%20not%20listed%20using%20*combined_df.describe()*%20method.%20But%20*combined_df.info()*%20was%20helpful%20to%20identify%20missing%20data%20for%20some%20features.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20First%20columns%20drop.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20I%20want%20to%20predict%20*ttm_reserved_days*%20using%20the%20descriptive%20features%20of%20the%20listing.%20So%20I%20decided%20to%20drop%20the%20following%20columns%20without%20EDA%2C%20good%20or%20bad%20decision%3F%20I%20will%20never%20know%20%F0%9F%A4%A3.%0A%0A%0A%20%20%20%20The%20dropped%20features%20are%3A%0A%20%20%20%201.%20listing_name%0A%20%20%20%202.%20cover_photo_url%0A%20%20%20%203.%20host_id%0A%20%20%20%204.%20host_name%0A%20%20%20%205.%20cohost_ids%0A%20%20%20%206.%20cohost_names%0A%20%20%20%207.%20latitude%0A%20%20%20%208.%20longitude%0A%20%20%20%209.%20registration%0A%20%20%20%2010.%20cancellation_policy%0A%20%20%20%2011.%20currency%0A%0A%20%20%20%20I%20also%20include%20latitude%20and%20longituge%20because%20all%20are%20in%20Mexico%2C%20maybe%20in%20cities%20very%20far%20between%20them%2C%20but%20my%20analysis%20is%20at%20country%20level.%0A%0A%20%20%20%20And%20I%20will%20also%20dropped%20all%20*ttm*%20and%20l90%20columns.%20Because%20I%20want%20to%20train%20my%20model%20with%20information%20when%20you%20are%20planning%20to%20open%20an%20Airbnb%20or%20at%20your%20start%2C%20not%2012%20or%203%20months%20later.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(combined_df)%3A%0A%20%20%20%20descriptive_features_df%3D%20combined_df.drop(columns%3D%5B'listing_id'%2C%20'listing_name'%2C%20'cover_photo_url'%2C%20'host_id'%2C%20'host_name'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'cohost_ids'%2C'cohost_names'%2C%20'latitude'%2C'longitude'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'registration'%2C%20'currency'%2C%20'ttm_revenue'%2C%20'ttm_revenue_native'%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'ttm_avg_rate'%2C%20'ttm_avg_rate_native'%2C%20'ttm_occupancy'%2C%20'ttm_adjusted_occupancy'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'ttm_revpar'%2C%20'ttm_revpar_native'%2C%20'ttm_adjusted_revpar'%2C%20'ttm_adjusted_revpar_native'%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'ttm_blocked_days'%2C%20'ttm_available_days'%2C%20'ttm_total_days'%2C%20'l90d_revenue'%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'l90d_revenue_native'%2C%20'l90d_avg_rate'%2C%20'l90d_avg_rate_native'%2C%20'l90d_occupancy'%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'l90d_adjusted_occupancy'%2C%20'l90d_revpar'%2C%20'l90d_revpar_native'%2C%20'l90d_adjusted_revpar'%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'l90d_adjusted_revpar_native'%2C%20'l90d_reserved_days'%2C%20'l90d_blocked_days'%2C%20'l90d_available_days'%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'l90d_total_days'%5D)%0A%20%20%20%20return%20(descriptive_features_df%2C)%0A%0A%0A%40app.cell%0Adef%20_(descriptive_features_df)%3A%0A%20%20%20%20descriptive_features_df.info()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20_Listin_id_%20because%20it%20is%20not%20a%20feature%2C%20it%20is%20an%20identifier.%20Probably%20I%20will%20use%20it%20later%2C%20so%20I%20will%20convert%20it%20in%20my%20index.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%23%20descriptive_features_index%20%3D%20descriptive_features_df.set_index('listing_id')%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Why%20instant_book%20and%20professional_management%20are%20not%20booleans%3F%0A%0A%20%20%20%20These%20two%20are%20currently%20object%20type%2C%20so%2C%20lets%20check%20why%20and%20if%20is%20it%20possible%20to%20convert%20them%20into%20booleans.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(descriptive_features_df)%3A%0A%20%20%20%20descriptive_features_df%5B'instant_book'%5D.value_counts(dropna%3DFalse)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20I%20decied%20to%20drop%20260%20rows%20with%20null%20values%20and%20then%20convert%20the%20column%20as%20bool%20type.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(descriptive_features_df)%3A%0A%20%20%20%20drop_instant_book_nulls%20%3D%20descriptive_features_df.dropna(subset%3D%5B'instant_book'%5D)%0A%20%20%20%20drop_instant_book_nulls%20%3D%20drop_instant_book_nulls.astype(%7B'instant_book'%3A%20'bool'%7D)%0A%20%20%20%20return%20(drop_instant_book_nulls%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Now%20_instant_book_%20is%20a%20boolean%20feature!!!%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(drop_instant_book_nulls)%3A%0A%20%20%20%20drop_instant_book_nulls%5B'professional_management'%5D.value_counts(dropna%3DFalse)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20_professional_management_%20issue%20is%20more%20complex.%20It%20has%201184%20null%20values%2C%20so%20I%20decided%20to%20drop%20this%20column%20to%20keep%20the%20analysis%20simple.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(drop_instant_book_nulls)%3A%0A%20%20%20%20drop_professional_management%20%3D%20drop_instant_book_nulls.drop(columns%3D'professional_management')%0A%20%20%20%20return%20(drop_professional_management%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20_Rating_%20columns%20with%20null%20values.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20For%20all%20the%20_rating_%20columns%20with%20null%20values%2C%20I%20will%20fill%20them%20with%200.%20Assuming%20it%20is%20because%20they%20have%20very%20few%20number%20of%20reviews.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(drop_professional_management)%3A%0A%20%20%20%20drop_professional_management%5B'rating_overall'%5D%20%3D%20drop_professional_management%5B'rating_overall'%5D.fillna(0)%0A%20%20%20%20drop_professional_management%5B'rating_accuracy'%5D%20%3D%20drop_professional_management%5B'rating_accuracy'%5D.fillna(0)%0A%20%20%20%20drop_professional_management%5B'rating_checkin'%5D%20%3D%20drop_professional_management%5B'rating_checkin'%5D.fillna(0)%0A%20%20%20%20drop_professional_management%5B'rating_cleanliness'%5D%20%3D%20drop_professional_management%5B'rating_cleanliness'%5D.fillna(0)%0A%20%20%20%20drop_professional_management%5B'rating_communication'%5D%20%3D%20drop_professional_management%5B'rating_communication'%5D.fillna(0)%0A%20%20%20%20drop_professional_management%5B'rating_location'%5D%20%3D%20drop_professional_management%5B'rating_location'%5D.fillna(0)%0A%20%20%20%20drop_professional_management%5B'rating_value'%5D%20%3D%20drop_professional_management%5B'rating_value'%5D.fillna(0)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20_cleaning_fee_%20and%20_extra_guest_fee_.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20And%20something%20similar%20for%20_cleaning_fee_%20and%20_extra_guest_fee_.%20Assumming%20null%20values%20as%20not%20fee.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(drop_professional_management)%3A%0A%20%20%20%20drop_professional_management%5B'cleaning_fee'%5D%20%3D%20drop_professional_management%5B'cleaning_fee'%5D.fillna(0)%0A%20%20%20%20drop_professional_management%5B'extra_guest_fee'%5D%20%3D%20drop_professional_management%5B'extra_guest_fee'%5D.fillna(0)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20_guests_%2C%20_bedrooms_%2C%20_beds_%2C%20and%20_min_nights_.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20For%20_guests_%2C%20_bedrooms_%2C%20_beds_%2C%20and%20_min_nights_%20I%20will%20fill%20null%20rows%20with%20them%20medians.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(drop_professional_management)%3A%0A%20%20%20%20drop_professional_management%5B'guests'%5D%20%3D%20drop_professional_management%5B'guests'%5D.fillna(drop_professional_management%5B'guests'%5D.median())%0A%20%20%20%20drop_professional_management%5B'bedrooms'%5D%20%3D%20drop_professional_management%5B'bedrooms'%5D.fillna(drop_professional_management%5B'bedrooms'%5D.median())%0A%20%20%20%20drop_professional_management%5B'beds'%5D%20%3D%20drop_professional_management%5B'beds'%5D.fillna(drop_professional_management%5B'beds'%5D.median())%0A%20%20%20%20drop_professional_management%5B'min_nights'%5D%20%3D%20drop_professional_management%5B'min_nights'%5D.fillna(drop_professional_management%5B'min_nights'%5D.median())%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Creating%20amenities_count%20column.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20And%20I%20want%20to%20create%20a%20new%20column%20for%20the%20number%20of%20amenities%20instead%20of%20the%20original%20string%20columns.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(drop_professional_management)%3A%0A%20%20%20%20drop_professional_management%5B'amenities_count'%5D%20%3D%20drop_professional_management%5B'amenities'%5D.str.split('%2C').str.len().astype(int)%0A%20%20%20%20df%20%3D%20drop_professional_management.drop(columns%3D%5B'amenities'%5D)%0A%20%20%20%20df.info()%0A%20%20%20%20return%20(df%2C)%0A%0A%0A%40app.cell%0Adef%20_(df)%3A%0A%20%20%20%20df%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Plots%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(hv)%3A%0A%20%20%20%20hv.extension('bokeh')%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20TTM%20Reserved%20Days%20histogram%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df%2C%20hv%2C%20np%2C%20opts)%3A%0A%20%20%20%20%23%201.%20Original%20Distribution%0A%20%20%20%20hist_original%20%3D%20hv.Histogram(%0A%20%20%20%20%20%20%20%20np.histogram(df%5B'ttm_reserved_days'%5D%2C%20bins%3D50)%2C%20%0A%20%20%20%20%20%20%20%20label%3D'Original%3A%20TTM%20Reserved%20Days'%0A%20%20%20%20).opts(xlabel%3D'Days%20Booked')%0A%0A%20%20%20%20%23%20Combine%20side-by-side%0A%20%20%20%20target_plot%20%3D%20(hist_original).opts(%0A%20%20%20%20%20%20%20%20opts.Histogram(width%3D450%2C%20height%3D350%2C%20color%3D'%231f77b4'%2C%20tools%3D%5B'hover'%5D)%0A%20%20%20%20)%0A%0A%20%20%20%20target_plot%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20From%20above%20histogram%20I%20can%20conclude%20that%20the%20_number%20of%20booked%2Freserved%20days%20in%20trailing%20twelve%20months_%20is%20a%20good%20variable%20to%20be%20predicted%20because%20is%20distributed%20in%20a%20well%20way%2C%20having%20samples%20for%20a%20lot%20of%20different%20values.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Feature%20Correlation%20Matrix%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df%2C%20hv)%3A%0A%20%20%20%20%23%20Select%20numeric%20columns%0A%20%20%20%20numeric_cols%20%3D%20%5B'photos_count'%2C%20'guests'%2C%20'bedrooms'%2C%20'beds'%2C%20'baths'%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'min_nights'%2C%20'cleaning_fee'%2C%20'extra_guest_fee'%2C%20'num_reviews'%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'rating_overall'%2C%20'rating_accuracy'%2C%20'rating_checkin'%2C%20'rating_cleanliness'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'rating_communication'%2C%20'rating_location'%2C%20'rating_value'%2C%20'amenities_count'%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'ttm_reserved_days'%5D%0A%0A%20%20%20%20%23%20Compute%20correlation%20and%20reshape%20for%20HoloViews%0A%20%20%20%20corr_matrix%20%3D%20df%5Bnumeric_cols%5D.corr()%0A%20%20%20%20corr_tidy%20%3D%20corr_matrix.stack().reset_index()%0A%20%20%20%20corr_tidy.columns%20%3D%20%5B'x'%2C%20'y'%2C%20'correlation'%5D%0A%0A%20%20%20%20%23%20Create%20HeatMap%0A%20%20%20%20heatmap%20%3D%20hv.HeatMap(corr_tidy).opts(%0A%20%20%20%20%20%20%20%20tools%3D%5B'hover'%5D%2C%0A%20%20%20%20%20%20%20%20colorbar%3DTrue%2C%0A%20%20%20%20%20%20%20%20width%3D700%2C%0A%20%20%20%20%20%20%20%20height%3D600%2C%0A%20%20%20%20%20%20%20%20toolbar%3D'above'%2C%0A%20%20%20%20%20%20%20%20cmap%3D'RdBu_r'%2C%20%20%20%20%20%20%20%20%20%20%23%20Red-Blue%20colormap%20(Red%20%3D%20positive%2C%20Blue%20%3D%20negative)%0A%20%20%20%20%20%20%20%20clim%3D(-1%2C%201)%2C%20%20%20%20%20%20%20%20%20%20%20%23%20Lock%20color%20scale%20between%20-1%20and%201%0A%20%20%20%20%20%20%20%20xrotation%3D45%2C%20%20%20%20%20%20%20%20%20%20%20%23%20Rotate%20labels%20for%20readability%0A%20%20%20%20%20%20%20%20title%3D%22Feature%20Correlation%20Matrix%22%0A%20%20%20%20)%0A%0A%20%20%20%20heatmap%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20With%20above%20plot%20I%20decided%20to%20drop%20all%20_rating_%20features%20_rating_overall_%20because%20it%20is%20calculated%20from%20the%20other%20_ratings_%20features.%0A%0A%20%20%20%20I%20also%20see%20that%20_baths_%2C%20_beds_%2C%20_bedrooms_%20and%20_guest_%20have%20a%20high%20correlation%2C%20but%20that%20is%20something%20obvious%2C%20because%20they%20are%20very%20related%20to%20the%20size%20of%20the%20house.%20In%20this%20case%20I%20decided%20to%20not%20drop%20any%20of%20them%20because%20in%20this%20case%20the%20dataset%20doesn%C2%B4t%20have%20any%20other%20feature%20that%20summarize%20all%20of%20them.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df)%3A%0A%20%20%20%20df1%20%3D%20df.drop(columns%3D%5B'rating_value'%2C%20'rating_location'%2C%20'rating_communication'%2C%20'rating_cleanliness'%2C%20'rating_checkin'%2C%20'rating_accuracy'%20%5D)%0A%20%20%20%20return%20(df1%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Box%20plots%20of%20superhost%20starus%20and%20instant%20book.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df1%2C%20hv)%3A%0A%20%20%20%20df1%5B'superhost'%5D%20%3D%20df1%5B'superhost'%5D.astype(str)%0A%20%20%20%20df1%5B'instant_book'%5D%20%3D%20df1%5B'instant_book'%5D.astype(str)%0A%20%20%20%20%23%20kdims%20%3D%20Categorical%20groupings%20(X-axis)%0A%20%20%20%20%23%20vdims%20%3D%20Continuous%20variable%20(Y-axis)%0A%20%20%20%20box_plot%20%3D%20hv.BoxWhisker(%0A%20%20%20%20%20%20%20%20df1%2C%20%0A%20%20%20%20%20%20%20%20kdims%3D%5B'superhost'%2C%20'instant_book'%5D%2C%20%0A%20%20%20%20%20%20%20%20vdims%3D%5B'ttm_reserved_days'%5D%0A%20%20%20%20).opts(%0A%20%20%20%20%20%20%20%20width%3D600%2C%0A%20%20%20%20%20%20%20%20height%3D400%2C%0A%20%20%20%20%20%20%20%20box_fill_color%3D'instant_book'%2C%20%23%20Color%20by%20the%20second%20category%0A%20%20%20%20%20%20%20%20cmap%3D'Set1'%2C%0A%20%20%20%20%20%20%20%20xlabel%3D'Superhost%20Status%20%2F%20Instant%20Book'%2C%0A%20%20%20%20%20%20%20%20ylabel%3D'Reserved%20Days'%2C%0A%20%20%20%20%20%20%20%20title%3D'Impact%20of%20Trust%20%26%20Friction%20on%20Bookings'%0A%20%20%20%20)%0A%0A%20%20%20%20box_plot%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Both%2C%20_superhost_%20and%20_instant_book_%20appear%20not%20being%20influencing%20in%20_ttm_reserved_days_%20but%20I%20am%20not%20sure%20if%20is%20good%20idea%20to%20drop%20them%2C%20I%20will%20leave%20them%20as%20part%20of%20the%20model.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(disabled%3DTrue)%0Adef%20_(df1%2C%20gridmatrix%2C%20hv)%3A%0A%20%20%20%20%23deactivating%20this%20cell%20to%20publish%20it%20to%20marimo%20service%2C%20but%20it%20render%20a%20beatiful%20plot.%0A%0A%20%20%20%20ds%3Dhv.Dataset(df1)%0A%20%20%20%20grouped_by_room_type%3D%20ds.groupby('cancellation_policy'%2C%20container_type%3Dhv.NdOverlay)%0A%20%20%20%20grid%20%3D%20gridmatrix(grouped_by_room_type%2C%20diagonal_type%3Dhv.Scatter)%0A%20%20%20%20grid.options('Scatter'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width%3D120%2C%20%20%20%23%20Smaller%20width%20per%20square%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height%3D120%2C%20%20%23%20Smaller%20height%20per%20square%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fontsize%3D%7B'labels'%3A%208%7D%2C%20%23%20Reduce%20font%20size%20if%20making%20plots%20small%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tools%3D%5B'hover'%2C%20'box_select'%5D%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bgcolor%3D'%23efe8e2'%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fill_alpha%3D0.2%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20size%3D4%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df1)%3A%0A%20%20%20%20df1%5B'superhost'%5D%20%3D%20df1%5B'superhost'%5D.astype(bool)%0A%20%20%20%20df1%5B'instant_book'%5D%20%3D%20df1%5B'instant_book'%5D.astype(bool)%0A%20%20%20%20df1%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Model%20Training%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20from%20sklearn.model_selection%20import%20train_test_split%0A%20%20%20%20from%20sklearn.preprocessing%20import%20OneHotEncoder%2C%20StandardScaler%2C%20FunctionTransformer%0A%20%20%20%20from%20sklearn.impute%20import%20SimpleImputer%0A%20%20%20%20from%20sklearn.compose%20import%20ColumnTransformer%0A%20%20%20%20from%20sklearn.pipeline%20import%20Pipeline%0A%20%20%20%20from%20sklearn.linear_model%20import%20Ridge%0A%20%20%20%20from%20sklearn.ensemble%20import%20GradientBoostingRegressor%2C%20RandomForestRegressor%0A%20%20%20%20from%20sklearn.metrics%20import%20mean_absolute_error%2C%20r2_score%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20ColumnTransformer%2C%0A%20%20%20%20%20%20%20%20FunctionTransformer%2C%0A%20%20%20%20%20%20%20%20GradientBoostingRegressor%2C%0A%20%20%20%20%20%20%20%20OneHotEncoder%2C%0A%20%20%20%20%20%20%20%20Pipeline%2C%0A%20%20%20%20%20%20%20%20RandomForestRegressor%2C%0A%20%20%20%20%20%20%20%20Ridge%2C%0A%20%20%20%20%20%20%20%20SimpleImputer%2C%0A%20%20%20%20%20%20%20%20StandardScaler%2C%0A%20%20%20%20%20%20%20%20mean_absolute_error%2C%0A%20%20%20%20%20%20%20%20r2_score%2C%0A%20%20%20%20%20%20%20%20train_test_split%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%23%20---------------------------------------------------------%0A%20%20%20%20%23%201.%20Setup%20Data%20(Matching%20Schema)%0A%20%20%20%20%23%20---------------------------------------------------------%0A%0A%20%20%20%20target_col%20%3D%20'ttm_reserved_days'%20%23%20I%20am%20trying%20to%20predict%20this%0A%0A%20%20%20%20%23%20Categorical%20features%20(Text)%0A%20%20%20%20cat_features%20%3D%20%5B'listing_type'%2C%20'room_type'%2C%20'cancellation_policy'%5D%0A%0A%20%20%20%20%23%20Boolean%20features%20(True%2FFalse)%0A%20%20%20%20bool_features%20%3D%20%5B'superhost'%2C%20'instant_book'%5D%0A%0A%20%20%20%20%23%20Numerical%20features%20(Everything%20else)%0A%20%20%20%20num_features%20%3D%20%5B%0A%20%20%20%20%20%20%20%20'photos_count'%2C%20'guests'%2C%20'bedrooms'%2C%20'beds'%2C%20'baths'%2C%20%0A%20%20%20%20%20%20%20%20'min_nights'%2C%20'cleaning_fee'%2C%20'extra_guest_fee'%2C%20'num_reviews'%2C%20%0A%20%20%20%20%20%20%20%20'rating_overall'%2C%20'amenities_count'%0A%20%20%20%20%5D%0A%20%20%20%20return%20bool_features%2C%20cat_features%2C%20num_features%2C%20target_col%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20ColumnTransformer%2C%0A%20%20%20%20FunctionTransformer%2C%0A%20%20%20%20OneHotEncoder%2C%0A%20%20%20%20Pipeline%2C%0A%20%20%20%20SimpleImputer%2C%0A%20%20%20%20StandardScaler%2C%0A%20%20%20%20bool_features%2C%0A%20%20%20%20cat_features%2C%0A%20%20%20%20num_features%2C%0A)%3A%0A%20%20%20%20%23%20---------------------------------------------------------%0A%20%20%20%20%23%202.%20Preprocessing%20Pipelines%0A%20%20%20%20%23%20---------------------------------------------------------%0A%0A%20%20%20%20%23%20Pipeline%20for%20Numerical%20Data%3A%0A%20%20%20%20%23%201.%20Fill%20missing%20values%20with%20the%20Median%20(handles%20the%20missing%20'num_reviews')%0A%20%20%20%20%23%202.%20Scale%20data%20(StandardScaler)%20helps%20models%20converge%20faster%0A%20%20%20%20numeric_transformer%20%3D%20Pipeline(steps%3D%5B%0A%20%20%20%20%20%20%20%20('imputer'%2C%20SimpleImputer(strategy%3D'median'))%2C%0A%20%20%20%20%20%20%20%20('scaler'%2C%20StandardScaler())%0A%20%20%20%20%5D)%0A%0A%20%20%20%20%23%20Pipeline%20for%20Categorical%20Data%3A%0A%20%20%20%20%23%201.%20OneHotEncode%20converts%20%22Apartment%22%20-%3E%20%5B0%2C%201%2C%200%5D%0A%20%20%20%20%23%20handle_unknown%3D'ignore'%20prevents%20crashes%20if%20new%20categories%20appear%20in%20the%20future%0A%20%20%20%20categorical_transformer%20%3D%20Pipeline(steps%3D%5B%0A%20%20%20%20%20%20%20%20('imputer'%2C%20SimpleImputer(strategy%3D'most_frequent'))%2C%0A%20%20%20%20%20%20%20%20('encoder'%2C%20OneHotEncoder(handle_unknown%3D'ignore'))%0A%20%20%20%20%5D)%0A%0A%20%20%20%20%23%20Pipeline%20for%20Boolean%20Data%3A%20Cast%20to%20Float%20-%3E%20Fill%20missing%0A%20%20%20%20%23%20This%20converts%20True-%3E1.0%20and%20False-%3E0.0%0A%20%20%20%20boolean_transformer%20%3D%20Pipeline(steps%3D%5B%0A%20%20%20%20%20%20%20%20('cast_to_float'%2C%20FunctionTransformer(lambda%20x%3A%20x.astype(float)%2C%20validate%3DFalse))%2C%0A%20%20%20%20%20%20%20%20('imputer'%2C%20SimpleImputer(strategy%3D'most_frequent'))%0A%20%20%20%20%5D)%0A%0A%20%20%20%20%23%20Combine%20them%20into%20a%20ColumnTransformer%0A%20%20%20%20preprocessor%20%3D%20ColumnTransformer(%0A%20%20%20%20%20%20%20%20transformers%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20('num'%2C%20numeric_transformer%2C%20num_features)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20('cat'%2C%20categorical_transformer%2C%20cat_features)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20('bool'%2C%20boolean_transformer%2C%20bool_features)%20%23%20%3C---%20Use%20the%20new%20transformer%20here%0A%20%20%20%20%20%20%20%20%5D)%0A%20%20%20%20return%20(preprocessor%2C)%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20GradientBoostingRegressor%2C%0A%20%20%20%20Pipeline%2C%0A%20%20%20%20RandomForestRegressor%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20df1%2C%0A%20%20%20%20mean_absolute_error%2C%0A%20%20%20%20preprocessor%2C%0A%20%20%20%20r2_score%2C%0A%20%20%20%20target_col%2C%0A%20%20%20%20train_test_split%2C%0A)%3A%0A%20%20%20%20%23%20---------------------------------------------------------%0A%20%20%20%20%23%203.%20Define%20the%20Model%0A%20%20%20%20%23%20---------------------------------------------------------%0A%0A%20%20%20%20models%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22Ridge%20Regression%20(Linear)%20-%20Alpha%20%3D%201.0%22%3A%20Ridge(alpha%3D1.0)%2C%0A%20%20%20%20%20%20%20%20%22Ridge%20Regression%20(Linear)%20-%20Alpha%20%3D%205.0%22%3A%20Ridge(alpha%3D5.0)%2C%0A%20%20%20%20%20%20%20%20%22Ridge%20Regression%20(Linear)%20-%20Alpha%20%3D%2010.0%22%3A%20Ridge(alpha%3D10.0)%2C%0A%20%20%20%20%20%20%20%20%22Random%20Forest%20-%20n_estimators%20%3D%20100%22%3A%20RandomForestRegressor(n_estimators%3D100%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Random%20Forest%20-%20n_estimators%20%3D%20500%22%3A%20RandomForestRegressor(n_estimators%3D500%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Random%20Forest%20-%20n_estimators%20%3D%201000%22%3A%20RandomForestRegressor(n_estimators%3D1000%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Gradient%20Boosting%20-%20n_estimators%20%3D%20100%2C%20learning_rate%20%3D%200.1%22%3A%20GradientBoostingRegressor(n_estimators%3D100%2C%20learning_rate%3D0.1%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Gradient%20Boosting%20-%20n_estimators%20%3D%20500%2C%20learning_rate%20%3D%200.1%22%3A%20GradientBoostingRegressor(n_estimators%3D500%2C%20learning_rate%3D0.1%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Gradient%20Boosting%20-%20n_estimators%20%3D%201000%2C%20learning_rate%20%3D%200.1%22%3A%20GradientBoostingRegressor(n_estimators%3D1000%2C%20learning_rate%3D0.1%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Gradient%20Boosting%20-%20n_estimators%20%3D%20100%2C%20learning_rate%20%3D%200.5%22%3A%20GradientBoostingRegressor(n_estimators%3D100%2C%20learning_rate%3D0.5%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Gradient%20Boosting%20-%20n_estimators%20%3D%20500%2C%20learning_rate%20%3D%200.5%22%3A%20GradientBoostingRegressor(n_estimators%3D500%2C%20learning_rate%3D0.5%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Gradient%20Boosting%20-%20n_estimators%20%3D%201000%2C%20learning_rate%20%3D%200.5%22%3A%20GradientBoostingRegressor(n_estimators%3D1000%2C%20learning_rate%3D0.5%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Gradient%20Boosting%20-%20n_estimators%20%3D%20100%2C%20learning_rate%20%3D%201.0%22%3A%20GradientBoostingRegressor(n_estimators%3D100%2C%20learning_rate%3D1.0%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Gradient%20Boosting%20-%20n_estimators%20%3D%20500%2C%20learning_rate%20%3D%201.0%22%3A%20GradientBoostingRegressor(n_estimators%3D500%2C%20learning_rate%3D1.0%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20%22Gradient%20Boosting%20-%20n_estimators%20%3D%201000%2C%20learning_rate%20%3D%201.0%22%3A%20GradientBoostingRegressor(n_estimators%3D1000%2C%20learning_rate%3D1.0%2C%20random_state%3D42)%2C%0A%20%20%20%20%7D%0A%0A%20%20%20%20print(f%22%7B'Model%20Name'%3A%3C30%7D%20%7C%20%7B'MAE'%3A%3C10%7D%20%7C%20%7B'R2%20Score'%3A%3C10%7D%22)%0A%20%20%20%20print(%22-%22%20*%2055)%0A%0A%20%20%20%20X%20%3D%20df1.drop(columns%3D%5Btarget_col%5D)%0A%20%20%20%20y%20%3D%20df1%5Btarget_col%5D%0A%0A%20%20%20%20%23%20Split%20data%0A%20%20%20%20X_train%2C%20X_test%2C%20y_train%2C%20y_test%20%3D%20train_test_split(X%2C%20y%2C%20test_size%3D0.2%2C%20random_state%3D42)%0A%0A%20%20%20%20for%20name%2C%20model_instance%20in%20models.items()%3A%0A%20%20%20%20%20%20%20%20%23%20Create%20a%20new%20pipeline%20with%20the%20specific%20model%0A%20%20%20%20%20%20%20%20%23%20(Assuming%20'preprocessor'%20is%20defined%20from%20the%20previous%20steps)%0A%20%20%20%20%20%20%20%20clf%20%3D%20Pipeline(steps%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20('preprocessor'%2C%20preprocessor)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20('regressor'%2C%20model_instance)%0A%20%20%20%20%20%20%20%20%5D)%0A%0A%20%20%20%20%20%20%20%20%23%20Train%0A%20%20%20%20%20%20%20%20clf.fit(X_train%2C%20y_train)%0A%0A%20%20%20%20%20%20%20%20%23%20Predict%0A%20%20%20%20%20%20%20%20y_pred%20%3D%20clf.predict(X_test)%0A%0A%20%20%20%20%20%20%20%20%23%20Evaluate%0A%20%20%20%20%20%20%20%20mae%20%3D%20mean_absolute_error(y_test%2C%20y_pred)%0A%20%20%20%20%20%20%20%20r2%20%3D%20r2_score(y_test%2C%20y_pred)%0A%0A%20%20%20%20%20%20%20%20print(f%22%7Bname%3A%3C30%7D%20%7C%20%7Bmae%3A%3C10.2f%7D%20%7C%20%7Br2%3A%3C10.4f%7D%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20**The%20best%20model%20is%20Gradient%20Boosting%20-%20n_estimators%20%3D%20100%2C%20learning_rate%20%3D%200.1%20because%20it%20has%20the%20lowest%20MAE%20(45.46)%20and%20the%20highest%20R2%20Score%20(0.3133)**%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
c99d6e186ad678f89e7b5f4c7d97e6b0