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%2C%20plt%2C%20sns%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%20Module%206%3A%20%5BDecision%20Trees%5D(https%3A%2F%2Fgithub.com%2FDataTalksClub%2Fmachine-learning-zoomcamp%2Ftree%2Fmaster%2F06-trees)%0A%0A%20%20%20%20%3E%20Note%3A%20sometimes%20your%20answer%20doesn't%20match%20one%20of%20%0A%20%20%20%20%3E%20the%20options%20exactly.%20That's%20fine.%20%0A%20%20%20%20%3E%20Select%20the%20option%20that's%20closest%20to%20your%20solution.%0A%20%20%20%20%3E%20If%20it's%20exactly%20in%20between%20two%20options%2C%20select%20the%20higher%20value.%0A%0A%0A%20%20%20%20%23%23%20Dataset%0A%0A%20%20%20%20In%20this%20homework%2C%20we%20continue%20using%20the%20fuel%20efficiency%20dataset.%0A%20%20%20%20Download%20it%20from%20%3Ca%20href%3D'https%3A%2F%2Fraw.githubusercontent.com%2Falexeygrigorev%2Fdatasets%2Fmaster%2Fcar_fuel_efficiency.csv'%3Ehere%3C%2Fa%3E.%0A%0A%20%20%20%20You%20can%20do%20it%20with%20wget%3A%0A%0A%20%20%20%20%60%60%60bash%0A%20%20%20%20wget%20https%3A%2F%2Fraw.githubusercontent.com%2Falexeygrigorev%2Fdatasets%2Fmaster%2Fcar_fuel_efficiency.csv%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20The%20goal%20of%20this%20homework%20is%20to%20create%20a%20regression%20model%20for%20predicting%20the%20car%20fuel%20efficiency%20(column%20%60'fuel_efficiency_mpg'%60).%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pd)%3A%0A%20%20%20%20def%20get_dataframe()%3A%0A%20%20%20%20%20%20%20%20return%20pd.read_csv(%22.%2Fmodule-2%2Fdata%2Fcar_fuel_efficiency.csv%22)%0A%0A%20%20%20%20df_raw%20%3D%20get_dataframe()%0A%20%20%20%20df_raw.head()%0A%20%20%20%20return%20df_raw%2C%20get_dataframe%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%23%20Preparing%20the%20dataset%20%0A%0A%20%20%20%20Preparation%3A%0A%0A%20%20%20%20*%20Fill%20missing%20values%20with%20zeros.%0A%20%20%20%20*%20Do%20train%2Fvalidation%2Ftest%20split%20with%2060%25%2F20%25%2F20%25%20distribution.%20%0A%20%20%20%20*%20Use%20the%20%60train_test_split%60%20function%20and%20set%20the%20%60random_state%60%20parameter%20to%201.%0A%20%20%20%20*%20Use%20%60DictVectorizer(sparse%3DTrue)%60%20to%20turn%20the%20dataframes%20into%20matrices.%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(r%22%22%22%23%23%23%23%20Fill%20missing%20values%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_raw%2C%20get_dataframe%2C%20pd)%3A%0A%20%20%20%20def%20fill_dataframe(df%3A%20pd.DataFrame)%20-%3E%20pd.DataFrame%3A%0A%20%20%20%20%20%20%20%20df%20%3D%20get_dataframe()%0A%0A%20%20%20%20%20%20%20%20copy%20%3D%20df.copy()%0A%20%20%20%20%20%20%20%20copy%20%3D%20copy.fillna(0)%0A%0A%20%20%20%20%20%20%20%20return%20copy%0A%0A%20%20%20%20df_filled%20%3D%20fill_dataframe(df_raw)%0A%20%20%20%20df_filled.head()%0A%20%20%20%20return%20(df_filled%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%20Create%20Data%20Splits%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_filled%2C%20pd)%3A%0A%20%20%20%20from%20sklearn.model_selection%20import%20train_test_split%0A%0A%20%20%20%20def%20get_splits(df%3A%20pd.DataFrame)%20-%3E%20(pd.DataFrame%2C%20pd.DataFrame%2C%20pd.DataFrame)%3A%0A%20%20%20%20%20%20%20%20df_full%2C%20df_test%20%3D%20train_test_split(df%2C%20test_size%3D0.2%2C%20random_state%3D1)%0A%20%20%20%20%20%20%20%20df_train%2C%20df_val%20%3D%20train_test_split(df_full%2C%20test_size%3D0.25%2C%20random_state%3D1)%0A%0A%20%20%20%20%20%20%20%20return%20df_train%2C%20df_val%2C%20df_test%0A%0A%20%20%20%20df_train%2C%20df_val%2C%20df_test%20%3D%20get_splits(df_filled)%0A%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22len(df_train)%22%3A%20len(df_train)%2C%0A%20%20%20%20%20%20%20%20%22len(df_val)%22%3A%20len(df_val)%2C%0A%20%20%20%20%20%20%20%20%22len(df_test)%22%3A%20len(df_test)%0A%20%20%20%20%7D%0A%20%20%20%20return%20df_train%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%20Train%20a%20Dictionary%20Vectorizer%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_train%2C%20pd)%3A%0A%20%20%20%20from%20sklearn.feature_extraction%20import%20DictVectorizer%0A%0A%20%20%20%20def%20separate_target(df%3A%20pd.DataFrame)%20-%3E%20(pd.DataFrame%2C%20pd.DataFrame)%3A%0A%20%20%20%20%20%20%20%20target%20%3D%20df.copy().fuel_efficiency_mpg%0A%20%20%20%20%20%20%20%20features%20%3D%20df.copy()%0A%20%20%20%20%20%20%20%20del%20features%5B%22fuel_efficiency_mpg%22%5D%0A%0A%20%20%20%20%20%20%20%20return%20features%2C%20target%0A%0A%20%20%20%20def%20train_dict_vectorizer(df%3A%20pd.DataFrame)%20-%3E%20DictVectorizer%3A%0A%20%20%20%20%20%20%20%20features%2C%20_%20%3D%20separate_target(df)%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(features.to_dict(orient%3D%22records%22))%0A%0A%20%20%20%20%20%20%20%20return%20dict_vectorizer%0A%0A%20%20%20%20dict_vectorizer%20%3D%20train_dict_vectorizer(df_train)%0A%20%20%20%20return%20DictVectorizer%2C%20dict_vectorizer%2C%20separate_target%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%20Question%201%0A%0A%20%20%20%20Let's%20train%20a%20decision%20tree%20regressor%20to%20predict%20the%20%60fuel_efficiency_mpg%60%20variable.%20%0A%0A%20%20%20%20*%20Train%20a%20model%20with%20%60max_depth%3D1%60.%0A%0A%0A%20%20%20%20Which%20feature%20is%20used%20for%20splitting%20the%20data%3F%0A%0A%0A%20%20%20%20*%20%60'vehicle_weight'%60%0A%20%20%20%20*%20%60'model_year'%60%0A%20%20%20%20*%20%60'origin'%60%0A%20%20%20%20*%20%60'fuel_type'%60%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(DictVectorizer%2C%20df_train%2C%20dict_vectorizer%2C%20pd%2C%20separate_target)%3A%0A%20%20%20%20from%20sklearn.tree%20import%20DecisionTreeRegressor%0A%0A%20%20%20%20def%20train_smallest_decision_tree(df%3A%20pd.DataFrame%2C%20dict_vectorizer%3A%20DictVectorizer)%20-%3E%20DecisionTreeRegressor%3A%0A%20%20%20%20%20%20%20%20features%2C%20y%20%3D%20separate_target(df)%0A%20%20%20%20%20%20%20%20X%20%3D%20dict_vectorizer.transform(features.to_dict(orient%3D%22records%22))%0A%20%20%20%20%20%20%20%20decision_tree%20%3D%20DecisionTreeRegressor(max_depth%3D1)%0A%20%20%20%20%20%20%20%20decision_tree.fit(X%2C%20y)%0A%0A%20%20%20%20%20%20%20%20return%20decision_tree%0A%0A%20%20%20%20smallest_decision_tree%20%3D%20train_smallest_decision_tree(df_train%2C%20dict_vectorizer)%0A%20%20%20%20return%20(smallest_decision_tree%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22As%20we%20can%20see%20below%2C%20**vehicle_weight**%20is%20the%20principal%20feature%20used%20to%20split%20the%20data.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dict_vectorizer%2C%20smallest_decision_tree)%3A%0A%20%20%20%20from%20sklearn.tree%20import%20plot_tree%0A%0A%20%20%20%20plot_tree(smallest_decision_tree%2C%20feature_names%3Ddict_vectorizer.get_feature_names_out().tolist())%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%20Question%202%0A%0A%20%20%20%20Train%20a%20random%20forest%20regressor%20with%20these%20parameters%3A%0A%0A%20%20%20%20*%20%60n_estimators%3D10%60%0A%20%20%20%20*%20%60random_state%3D1%60%0A%20%20%20%20*%20%60n_jobs%3D-1%60%20(optional%20-%20to%20make%20training%20faster)%0A%0A%0A%20%20%20%20What's%20the%20RMSE%20of%20this%20model%20on%20the%20validation%20data%3F%0A%0A%20%20%20%20*%200.045%0A%20%20%20%20*%200.45%0A%20%20%20%20*%204.5%0A%20%20%20%20*%2045.0%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(DictVectorizer%2C%20df_train%2C%20dict_vectorizer%2C%20pd%2C%20separate_target)%3A%0A%20%20%20%20from%20typing%20import%20Optional%0A%20%20%20%20from%20sklearn.ensemble%20import%20RandomForestRegressor%0A%0A%20%20%20%20def%20train_random_forest(%0A%20%20%20%20%20%20%20%20df%3A%20pd.DataFrame%2C%0A%20%20%20%20%20%20%20%20dict_vectorizer%3A%20DictVectorizer%2C%0A%20%20%20%20%20%20%20%20n_estimators%3A%20int%20%3D%2010%2C%0A%20%20%20%20%20%20%20%20max_depth%3A%20Optional%5Bint%5D%20%3D%20None%0A%20%20%20%20)%20-%3E%20RandomForestRegressor%3A%0A%20%20%20%20%20%20%20%20features%2C%20y%20%3D%20separate_target(df)%0A%20%20%20%20%20%20%20%20X%20%3D%20dict_vectorizer.transform(features.to_dict(orient%3D%22records%22))%0A%20%20%20%20%20%20%20%20random_forest%20%3D%20RandomForestRegressor(n_estimators%3Dn_estimators%2C%20max_depth%3Dmax_depth%2C%20random_state%3D1%2C%20n_jobs%3D-1)%0A%20%20%20%20%20%20%20%20random_forest.fit(X%2C%20y)%0A%0A%20%20%20%20%20%20%20%20return%20random_forest%0A%0A%20%20%20%20random_forest%20%3D%20train_random_forest(df_train%2C%20dict_vectorizer)%0A%20%20%20%20return%20RandomForestRegressor%2C%20random_forest%2C%20train_random_forest%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22The%20RMSE%20of%20the%20random%20forest%20model%20on%20the%20validation%20data%20is%20close%20to%200.45.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20DictVectorizer%2C%0A%20%20%20%20RandomForestRegressor%2C%0A%20%20%20%20df_val%2C%0A%20%20%20%20dict_vectorizer%2C%0A%20%20%20%20pd%2C%0A%20%20%20%20random_forest%2C%0A%20%20%20%20separate_target%2C%0A)%3A%0A%20%20%20%20from%20sklearn.metrics%20import%20root_mean_squared_error%0A%0A%20%20%20%20def%20predict_random_forest(%0A%20%20%20%20%20%20%20%20df%3A%20pd.DataFrame%2C%0A%20%20%20%20%20%20%20%20dict_vectorizer%3A%20DictVectorizer%2C%0A%20%20%20%20%20%20%20%20random_forest%3A%20RandomForestRegressor%0A%20%20%20%20)%20-%3E%20(pd.DataFrame%2C%20pd.DataFrame)%3A%0A%20%20%20%20%20%20%20%20features%2C%20y%20%3D%20separate_target(df)%0A%20%20%20%20%20%20%20%20X%20%3D%20dict_vectorizer.transform(features.to_dict(orient%3D%22records%22))%0A%0A%20%20%20%20%20%20%20%20return%20random_forest.predict(X)%2C%20y%0A%0A%20%20%20%20def%20eval_random_forest(%0A%20%20%20%20%20%20%20%20df%3A%20pd.DataFrame%2C%0A%20%20%20%20%20%20%20%20dict_vectorizer%3A%20DictVectorizer%2C%0A%20%20%20%20%20%20%20%20random_forest%3A%20RandomForestRegressor%0A%20%20%20%20)%20-%3E%20float%3A%0A%20%20%20%20%20%20%20%20y_pred%2C%20y%20%3D%20predict_random_forest(df_val%2C%20dict_vectorizer%2C%20random_forest)%0A%0A%20%20%20%20%20%20%20%20return%20root_mean_squared_error(y_true%3Dy%2C%20y_pred%3Dy_pred)%0A%0A%20%20%20%20eval_random_forest(df_val%2C%20dict_vectorizer%2C%20random_forest)%0A%20%20%20%20return%20(eval_random_forest%2C)%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%20Question%203%0A%0A%20%20%20%20Now%20let's%20experiment%20with%20the%20%60n_estimators%60%20parameter%0A%0A%20%20%20%20*%20Try%20different%20values%20of%20this%20parameter%20from%2010%20to%20200%20with%20step%2010.%0A%20%20%20%20*%20Set%20%60random_state%60%20to%20%601%60.%0A%20%20%20%20*%20Evaluate%20the%20model%20on%20the%20validation%20dataset.%0A%0A%0A%20%20%20%20After%20which%20value%20of%20%60n_estimators%60%20does%20RMSE%20stop%20improving%3F%0A%20%20%20%20Consider%203%20decimal%20places%20for%20calculating%20the%20answer.%0A%0A%20%20%20%20-%2010%0A%20%20%20%20-%2025%0A%20%20%20%20-%2080%0A%20%20%20%20-%20200%0A%0A%20%20%20%20If%20it%20doesn't%20stop%20improving%2C%20use%20the%20latest%20iteration%20number%20in%0A%20%20%20%20your%20answer.%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20DictVectorizer%2C%0A%20%20%20%20df_train%2C%0A%20%20%20%20df_val%2C%0A%20%20%20%20dict_vectorizer%2C%0A%20%20%20%20eval_random_forest%2C%0A%20%20%20%20pd%2C%0A%20%20%20%20train_random_forest%2C%0A)%3A%0A%20%20%20%20def%20evaluate_n_estimators(df_train%3A%20pd.DataFrame%2C%20df_val%3A%20pd.DataFrame%2C%20dict_vectorizer%3A%20DictVectorizer)%20-%3E%20dict%3A%0A%20%20%20%20%20%20%20%20evals%20%3D%20%5B%5D%0A%0A%20%20%20%20%20%20%20%20for%20n%20in%20range(10%2C%20201%2C%2010)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20random_forest%20%3D%20train_random_forest(df_train%2C%20dict_vectorizer%2C%20n_estimators%3Dn)%0A%20%20%20%20%20%20%20%20%20%20%20%20eval%20%3D%20eval_random_forest(df_val%2C%20dict_vectorizer%2C%20random_forest)%0A%20%20%20%20%20%20%20%20%20%20%20%20evals.append((n%2C%20eval))%0A%0A%20%20%20%20%20%20%20%20return%20pd.DataFrame(evals%2C%20columns%3D%5B%22n_estimators%22%2C%20%22rmse%22%5D)%0A%0A%20%20%20%20n_estimators_evals%20%3D%20evaluate_n_estimators(df_train%2C%20df_val%2C%20dict_vectorizer)%0A%0A%20%20%20%20n_estimators_evals.sort_values(%22rmse%22%2C%20ascending%3DTrue)%5B%3A5%5D%0A%20%20%20%20return%20(n_estimators_evals%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22The%20improvement%20stops%20at%20about%20200%20estimators.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(n_estimators_evals%2C%20plt%2C%20sns)%3A%0A%20%20%20%20best_n_estimators%20%3D%20n_estimators_evals.sort_values(%22rmse%22%2C%20ascending%3DTrue)%5B0%3A1%5D.n_estimators.min()%0A%0A%20%20%20%20plt.figure(figsize%3D(12%2C%207))%0A%20%20%20%20plt.title(%22Improvement%20limit%22)%0A%20%20%20%20ax%20%3D%20sns.lineplot(x%3Dn_estimators_evals.n_estimators%2C%20y%3Dn_estimators_evals.rmse%2C%20color%3D%22limegreen%22)%0A%20%20%20%20ax.axvline(x%20%3D%20best_n_estimators%2C%20ymin%20%3D%200%2C%20ymax%20%3D%201)%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%20Question%204%0A%0A%20%20%20%20Let's%20select%20the%20best%20%60max_depth%60%3A%0A%0A%20%20%20%20*%20Try%20different%20values%20of%20%60max_depth%60%3A%20%60%5B10%2C%2015%2C%2020%2C%2025%5D%60%0A%20%20%20%20*%20For%20each%20of%20these%20values%2C%0A%20%20%20%20%20%20*%20try%20different%20values%20of%20%60n_estimators%60%20from%2010%20till%20200%20(with%20step%2010)%0A%20%20%20%20%20%20*%20calculate%20the%20mean%20RMSE%20%0A%20%20%20%20*%20Fix%20the%20random%20seed%3A%20%60random_state%3D1%60%0A%0A%20%20%20%20def%20evaluate_n_estimators(df_train%3A%20pd.DataFrame%2C%20df_val%3A%20pd.DataFrame%2C%20dict_vectorizer%3A%20DictVectorizer)%20-%3E%20dict%3A%0A%20%20%20%20%20%20%20%20evals%20%3D%20%5B%5D%0A%0A%20%20%20%20%20%20%20%20for%20n%20in%20range(10%2C%20201%2C%2010)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20random_forest%20%3D%20train_random_forest(df_train%2C%20dict_vectorizer%2C%20n_estimators%3Dn)%0A%20%20%20%20%20%20%20%20%20%20%20%20eval%20%3D%20eval_random_forest(df_val%2C%20dict_vectorizer%2C%20random_forest)%0A%20%20%20%20%20%20%20%20%20%20%20%20evals.append((n%2C%20eval))%0A%0A%20%20%20%20%20%20%20%20return%20pd.DataFrame(evals%2C%20columns%3D%5B%22n_estimators%22%2C%20%22rmse%22%5D)%0A%0A%20%20%20%20n_estimators_evals%20%3D%20evaluate_n_estimators(df_train%2C%20df_val%2C%20dict_vectorizer)%0A%0A%20%20%20%20n_estimators_evals.sort_values(%22rmse%22%2C%20ascending%3DTrue)%5B%3A5%5D%0A%20%20%20%20What's%20the%20best%20%60max_depth%60%2C%20using%20the%20mean%20RMSE%3F%0A%0A%20%20%20%20*%2010%0A%20%20%20%20*%2015%0A%20%20%20%20*%2020%0A%20%20%20%20*%2025%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20DictVectorizer%2C%0A%20%20%20%20df_train%2C%0A%20%20%20%20df_val%2C%0A%20%20%20%20dict_vectorizer%2C%0A%20%20%20%20eval_random_forest%2C%0A%20%20%20%20pd%2C%0A%20%20%20%20train_random_forest%2C%0A)%3A%0A%20%20%20%20def%20evaluate_n_estimators_and_max_depth(%0A%20%20%20%20%20%20%20%20df_train%3A%20pd.DataFrame%2C%0A%20%20%20%20%20%20%20%20df_val%3A%20pd.DataFrame%2C%0A%20%20%20%20%20%20%20%20dict_vectorizer%3A%20DictVectorizer%0A%20%20%20%20)%20-%3E%20dict%3A%0A%20%20%20%20%20%20%20%20evals%20%3D%20%5B%5D%0A%0A%20%20%20%20%20%20%20%20for%20d%20in%20%5B10%2C%2015%2C%2020%2C%2025%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20n%20in%20range(10%2C%20201%2C%2010)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20random_forest%20%3D%20train_random_forest(df_train%2C%20dict_vectorizer%2C%20n_estimators%3Dn%2C%20max_depth%3Dd)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20eval%20%3D%20eval_random_forest(df_val%2C%20dict_vectorizer%2C%20random_forest)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20evals.append((d%2C%20n%2C%20eval))%0A%0A%20%20%20%20%20%20%20%20return%20pd.DataFrame(evals%2C%20columns%3D%5B%22max_depth%22%2C%20%22n_estimators%22%2C%20%22rmse%22%5D)%0A%0A%20%20%20%20n_estimators_and_max_depth_evals%20%3D%20evaluate_n_estimators_and_max_depth(df_train%2C%20df_val%2C%20dict_vectorizer)%0A%0A%20%20%20%20n_estimators_and_max_depth_evals.sort_values(%22rmse%22%2C%20ascending%3DTrue)%5B%3A5%5D%0A%20%20%20%20return%20(n_estimators_and_max_depth_evals%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22The%20best%20**max_depth**%20according%20to%20the%20RMSE%20metric%20is%2010.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(n_estimators_and_max_depth_evals%2C%20plt%2C%20sns)%3A%0A%20%20%20%20plt.figure(figsize%3D(12%2C%207))%0A%20%20%20%20plt.title(%22Best%20parameters%22)%0A%0A%20%20%20%20n_estimators_and_max_depth_evals.max_depth%20%3D%20%22max_depth%3D%22%20%2B%20n_estimators_and_max_depth_evals.max_depth.astype(str)%0A%20%20%20%20n_estimators_and_max_depth_evals.pivot(index%3D%22n_estimators%22%2C%20columns%3D%22max_depth%22%2C%20values%3D%22rmse%22)%0A%0A%20%20%20%20sns.heatmap(%0A%20%20%20%20%20%20%20%20n_estimators_and_max_depth_evals.pivot(index%3D%22n_estimators%22%2C%20columns%3D%5B%22max_depth%22%5D)%2C%0A%20%20%20%20%20%20%20%20annot%3DTrue%2C%0A%20%20%20%20%20%20%20%20fmt%3D%22.3f%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%20Question%205%0A%0A%20%20%20%20We%20can%20extract%20feature%20importance%20information%20from%20tree-based%20models.%20%0A%0A%20%20%20%20At%20each%20step%20of%20the%20decision%20tree%20learning%20algorithm%2C%20it%20finds%20the%20best%20split.%20%0A%20%20%20%20When%20doing%20it%2C%20we%20can%20calculate%20%22gain%22%20-%20the%20reduction%20in%20impurity%20before%20and%20after%20the%20split.%20%0A%20%20%20%20This%20gain%20is%20quite%20useful%20in%20understanding%20what%20are%20the%20important%20features%20for%20tree-based%20models.%0A%0A%20%20%20%20In%20Scikit-Learn%2C%20tree-based%20models%20contain%20this%20information%20in%20the%0A%20%20%20%20%5B%60feature_importances_%60%5D(https%3A%2F%2Fscikit-learn.org%2Fstable%2Fmodules%2Fgenerated%2Fsklearn.ensemble.RandomForestRegressor.html%23sklearn.ensemble.RandomForestRegressor.feature_importances_)%0A%20%20%20%20field.%20%0A%0A%20%20%20%20For%20this%20homework%20question%2C%20we'll%20find%20the%20most%20important%20feature%3A%0A%0A%20%20%20%20*%20Train%20the%20model%20with%20these%20parameters%3A%0A%20%20%20%20%20%20*%20%60n_estimators%3D10%60%2C%0A%20%20%20%20%20%20*%20%60max_depth%3D20%60%2C%0A%20%20%20%20%20%20*%20%60random_state%3D1%60%2C%0A%20%20%20%20%20%20*%20%60n_jobs%3D-1%60%20(optional)%0A%20%20%20%20*%20Get%20the%20feature%20importance%20information%20from%20this%20model%0A%0A%0A%20%20%20%20What's%20the%20most%20important%20feature%20(among%20these%204)%3F%20%0A%0A%20%20%20%20*%20%60vehicle_weight%60%0A%20%20%20%20*%09%60horsepower%60%0A%20%20%20%20*%20%60acceleration%60%0A%20%20%20%20*%20%60engine_displacement%60%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20DictVectorizer%2C%0A%20%20%20%20df_train%2C%0A%20%20%20%20df_val%2C%0A%20%20%20%20dict_vectorizer%2C%0A%20%20%20%20pd%2C%0A%20%20%20%20train_random_forest%2C%0A)%3A%0A%20%20%20%20def%20find_importances(df_train%3A%20pd.DataFrame%2C%20df_val%3A%20pd.DataFrame%2C%20dict_vectorizer%3A%20DictVectorizer)%3A%0A%20%20%20%20%20%20%20%20random_forest%20%3D%20train_random_forest(df_train%2C%20dict_vectorizer%2C%20n_estimators%3D10%2C%20max_depth%3D20)%0A%0A%20%20%20%20%20%20%20%20importances%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20for%20name%2C%20importance%20in%20zip(dict_vectorizer.get_feature_names_out()%2C%20random_forest.feature_importances_)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20importances%5Bname%5D%20%3D%20importance%0A%0A%20%20%20%20%20%20%20%20return%20importances%0A%0A%20%20%20%20importances%20%3D%20find_importances(df_train%2C%20df_val%2C%20dict_vectorizer)%0A%20%20%20%20importances%0A%20%20%20%20return%20(importances%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22The%20most%20important%20feature%20is%20**vehicle_weight**.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(importances)%3A%0A%20%20%20%20importances%5B%22vehicle_weight%22%5D%2C%20importances%5B%22horsepower%22%5D%2C%20importances%5B%22acceleration%22%5D%2C%20importances%5B%22engine_displacement%22%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%20Question%206%0A%0A%20%20%20%20Now%20let's%20train%20an%20XGBoost%20model!%20For%20this%20question%2C%20we'll%20tune%20the%20%60eta%60%20parameter%3A%0A%0A%20%20%20%20*%20Install%20XGBoost%0A%20%20%20%20*%20Create%20DMatrix%20for%20train%20and%20validation%0A%20%20%20%20*%20Create%20a%20watchlist%0A%20%20%20%20*%20Train%20a%20model%20with%20these%20parameters%20for%20100%20rounds%3A%0A%0A%20%20%20%20%60%60%60%0A%20%20%20%20xgb_params%20%3D%20%7B%0A%20%20%20%20%20%20%20%20'eta'%3A%200.3%2C%20%0A%20%20%20%20%20%20%20%20'max_depth'%3A%206%2C%0A%20%20%20%20%20%20%20%20'min_child_weight'%3A%201%2C%0A%0A%20%20%20%20%20%20%20%20'objective'%3A%20'reg%3Asquarederror'%2C%0A%20%20%20%20%20%20%20%20'nthread'%3A%208%2C%0A%0A%20%20%20%20%20%20%20%20'seed'%3A%201%2C%0A%20%20%20%20%20%20%20%20'verbosity'%3A%201%2C%0A%20%20%20%20%7D%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20Now%20change%20%60eta%60%20from%20%600.3%60%20to%20%600.1%60.%0A%0A%20%20%20%20Which%20eta%20leads%20to%20the%20best%20RMSE%20score%20on%20the%20validation%20dataset%3F%0A%0A%20%20%20%20*%200.3%0A%20%20%20%20*%200.1%0A%20%20%20%20*%20Both%20give%20equal%20value%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(DictVectorizer%2C%20pd%2C%20separate_target)%3A%0A%20%20%20%20import%20xgboost%20as%20xgb%0A%20%20%20%20from%20xgboost.core%20import%20Booster%0A%0A%20%20%20%20def%20train_xgboost(%0A%20%20%20%20%20%20%20%20df_train%3A%20pd.DataFrame%2C%0A%20%20%20%20%20%20%20%20df_val%3A%20pd.DataFrame%2C%0A%20%20%20%20%20%20%20%20dict_vectorizer%3A%20DictVectorizer%2C%0A%20%20%20%20%20%20%20%20eta%3A%20float%20%3D%200.3%0A%20%20%20%20)%20-%3E%20(Booster%2C%20dict)%3A%0A%20%20%20%20%20%20%20%20features_train%2C%20y_train%20%3D%20separate_target(df_train)%0A%20%20%20%20%20%20%20%20X_train%20%3D%20dict_vectorizer.transform(features_train.to_dict(orient%3D%22records%22))%0A%0A%20%20%20%20%20%20%20%20dmatrix_train%20%3D%20xgb.DMatrix(%0A%20%20%20%20%20%20%20%20%20%20%20%20X_train%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20label%3Dy_train%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20feature_names%3Ddict_vectorizer.get_feature_names_out().tolist()%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20features_val%2C%20y_val%20%3D%20separate_target(df_val)%0A%20%20%20%20%20%20%20%20X_val%20%3D%20dict_vectorizer.transform(features_val.to_dict(orient%3D%22records%22))%0A%0A%20%20%20%20%20%20%20%20dmatrix_val%20%3D%20xgb.DMatrix(%0A%20%20%20%20%20%20%20%20%20%20%20%20X_val%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20label%3Dy_val%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20feature_names%3Ddict_vectorizer.get_feature_names_out().tolist()%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20watchlist%20%3D%20%5B(dmatrix_train%2C%20%22train%22)%2C%20(dmatrix_val%2C%20%22val%22)%5D%0A%20%20%20%20%20%20%20%20evals%20%3D%20%7B%7D%0A%0A%20%20%20%20%20%20%20%20xgb_params%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22eta%22%3A%20eta%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22max_depth%22%3A%206%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22min_child_weight%22%3A%201%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22objective%22%3A%20%22reg%3Asquarederror%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22nthread%22%3A%208%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22seed%22%3A%201%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22verbosity%22%3A%201%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22eval_metric%22%3A%20%22rmse%22%2C%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20booster%20%3D%20xgb.train(%0A%20%20%20%20%20%20%20%20%20%20%20%20xgb_params%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20dmatrix_train%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20num_boost_round%3D100%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20evals%3Dwatchlist%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20evals_result%3Devals%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20verbose_eval%3DFalse%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20return%20booster%2C%20evals%0A%20%20%20%20return%20(train_xgboost%2C)%0A%0A%0A%40app.cell%0Adef%20_(df_train%2C%20df_val%2C%20dict_vectorizer%2C%20train_xgboost)%3A%0A%20%20%20%20first_booster%2C%20first_evals%20%3D%20train_xgboost(df_train%2C%20df_val%2C%20dict_vectorizer%2C%20eta%3D0.3)%0A%20%20%20%20second_booster%2C%20second_evals%20%3D%20train_xgboost(df_train%2C%20df_val%2C%20dict_vectorizer%2C%20eta%3D0.1)%0A%20%20%20%20return%20first_evals%2C%20second_evals%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22The%20best%20RMSE%20is%20found%20for%20ETA%20%3D%200.1%20when%20the%20number%20of%20rounds%20approaches%20100.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(first_evals%2C%20second_evals)%3A%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22min_rmse(eta%3D0.3)%22%3A%20min(first_evals%5B%22val%22%5D%5B%22rmse%22%5D)%2C%0A%20%20%20%20%20%20%20%20%22min_rmse(eta%3D0.1)%22%3A%20min(second_evals%5B%22val%22%5D%5B%22rmse%22%5D)%2C%0A%20%20%20%20%7D%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(first_evals%2C%20second_evals%2C%20sns)%3A%0A%20%20%20%20sns.lineplot(first_evals%5B%22val%22%5D%5B%22rmse%22%5D%2C%20label%3D%22ETA%20%3D%200.3%22)%0A%20%20%20%20sns.lineplot(second_evals%5B%22val%22%5D%5B%22rmse%22%5D%2C%20label%3D%22ETA%20%3D%200.1%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%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%20Submit%20the%20results%0A%0A%20%20%20%20*%20Submit%20your%20results%20here%3A%20https%3A%2F%2Fcourses.datatalks.club%2Fml-zoomcamp-2025%2Fhomework%2Fhw06%0A%20%20%20%20*%20If%20your%20answer%20doesn't%20match%20options%20exactly%2C%20select%20the%20closest%20one.%20If%20the%20answer%20is%20exactly%20in%20between%20two%20options%2C%20select%20the%20higher%20value.%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
e4f6fb9c3a62c0b25b4f73a17a39bafe9703b69646b54ff7463971a484f32624