import%20marimo%0A%0A__generated_with%20%3D%20%220.16.0%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%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%20numpy%20as%20np%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20seaborn%20as%20sns%0A%20%20%20%20return%20mo%2C%20pd%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%20Machine%20Learning%20Zoomcamp%0A%0A%20%20%20%20%23%23%20Module%205%3A%20**Deployment**%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(pd)%3A%0A%20%20%20%20repository_root%20%3D%20(%0A%20%20%20%20%20%20%20%20%22https%3A%2F%2Fgithub.com%2FDataTalksClub%2Fmachine-learning-zoomcamp%2Fblob%2Fmaster%2F%22%0A%20%20%20%20)%0A%0A%20%20%20%20chapters%20%3D%20pd.DataFrame(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Session%20Overview%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22youtube_id%22%3A%20%22agIFak9A3m8%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22contents%22%3A%20repository_root%20%2B%20%2205-deployment%2F01-intro.md%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Saving%20and%20Loading%20the%20Model%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22youtube_id%22%3A%20%22EJpqZ7OlwFU%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22contents%22%3A%20repository_root%20%2B%20%2205-deployment%2F02-pickle.md%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Web%20Services%3A%20Introduction%20to%20Flask%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22youtube_id%22%3A%20%22W7ubna1Rfv8%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22contents%22%3A%20repository_root%20%2B%20%2205-deployment%2F03-flask-intro.md%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Serving%20the%20Churn%20Model%20with%20Flask%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22youtube_id%22%3A%20%22Q7ZWPgPnRz8%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22contents%22%3A%20repository_root%20%2B%20%2205-deployment%2F04-flask-deployment.md%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Python%20Virtual%20Environment%3A%20Pipenv%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22youtube_id%22%3A%20%22BMXh8JGROHM%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22contents%22%3A%20repository_root%20%2B%20%2205-deployment%2F05-pipenv.md%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Environment%20Management%3A%20Docker%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22youtube_id%22%3A%20%22wAtyYZ6zvAs%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22contents%22%3A%20repository_root%20%2B%20%2205-deployment%2F06-docker.md%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Deployment%20to%20the%20Cloud%3A%20AWS%20Elastic%20Beanstalk%20(optional)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22youtube_id%22%3A%20%22HGPJ4ekhcLg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22contents%22%3A%20repository_root%20%2B%20%2205-deployment%2F07-aws-eb.md%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Summary%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22youtube_id%22%3A%20%22sSAqYSk7Br4%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22contents%22%3A%20repository_root%20%2B%20%2205-deployment%2F08-summary.md%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Explore%20More%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22contents%22%3A%20repository_root%20%2B%20%2205-deployment%2F09-explore-more.md%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%0A%20%20%20%20chapters.insert(%0A%20%20%20%20%20%20%20%20loc%3D0%2C%0A%20%20%20%20%20%20%20%20column%3D%22snapshot%22%2C%0A%20%20%20%20%20%20%20%20value%3D%22https%3A%2F%2Fimg.youtube.com%2Fvi%2F%22%0A%20%20%20%20%20%20%20%20%2B%20chapters.youtube_id.astype(str)%0A%20%20%20%20%20%20%20%20%2B%20%22%2Fhqdefault.jpg%22%2C%0A%20%20%20%20)%0A%20%20%20%20chapters.insert(%0A%20%20%20%20%20%20%20%20loc%3D2%2C%0A%20%20%20%20%20%20%20%20column%3D%22youtube%22%2C%0A%20%20%20%20%20%20%20%20value%3D%22https%3A%2F%2Fyoutube.com%2Fwatch%3Fv%3D%22%20%2B%20chapters.youtube_id.astype(str)%2C%0A%20%20%20%20)%0A%0A%20%20%20%20videos%20%3D%20chapters%5Bchapters%5B%22youtube_id%22%5D.notnull()%5D%0A%20%20%20%20videos%5B%5B%22snapshot%22%2C%20%22title%22%2C%20%22youtube%22%5D%5D%0A%20%20%20%20return%20(chapters%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(chapters)%3A%0A%20%20%20%20contents%20%3D%20chapters%5Bchapters%5B%22contents%22%5D.notnull()%5D%0A%20%20%20%20contents%5B%5B%22title%22%2C%20%22contents%22%5D%5D%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%23%20Previous%20Sessions%20Refresh%0A%0A%20%20%20%20In%20the%20previous%20modules%20we%20created%20a%20model%20that%20predicted%20if%20a%20customer%20was%20about%20to%20churn%20or%20not.%20This%20time%20we'll%20learn%20how%20to%20save%20the%20module%20and%20serve%20it%20in%20a%20production%20environment.%20But%20first%20we%20have%20to%20reproduce%20the%20steps%20to%20build%20the%20model.%0A%0A%20%20%20%20%23%23%23%23%20Read%20and%20Standardize%20the%20Dataset%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(pd)%3A%0A%20%20%20%20def%20standardize_column_names(dataframe%3A%20pd.DataFrame)%20-%3E%20pd.DataFrame%3A%0A%20%20%20%20%20%20%20%20standardized%20%3D%20dataframe.copy()%0A%20%20%20%20%20%20%20%20standardized.columns%20%3D%20standardized.columns.str.lower().str.replace('%20'%2C%20'_')%0A%0A%20%20%20%20%20%20%20%20return%20standardized%0A%0A%20%20%20%20def%20get_cateogorical_columns(dataframe%3A%20pd.DataFrame)%20-%3E%20list%5Bstr%5D%3A%0A%20%20%20%20%20%20%20%20return%20list(list(dataframe.dtypes%5Bdataframe.dtypes%20%3D%3D%20'object'%5D.index))%0A%0A%20%20%20%20def%20standardize_categorical_values(dataframe%3A%20pd.DataFrame)%20-%3E%20pd.DataFrame%3A%0A%20%20%20%20%20%20%20%20standardized%20%3D%20dataframe.copy()%0A%0A%20%20%20%20%20%20%20%20for%20column%20in%20get_cateogorical_columns(standardized)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20standardized%5Bcolumn%5D%20%3D%20standardized%5Bcolumn%5D.str.lower().str.replace('%20'%2C%20'_')%0A%0A%20%20%20%20%20%20%20%20return%20standardized%0A%0A%20%20%20%20def%20standardize_non_categorical_values(dataframe%3A%20pd.DataFrame)%20-%3E%20pd.DataFrame%3A%0A%20%20%20%20%20%20%20%20totalcharges%20%3D%20pd.to_numeric(df_standardized.totalcharges%2C%20errors%3D'coerce')%0A%20%20%20%20%20%20%20%20df_standardized.totalcharges%20%3D%20totalcharges.fillna(0)%0A%0A%20%20%20%20%20%20%20%20return%20df_standardized%0A%0A%20%20%20%20df_raw%20%3D%20pd.read_csv(%22module-3%2Fdata%2Fcustomer-churn.csv%22)%0A%20%20%20%20df_standardized%20%3D%20standardize_column_names(df_raw)%0A%20%20%20%20df_standardized%20%3D%20standardize_categorical_values(df_standardized)%0A%20%20%20%20df_standardized%20%3D%20standardize_non_categorical_values(df_standardized)%0A%0A%20%20%20%20df_standardized.head()%0A%20%20%20%20return%20(df_standardized%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%23%23%23%23%20Setup%20the%20Validation%20Framework%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(df_standardized%2C%20pd)%3A%0A%20%20%20%20from%20sklearn.model_selection%20import%20train_test_split%0A%0A%20%20%20%20def%20split_dataframe(dataframe%3A%20pd.DataFrame)%20-%3E%20pd.DataFrame%3A%0A%20%20%20%20%20%20%20%20full_train%2C%20test%20%3D%20train_test_split(dataframe%2C%20test_size%3D0.2%2C%20random_state%3D1)%0A%20%20%20%20%20%20%20%20train%2C%20val%20%3D%20train_test_split(full_train%2C%20test_size%3D0.25%2C%20random_state%3D1)%0A%0A%20%20%20%20%20%20%20%20return%20train%2C%20val%2C%20test%2C%20full_train%0A%0A%20%20%20%20df_train%2C%20df_val%2C%20df_test%2C%20df_full%20%3D%20split_dataframe(df_standardized)%0A%0A%20%20%20%20df_train%20%3D%20df_train.reset_index(drop%3DTrue)%0A%20%20%20%20df_val%20%3D%20df_val.reset_index(drop%3DTrue)%0A%20%20%20%20df_test%20%3D%20df_test.reset_index(drop%3DTrue)%0A%20%20%20%20df_full%20%3D%20df_full.reset_index(drop%3DTrue)%0A%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22df_train%22%3A%20len(df_train)%2C%0A%20%20%20%20%20%20%20%20%22df_val%22%3A%20len(df_val)%2C%0A%20%20%20%20%20%20%20%20%22df_test%22%3A%20len(df_test)%2C%0A%20%20%20%20%20%20%20%20%22df_full%22%3A%20len(df_full)%2C%0A%20%20%20%20%7D%0A%20%20%20%20return%20df_full%2C%20df_val%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%23%23%23%23%20Prepare%20the%20Features%20and%20Target%20Tensors%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(df_full%2C%20df_val%2C%20pd)%3A%0A%20%20%20%20from%20sklearn.feature_extraction%20import%20DictVectorizer%0A%0A%20%20%20%20numerical_columns%20%3D%20%5B%22tenure%22%2C%20%22monthlycharges%22%2C%20%22totalcharges%22%5D%0A%0A%20%20%20%20categorical_columns%20%3D%20%5B%0A%20%20%20%20%20%20%20%20'gender'%2C%20'seniorcitizen'%2C%20'partner'%2C%20'dependents'%2C%0A%20%20%20%20%20%20%20%20'phoneservice'%2C%20'multiplelines'%2C%20'internetservice'%2C%20'onlinesecurity'%2C%0A%20%20%20%20%20%20%20%20'onlinebackup'%2C%20'deviceprotection'%2C%20'techsupport'%2C%20'streamingtv'%2C%0A%20%20%20%20%20%20%20%20'streamingmovies'%2C%20'contract'%2C%20'paperlessbilling'%2C%20'paymentmethod'%0A%20%20%20%20%5D%0A%0A%20%20%20%20def%20get_full_trained_vectorizer(dataframe%3A%20pd.DataFrame)%20-%3E%20list%5Bdict%5D%3A%0A%20%20%20%20%20%20%20%20copy%20%3D%20dataframe.copy()%0A%20%20%20%20%20%20%20%20del%20copy%5B%22churn%22%5D%0A%20%20%20%20%20%20%20%20dictionary%20%3D%20copy.to_dict(orient%3D%22records%22)%0A%0A%20%20%20%20%20%20%20%20dict_vectorizer%20%3D%20DictVectorizer(sparse%3DFalse)%0A%20%20%20%20%20%20%20%20dict_vectorizer.fit(dictionary)%0A%0A%20%20%20%20%20%20%20%20return%20dict_vectorizer%2C%20dictionary%0A%0A%20%20%20%20def%20get_features_and_target(dataframe%3A%20pd.DataFrame%2C%20dict_vectorizer%3A%20DictVectorizer%2C%20dictionary)%3A%0A%20%20%20%20%20%20%20%20X%20%3D%20dict_vectorizer.transform(dictionary)%0A%20%20%20%20%20%20%20%20y%20%3D%20dataframe.churn%20%3D%3D%20%22yes%22%0A%0A%20%20%20%20%20%20%20%20return%20X%2C%20y%0A%0A%20%20%20%20dict_vectorizer_full%2C%20dictionary_full%20%3D%20get_full_trained_vectorizer(df_full)%0A%20%20%20%20X_full%2C%20y_full%20%3D%20get_features_and_target(df_full%2C%20dict_vectorizer_full%2C%20dictionary_full)%0A%0A%20%20%20%20dictionary_val%20%3D%20df_val%5Bnumerical_columns%20%2B%20categorical_columns%5D.to_dict(orient%3D%22records%22)%0A%20%20%20%20X_val%2C%20y_val%20%3D%20get_features_and_target(df_val%2C%20dict_vectorizer_full%2C%20dictionary_val)%0A%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22X_full%22%3A%20len(X_full)%2C%0A%20%20%20%20%20%20%20%20%22y_full%22%3A%20len(y_full)%2C%0A%20%20%20%20%20%20%20%20%22X_val%22%3A%20len(X_val)%2C%0A%20%20%20%20%20%20%20%20%22y_val%22%3A%20len(y_val)%2C%0A%20%20%20%20%7D%0A%20%20%20%20return%20X_full%2C%20X_val%2C%20dict_vectorizer_full%2C%20y_full%2C%20y_val%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%23%23%20Saving%20and%20Loading%20the%20Model%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(X_full%2C%20X_val%2C%20dict_vectorizer_full%2C%20y_full%2C%20y_val)%3A%0A%20%20%20%20import%20pickle%0A%20%20%20%20import%20os%0A%20%20%20%20from%20sklearn.linear_model%20import%20LogisticRegression%0A%0A%20%20%20%20model_file%20%3D%20%22module-5%2Fdata%2Fmodel-weights.bin%22%0A%0A%20%20%20%20def%20load_model()%3A%0A%20%20%20%20%20%20%20%20with%20open(model_file%2C%20%22rb%22)%20as%20f_in%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20(model_loaded%2C%20dict_vectorizer_full_loaded)%20%3D%20pickle.load(f_in)%0A%20%20%20%20%20%20%20%20return%20model_loaded%2C%20dict_vectorizer_full_loaded%0A%0A%20%20%20%20def%20train_and_save_model()%3A%0A%20%20%20%20%20%20%20%20model%20%3D%20LogisticRegression(max_iter%3D5000)%0A%20%20%20%20%20%20%20%20model.fit(X_full%2C%20y_full)%0A%20%20%20%20%20%20%20%20with%20open(model_file%2C%20%22wb%22)%20as%20f_out%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20pickle.dump((model%2C%20dict_vectorizer_full)%2C%20f_out)%0A%0A%20%20%20%20%20%20%20%20return%20model%2C%20dict_vectorizer_full%0A%0A%20%20%20%20if%20not%20os.path.isfile(%22module-5%2Fdata%2Fmodel-weights.bin%22)%3A%0A%20%20%20%20%20%20%20%20train_and_save_model()%0A%0A%20%20%20%20model_loaded%2C%20dict_vectorizer_full_loaded%20%3D%20load_model()%0A%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20model_loaded.score(X_val%2C%20y_val)%0A%20%20%20%20%7D%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20To%20facilitate%20the%20deployment%2C%20a%20the%20code%20necessary%20to%20train%2C%20save%20and%20load%20the%20model%20has%20been%20extracted%20to%20these%20files%3A%0A%0A%20%20%20%20*%20%5Bmodel.py%5D(https%3A%2F%2Fgithub.com%2Felcapo%2Fml-zoomcamp-notes-and-homework%2Fblob%2Fmain%2Fmodule-5%2Fmodel_package%2Fmodel.py)%0A%20%20%20%20*%20%5Btrain.py%5D(https%3A%2F%2Fgithub.com%2Felcapo%2Fml-zoomcamp-notes-and-homework%2Fblob%2Fmain%2Fmodule-5%2Fmodel_package%2Ftrain.py)%0A%20%20%20%20*%20%5Bpredict.py%5D(https%3A%2F%2Fgithub.com%2Felcapo%2Fml-zoomcamp-notes-and-homework%2Fblob%2Fmain%2Fmodule-5%2Fmodel_package%2Fpredict.py)%0A%0A%20%20%20%20Before%20running%20any%20of%20these%20programs%2C%20first%20make%20sure%20that%20you%20have%20loaded%20the%20virtual%20environment%20for%20the%20course%3A%0A%0A%20%20%20%20%60%60%60bash%0A%20%20%20%20source%20.venv%2Fbin%2Factivate%0A%20%20%20%20cd%20module-5%2F%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20%23%23%23%20Train%0A%0A%20%20%20%20To%20run%20the%20training%3A%0A%0A%20%20%20%20%60%60%60bash%0A%20%20%20%20python%20-m%20model_package.train%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20%23%23%23%20Predict%0A%0A%20%20%20%20To%20run%20a%20prediction%3A%0A%0A%20%20%20%20%60%60%60bash%0A%20%20%20%20python%20-m%20model_package.predict%0A%20%20%20%20%60%60%60%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%23%20Web%20Services%3A%20Introduction%20to%20Flask%0A%0A%20%20%20%20The%20REST%20API%20server%20has%20been%20implemented%20in%20%5Bapi.py%5D(https%3A%2F%2Fgithub.com%2Felcapo%2Fml-zoomcamp-notes-and-homework%2Fblob%2Fmain%2Fmodule-5%2Fmodel_package%2Fapi.py)%20a%20single%20method%20that%20responds%20**PONG**%20when%20the%20%60%2Fping%60%20method%20is%20accessed%20via%20GET.%0A%0A%20%20%20%20To%20run%20it%3A%0A%0A%20%20%20%20%60%60%60bash%0A%20%20%20%20python%20-m%20model_package.api%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20When%20you%20run%20it%2C%20you'll%20see%20a%20message%20telling%20you%20where%20the%20service%20is%20listening.%20Something%20like%3A%0A%0A%20%20%20%20%3E%20Running%20on%20http%3A%2F%2F127.0.0.1%3A5000%0A%0A%20%20%20%20You%20can%20use%20that%20address%20to%20test%20the%20service%3A%0A%0A%20%20%20%20%60%60%60bash%0A%20%20%20%20curl%20http%3A%2F%2F127.0.0.1%3A5000%2Fping%0A%20%20%20%20%60%60%60%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%23%20Serving%20the%20Churn%20Model%20with%20Flask%0A%0A%20%20%20%20In%20this%20chapter%20we%20added%20a%20%60%2Fpredict%60%20method%20to%20our%20API%20that%20responds%20to%20POST%20requests%20with%20JSONs%20similar%20to%20the%20dictionaries%20that%20we%20were%20obtaining%20from%20the%20dataset%3A%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(df_val)%3A%0A%20%20%20%20import%20json%0A%0A%20%20%20%20print(json.dumps(df_val%5B1%3A2%5D.to_dict(orient%3D'records')%5B0%5D%2C%20indent%3D4))%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20...%20and%20returns%20the%20corresponding%20prediction%3A%0A%0A%20%20%20%20%60%60%60json%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%22customer%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22churn%22%3A%20%22no%22%2C%0A%20%20%20%20%20%20%20%20%22contract%22%3A%20%22month-to-month%22%2C%0A%20%20%20%20%20%20%20%20%22customerid%22%3A%20%223645-deygf%22%2C%0A%20%20%20%20%20%20%20%20%22dependents%22%3A%20%22yes%22%2C%0A%20%20%20%20%20%20%20%20%22deviceprotection%22%3A%20%22no_internet_service%22%2C%0A%20%20%20%20%20%20%20%20%22gender%22%3A%20%22male%22%2C%0A%20%20%20%20%20%20%20%20%22internetservice%22%3A%20%22no%22%2C%0A%20%20%20%20%20%20%20%20%22monthlycharges%22%3A%2020.75%2C%0A%20%20%20%20%20%20%20%20%22multiplelines%22%3A%20%22no%22%2C%0A%20%20%20%20%20%20%20%20%22onlinebackup%22%3A%20%22no_internet_service%22%2C%0A%20%20%20%20%20%20%20%20%22onlinesecurity%22%3A%20%22no_internet_service%22%2C%0A%20%20%20%20%20%20%20%20%22paperlessbilling%22%3A%20%22no%22%2C%0A%20%20%20%20%20%20%20%20%22partner%22%3A%20%22no%22%2C%0A%20%20%20%20%20%20%20%20%22paymentmethod%22%3A%20%22mailed_check%22%2C%0A%20%20%20%20%20%20%20%20%22phoneservice%22%3A%20%22yes%22%2C%0A%20%20%20%20%20%20%20%20%22seniorcitizen%22%3A%200%2C%0A%20%20%20%20%20%20%20%20%22streamingmovies%22%3A%20%22no_internet_service%22%2C%0A%20%20%20%20%20%20%20%20%22streamingtv%22%3A%20%22no_internet_service%22%2C%0A%20%20%20%20%20%20%20%20%22techsupport%22%3A%20%22no_internet_service%22%2C%0A%20%20%20%20%20%20%20%20%22tenure%22%3A%201%2C%0A%20%20%20%20%20%20%20%20%22totalcharges%22%3A%2020.75%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%22predicted_churn%22%3A%20false%0A%20%20%20%20%7D%0A%20%20%20%20%60%60%60%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%23%20Python%20Virtual%20Environment%0A%0A%20%20%20%20For%20this%20project's%20dependencies%20we%20used%20a%20**requirements.txt**%20with%20the%20dependencies%20listed%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20pandas%3D%3D2.3.2%0A%20%20%20%20scikit-learn%3D%3D1.7.2%0A%20%20%20%20flask%3D%3D3.1.2%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20We%20also%20added%20a%20README%20with%20some%20installation%20instructions.%0A%0A%20%20%20%20%23%23%23%20Create%20and%20Activate%20a%20Virtual%20Environment%0A%0A%20%20%20%20%60%60%60bash%0A%20%20%20%20python%20-m%20venv%20.venv%0A%20%20%20%20source%20.venv%2Fbin%2Factivate%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20%23%23%23%20Install%20Dependencies%0A%0A%20%20%20%20%60%60%60bash%0A%20%20%20%20pip%20install%20-r%20requirements.txt%0A%20%20%20%20%60%60%60%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%23%20Environment%20Management%3A%20Docker%0A%0A%20%20%20%20The%20next%20step%20to%20isolate%20our%20services%20is%20Docker.%20With%20Docker%20we%20can%20automate%20the%20deployment%20of%20our%20programs%20including%20their%20dependencies%20in%20isolated%20environments.%20What%20gives%20us%20the%20warrant%20that%20our%20environments%20would%20be%20similar%20in%20development%20and%20production.%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%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
8207d517d4ccce4b47f1759f6fa7f75f952a049ae8d42744f4cf9e51ab3a8f99