<jupyter_start><jupyter_text>First Machine Learning Project  Automate the Data Fetching<jupyter_code>import os 
from zipfile import ZipFile

def extract_data(name_of_zip="cars", ROOT='C:/Users/VTSB/Desktop/CS Resources/AI Hands-On ML/datasets', extension=".csv.zip", reset_path="C:/Users/VTSB/Desktop/CS Resources/AI Hands-On ML"):
    os.chdir("C:/Users/VTSB/Downloads")
    print(os.getcwd())
    with ZipFile(name_of_zip + extension, 'r') as zipObj:
           zipObj.extractall(os.path.join(ROOT, name_of_zip))
    os.chdir(reset_path)
    print(os.getcwd())
        
extract_data()
import pandas as pd

def load_data(ROOT='C:/Users/VTSB/Desktop/CS Resources/AI Hands-On ML/datasets', extension=".csv", name_of_zip="cars"):
    csv_path = ROOT + "/" + name_of_zip + "/" + name_of_zip + extension
    print(csv_path)
    return pd.read_csv(csv_path)

original_df = load_data()
original_df
original_df = original_df.drop(columns="model_name")
original_df["engine_fuel"].value_counts()
original_df["engine_fuel"] = original_df["engine_fuel"].replace(["hybrid-diesel", "electric"], "gasoline")
original_df["engine_fuel"].value_counts()<jupyter_output><empty_output><jupyter_text>Preview the Data<jupyter_code>original_df.head()
original_df.info()

# engine_capacity has a few nulls (10)

# bool(13)
# float64(2)
# int64(5)
# object(10)
original_df.columns
original_df.describe()
original_df.shape
for x in original_df.columns:
    if original_df[x].dtype == "O":
        print(x + ": ", original_df[x].value_counts().count())
# counter = 0
# for x in original_df["model_name"].value_counts():
#     if x < 100:
#         counter += 1
# print(str(counter) + "\n") # number of model_names that have a frequency of less than 100

# print(original_df["model_name"].value_counts().sort_values(ascending=True))
import matplotlib.pyplot as plt
%matplotlib inline

def listing_numerical_columns():
    list_of_numerical_columns = []
    for x in original_df.columns:
        if original_df[x].dtype == "int64" or original_df[x].dtype == "float64":
            list_of_numerical_columns.append(x)
    print(list_of_numerical_columns)
        
listing_numerical_columns()
        
def preview_graphs(numerical_column_name):
    if original_df[numerical_column_name].dtype == "int64" or original_df[numerical_column_name].dtype == "float64":
        original_df[numerical_column_name].hist(bins=50)
        plt.title(numerical_column_name)

preview_graphs("odometer_value")<jupyter_output>['odometer_value', 'year_produced', 'engine_capacity', 'price_usd', 'number_of_photos', 'up_counter', 'duration_listed']<jupyter_text>Create Test Data<jupyter_code>from sklearn.model_selection import StratifiedShuffleSplit

split = StratifiedShuffleSplit(test_size=0.2, n_splits=1, random_state=42)

for train_index, test_index in split.split(original_df, original_df["manufacturer_name"]):
    strat_train_set = original_df.loc[train_index]
    strat_test_set = original_df.loc[test_index]
    
strat_train_set
# check how evenly distributed the stratification was 

strat_ratio = strat_train_set["manufacturer_name"].value_counts() / len(strat_train_set)
print(strat_ratio)
strat_test_set.info()
strat_train_set.info()
strat_train_set_features = strat_train_set.drop("price_usd", axis=1)
strat_train_set_labels = strat_train_set["price_usd"].copy()
strat_train_set_features
strat_train_set_labels<jupyter_output><empty_output><jupyter_text>EDA<jupyter_code>strat_train_set_EDA = strat_train_set.copy()
corr_matrix = strat_train_set_EDA.corr()
corr_matrix["price_usd"].sort_values(ascending=False)<jupyter_output><empty_output><jupyter_text>Data Cleaning And Combinations<jupyter_code>from sklearn.pipeline import Pipeline
from sklearn.base import TransformerMixin, BaseEstimator
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
strat_train_set_features
empty_list = []
for x in strat_train_set_features.columns:
    if strat_train_set_features[x].dtype == "float64" or strat_train_set_features[x].dtype == "int64":
        empty_list.append(x)
        
print(empty_list)
a = strat_train_set_features[empty_list]
a
2019 - a.iloc[:,1]
imputer = SimpleImputer(strategy="median")
b = imputer.fit_transform(a)
# print(imputer.statistics_)
print(len(b), len(b[0]))

print(b)
print(b[:, 1])<jupyter_output>30824 6
[[2.950e+05 2.003e+03 2.200e+00 1.400e+01 2.500e+01 9.600e+01]
 [4.100e+05 1.998e+03 2.000e+00 1.400e+01 8.000e+00 1.330e+02]
 [2.390e+05 2.010e+03 2.000e+00 1.300e+01 1.100e+01 3.100e+01]
 ...
 [3.300e+05 1.987e+03 2.200e+00 9.000e+00 5.000e+00 1.200e+01]
 [3.430e+05 1.964e+03 2.400e+00 4.000e+00 9.100e+01 1.530e+02]
 [7.896e+03 2.005e+03 1.200e+00 5.000e+00 1.000e+00 1.000e+00]]
[2003. 1998. 2010. ... 1987. 1964. 2005.]<jupyter_text>Custom Transformer<jupyter_code>class CombinedAttributesAdder(BaseEstimator, TransformerMixin):
    def __init__(self):
        pass
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        return X
        
s = CombinedAttributesAdder()
c = s.fit_transform(b)
print(c)
scaler = StandardScaler()
scaler.fit_transform(a)<jupyter_output><empty_output><jupyter_text>Numeric Pipeline<jupyter_code>num_pipeline = Pipeline([
    ("imputer", SimpleImputer(strategy="median")),
    ("attribs_adder", CombinedAttributesAdder()),
    ("standard_scaler", StandardScaler())
])

num_pipeline.fit_transform(a)<jupyter_output><empty_output><jupyter_text>Full Pipeline<jupyter_code>num_attribs, cat_attribs = [], []

for x in strat_train_set_features.columns:
    if strat_train_set_features[x].dtype == "float64" or strat_train_set_features[x].dtype == "int64":
        num_attribs.append(x)
    if strat_train_set_features[x].dtype == "object" or strat_train_set_features[x].dtype == "bool":
        cat_attribs.append(x)
print(num_attribs)
print(cat_attribs)
        
full_pipeline = ColumnTransformer([
    ("num", num_pipeline, num_attribs),
    ("cat", OneHotEncoder(), cat_attribs)
])

strat_train_set_features_prepared = full_pipeline.fit_transform(strat_train_set_features)
for x in strat_train_set_features.columns:
    print(x, strat_train_set_features[x].value_counts().count())
55 + 2 + 12 + 6 + 2 + 3 + 12 + 2 + 3 + 3 + 2 + 6 + 20 + 6
strat_train_set_features["engine_fuel"].value_counts()
len(strat_train_set_features_prepared.toarray()[0])
strat_train_set_features_prepared.toarray()<jupyter_output><empty_output><jupyter_text>Create and Train the Models<jupyter_code>from sklearn.linear_model import LinearRegression

lin_reg = LinearRegression()
lin_reg.fit(strat_train_set_features_prepared, strat_train_set_labels)
some_data = strat_train_set_features[:5]
print(some_data)
some_data_prepared = full_pipeline.transform(some_data)
some_labels = strat_train_set_labels[:5]
print(some_labels)

lin_reg.predict(some_data_prepared)
from sklearn.tree import DecisionTreeRegressor

decision_tree_reg = DecisionTreeRegressor()

decision_tree_reg.fit(strat_train_set_features_prepared, strat_train_set_labels)
print(some_labels)
decision_tree_reg.predict(some_data_prepared)
from sklearn.ensemble import RandomForestRegressor

random_forest_reg = RandomForestRegressor(verbose=2, n_jobs=-1)

random_forest_reg.fit(strat_train_set_features_prepared, strat_train_set_labels)
len(strat_train_set_features_prepared.toarray()[0])
print(some_labels)
random_forest_reg.predict(some_data_prepared)<jupyter_output>[Parallel(n_jobs=8)]: Using backend ThreadingBackend with 8 concurrent workers.
[Parallel(n_jobs=8)]: Done  25 tasks      | elapsed:    0.0s
[Parallel(n_jobs=8)]: Done 100 out of 100 | elapsed:    0.0s finished<jupyter_text>Evaluate the Model<jupyter_code>from sklearn.metrics import mean_squared_error
import numpy as np

lin_reg_all_predictions = lin_reg.predict(strat_train_set_features_prepared)
lin_reg_mse = mean_squared_error(strat_train_set_labels, lin_reg_all_predictions)
lin_reg_rmse = np.sqrt(lin_reg_mse)
print("lin_reg_rmse: ", lin_reg_rmse)
print(lin_reg_rmse/original_df["price_usd"].mean())
decision_tree_reg_all_predictions = decision_tree_reg.predict(strat_train_set_features_prepared)
decision_tree_reg_mse = mean_squared_error(strat_train_set_labels, decision_tree_reg_all_predictions)
decision_tree_reg_rmse = np.sqrt(decision_tree_reg_mse)
print("decision_tree_reg_rmse: ", decision_tree_reg_rmse)
print(decision_tree_reg_rmse/original_df["price_usd"].mean())
random_forest_reg_all_predictions = random_forest_reg.predict(strat_train_set_features_prepared)
random_forest_reg_mse = mean_squared_error(strat_train_set_labels, random_forest_reg_all_predictions)
random_forest_reg_rmse = np.sqrt(random_forest_reg_mse)
print("random_forest_reg_rmse: ", random_forest_reg_rmse)
print(random_forest_reg_rmse/original_df["price_usd"].mean())<jupyter_output>[Parallel(n_jobs=8)]: Using backend ThreadingBackend with 8 concurrent workers.
[Parallel(n_jobs=8)]: Done  25 tasks      | elapsed:    0.0s
[Parallel(n_jobs=8)]: Done 100 out of 100 | elapsed:    0.1s finished<jupyter_text>Cross Validation for Better Evaluations<jupyter_code>from sklearn.model_selection import cross_val_score

def display_scores(scores):
    print("Scores: ", scores)
    print("Mean: ", scores.mean())
    print("Standard Deviation: ", scores.std())

lin_reg_scores = cross_val_score(lin_reg, strat_train_set_features_prepared, strat_train_set_labels, 
                         scoring="neg_mean_squared_error", cv=10)
lin_reg_rmse_scores = np.sqrt(-lin_reg_scores)

display_scores(lin_reg_rmse_scores)
decision_tree_reg_scores = cross_val_score(decision_tree_reg, strat_train_set_features_prepared, strat_train_set_labels, 
                         scoring="neg_mean_squared_error", cv=10, verbose=2)
decision_tree_reg_rmse_scores = np.sqrt(-decision_tree_reg_scores)

display_scores(decision_tree_reg_rmse_scores)
random_forest_reg_scores = cross_val_score(random_forest_reg, strat_train_set_features_prepared, strat_train_set_labels, 
                         scoring="neg_mean_squared_error", cv=10, verbose=2)
random_forest_reg_rmse_scores = np.sqrt(-random_forest_reg_scores)

display_scores(random_forest_reg_rmse_scores)<jupyter_output>[CV]  ................................................................<jupyter_text>Fine Tuning<jupyter_code>from sklearn.model_selection import RandomizedSearchCV

param_grid = [ 
    {"n_estimators": [3, 10, 30, 60],
     "max_features": [2, 4, 6, 8]},
    {"bootstrap": [False],
     "n_estimators": [3, 10],
     "max_features": [2, 3, 4]}
]

rnd_search_cv = RandomizedSearchCV(random_forest_reg, param_grid, cv=5, n_jobs=-1,
                                   scoring="neg_mean_squared_error",
                                   return_train_score=True, verbose=2)

rnd_search_cv.fit(strat_train_set_features_prepared, strat_train_set_labels)
rnd_search_cv.best_params_
rnd_search_cv.best_estimator_
cvres = rnd_search_cv.cv_results_
cvres
for mean_test_scores, params in zip(cvres["mean_test_score"], cvres["params"]):
    print(np.sqrt(-mean_test_scores), params)
feature_importances = rnd_search_cv.best_estimator_.feature_importances_
print(len(feature_importances))
cat_encoder = full_pipeline.named_transformers_["cat"]
counter = 0
for x in cat_encoder.categories_:
    for y in x:
        counter += 1
print(counter)
cat_encoder.categories_
feature_importances
cat_encoder = full_pipeline.named_transformers_["cat"]
cat_encoder_categories = cat_encoder.categories_
cat_attribs = []
for x in cat_encoder_categories:
    for y in x:
        cat_attribs.append(y)
attributes = num_attribs + cat_attribs
sorted(zip(feature_importances, attributes), reverse=True)
cat_encoder_categories<jupyter_output><empty_output><jupyter_text>Evaluate on Test Set<jupyter_code>final_model = rnd_search_cv.best_estimator_

strat_test_set_features = strat_test_set.drop(columns="price_usd")
strat_test_set_labels = strat_test_set["price_usd"].copy()

strat_test_set_features_prepared = full_pipeline.transform(strat_test_set_features)

final_predictions = final_model.predict(strat_test_set_features_prepared)

final_mse = mean_squared_error(strat_test_set_labels, final_predictions)
final_rmse = np.sqrt(final_mse)
print(final_rmse)
len(strat_test_set_features_prepared.toarray()[0])
for x in strat_test_set_features.columns:
    print(x, strat_test_set_features[x].value_counts().count())
55 + 2 + 12 + 5 + 2 + 3 + 12 + 2 + 3 + 3 + 2 + 6 + 20 + 6
55 + 2 + 12 + 6 + 2 + 3 + 12 + 2 + 3 + 3 + 2 + 6 + 20 + 6
strat_test_set_features
strat_train_set_features["engine_fuel"].value_counts()
strat_test_set_features["engine_fuel"].value_counts()<jupyter_output><empty_output><jupyter_text>Additional Fine Tuning  Loading and Stratifying Data<jupyter_code>original_df_copy = load_data()
from sklearn.model_selection import StratifiedShuffleSplit

split_copy = StratifiedShuffleSplit(test_size=0.2, n_splits=1, random_state=42)

for train_index, test_index in split_copy.split(original_df_copy, original_df_copy["manufacturer_name"]):
    strat_train_set_copy = original_df_copy.loc[train_index]
    strat_test_set_copy = original_df_copy.loc[test_index]
    
strat_train_set_copy
strat_train_set_copy_features = strat_train_set_copy.drop(columns="price_usd")
strat_train_set_copy_labels = strat_train_set_copy["price_usd"].copy()<jupyter_output><empty_output><jupyter_text>Custom Boolean Transformer<jupyter_code>bool_attribs_list = []
for x in strat_train_set_copy_features.columns:
    if strat_train_set_copy_features[x].dtype == "bool":
        bool_attribs_list.append(x)

print(len(bool_attribs_list))
print(bool_attribs_list)
# X["engine_fuel"] = X["engine_fuel"].replace(["hybrid-diesel", "electric"], "gasoline")

class BooleanTransformer(BaseEstimator, TransformerMixin):
    def __init__(self):
        pass
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        X_copy = X.copy()
        for attribute in X_copy.columns:
            if X_copy[attribute].dtype == "bool":
                X_copy[attribute] = X_copy[attribute].replace([True, False], [1, 0])
        return X_copy
    
bool_transformer = BooleanTransformer()
stscf_bool_transformed = bool_transformer.fit_transform(strat_train_set_copy_features)
stscf_bool_transformed
stscf_bool_transformed.dtypes.value_counts()<jupyter_output><empty_output><jupyter_text>Custom Categorical Transformer<jupyter_code># original_df["engine_fuel"] = original_df["engine_fuel"].replace(["hybrid-diesel", "electric"], "gasoline")
# original_df = original_df.drop(columns="model_name")

class CategoricalTransformer(BaseEstimator, TransformerMixin):
    def __init__(self, drop_model_name=True):
        self.drop_model_name = drop_model_name
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        X_copy = X.copy()
        if self.drop_model_name:
            X_copy = X_copy.drop(columns="model_name")
            X_copy["engine_fuel"] = X_copy["engine_fuel"].replace(["hybrid-diesel", "electric"], "gasoline")
        return X_copy
    
categorical_transformer = CategoricalTransformer()
stscf_bool_transformed_cat_transformed = categorical_transformer.fit_transform(stscf_bool_transformed)
stscf_bool_transformed_cat_transformed<jupyter_output><empty_output><jupyter_text>Numerical Pipeline<jupyter_code>num_pipeline_copy = Pipeline([
    ("imputer", SimpleImputer(strategy="median")),
    ("attribs_adder", CombinedAttributesAdder()),
    ("standard_scaler", StandardScaler())
])<jupyter_output><empty_output><jupyter_text>Full Pipeline<jupyter_code>num_attribs_copy, cat_attribs_copy = [], []

for x in stscf_bool_transformed_cat_transformed.columns:
    if stscf_bool_transformed_cat_transformed[x].dtype == "float64" or stscf_bool_transformed_cat_transformed[x].dtype == "int64":
        num_attribs_copy.append(x)
    if stscf_bool_transformed_cat_transformed[x].dtype == "object":
        cat_attribs_copy.append(x)

print(num_attribs_copy)
print(len(num_attribs_copy))
print(cat_attribs_copy)
print(len(cat_attribs_copy))
full_pipeline_1 = ColumnTransformer([
    ("num_pipeline", num_pipeline_copy, num_attribs_copy),
    ("1hot_encoded", OneHotEncoder(), cat_attribs_copy)
])

fp1_stscf_bool_cat_transformed = full_pipeline_1.fit_transform(stscf_bool_transformed_cat_transformed)
type(fp1_stscf_bool_cat_transformed)<jupyter_output><empty_output><jupyter_text>Full and Modified Pipeline<jupyter_code>strat_train_set_copy_features_COPY = strat_train_set_copy_features.copy()

full_and_modified_pipeline = Pipeline([
    ("bool_tfm", BooleanTransformer()),
    ("cat_transformer", CategoricalTransformer()),
    ("full_pipeline", full_pipeline_1),
#    ("feature_selection", TopFeatureSelector(feature_importances, k))
])
fmp_prepared = full_and_modified_pipeline.fit_transform(strat_train_set_copy_features_COPY)
fmp_prepared<jupyter_output><empty_output><jupyter_text>Getting Feature Importances<jupyter_code>from sklearn.model_selection import RandomizedSearchCV
from sklearn.ensemble import RandomForestRegressor

param_grid1 = [ 
    {"n_estimators": [3, 10, 30, 60, 90, 120, 140, 160, 180, 200],
     "max_features": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]},
    {"bootstrap": [False],
     "n_estimators": [3, 10, 30, 60, 90, 120, 140, 160, 180, 200],
     "max_features": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]}
]

rand_forest_reg = RandomForestRegressor()
rnd_search_cv1 = RandomizedSearchCV(rand_forest_reg, param_grid1, cv=5, n_jobs=-1,
                                   scoring="neg_mean_squared_error",
                                   return_train_score=True, verbose=2)

rnd_search_cv1.fit(fmp_prepared, strat_train_set_copy_labels)
print("The best parameters:", rnd_search_cv1.best_params_)
print("The best estimator:", rnd_search_cv1.best_estimator_)
print("The most important features on the best estimator:", \
      rnd_search_cv1.best_estimator_.feature_importances_)

cvres1 = rnd_search_cv1.cv_results_
for mean_test_scores, params in zip(cvres1["mean_test_score"], cvres1["params"]):
    print(np.sqrt(-mean_test_scores), params)
    

fmp_prepared.toarray()[0]
i = full_and_modified_pipeline.named_steps["full_pipeline"] # named_steps for Pipeline
h = i.named_transformers_["1hot_encoded"] # named_transformers_ for ColumnTransformer
h.categories_
be_feature_importances = rnd_search_cv1.best_estimator_.feature_importances_
print(len(be_feature_importances))

categorical_array_values_list = []
for array_of_categorical_values in h.categories_:
    for categorical_array_value in array_of_categorical_values:
        categorical_array_values_list.append(categorical_array_value)
attributes = num_attribs_copy + categorical_array_values_list
sorted_feature_importances = sorted(zip(be_feature_importances, attributes), reverse=True)
sorted_feature_importances<jupyter_output>119<jupyter_text>Feature Selection<jupyter_code># k = 5

top_features_list = []
for x in sorted_feature_importances[:5]:
    top_features_list.append(x[1])
print(top_features_list)

index_of_top_features = []
print(attributes)
for x in top_features_list:
    index_of_top_features.append(attributes.index(x))
print(sorted(index_of_top_features))
def indices_of_top_k(sorted_feature_importances, k):
    top_features_list, index_of_top_features = [], []
    for x in sorted_feature_importances[:k]:
        top_features_list.append(x[1])

    for x in top_features_list:
        index_of_top_features.append(attributes.index(x))
    return sorted(index_of_top_features)
    
    # return np.sort(np.argpartition(np.array(arr), -k)[-k:])

class FeatureSelection(BaseEstimator, TransformerMixin):
    def __init__(self, sorted_feature_importances, k):
        self.sorted_feature_importances = sorted_feature_importances
        self.k = k
    def fit(self, X, y=None):
        self.feature_indices_ = indices_of_top_k(self.sorted_feature_importances, self.k)
        # don't compute feature_importances_ here because it will drastically slow down
        # all calls to this fit() instance method
        return self
    def transform(self, X):
        X_copy = X.copy()
        if self.k > len(attributes):
            return X_copy
        elif self.k < len(attributes):
            return X_copy
        else:
            return X_copy[:, self.feature_indices_]

y = FeatureSelection(sorted_feature_importances, 5)
u = y.fit_transform(fp1_stscf_bool_cat_transformed)
u # 143778; 30824x5
fp1_stscf_bool_cat_transformed # 863072; 30824x119<jupyter_output><empty_output><jupyter_text>Full Modified Pipeline With Feature Selection and Model Training<jupyter_code>k = 30

fmp_selection_and_model_pipeline = Pipeline([
    ("fmp", full_and_modified_pipeline),
    ("feature_selection", FeatureSelection(sorted_feature_importances, k)),
    ("random_forest_reg_final", RandomForestRegressor(**rnd_search_cv1.best_params_))
])

fmp_selection_and_model_pipeline.fit(strat_train_set_copy_features, strat_train_set_copy_labels)
strat_test_set_copy_features = strat_test_set_copy.drop(columns="price_usd")
strat_test_set_copy_labels = strat_test_set_copy["price_usd"].copy()
fmp_final_predictions = fmp_selection_and_model_pipeline.predict(strat_test_set_copy_features)
fmp_mse = mean_squared_error(strat_test_set_copy_labels, fmp_final_predictions)
fmp_rmse = np.sqrt(fmp_mse)
fmp_rmse<jupyter_output><empty_output><jupyter_text>Fine Tuning Preparation Methods<jupyter_code>from sklearn.model_selection import GridSearchCV

param_grid_pspp = [{
    'fmp__full_pipeline__num_pipeline__imputer__strategy': ['mean', 'median', 'most_frequent'],
    'feature_selection__k': list(range(28, 32 + 1))
}]

grid_search_pspp = GridSearchCV(fmp_selection_and_model_pipeline, param_grid_pspp, cv=5,
                                scoring='neg_mean_squared_error', verbose=2, n_jobs=-1)
grid_search_pspp.fit(strat_train_set_copy_features, strat_train_set_copy_labels)
grid_search_pspp.best_params_<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10838156875256369, 'fraction_numerical': 0.02720933412333075, 'mean_word_length': 6.299401197604791, 'pattern_counts': {'":': 21, '<': 89, '<?xml version=': 0, '>': 88, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '23', 'dir': 'jupyter-structured-clean-dedup', 'id': '26353', 'license': 'MIT', 'n_tokens_mistral': 8377, 'n_tokens_neox': 7745, 'n_words': 1182, 'path': 'src/First ML Project.ipynb', 'repo_name': 'alckasoc/LearningML-Projects', 'size': '21941'}