df=df[df['operation_type']=='Venta']
df=df[df['property_type']=='Casa']
df=df[df['currency']=='COP']
df=df[df['l3']=='Bogotá D.C']
df=df[[ 'price', 'rooms', 'bathrooms', 'surface_total', 'surface_covered','lat','lon']]
df=df.dropna()

df = geopandas.GeoDataFrame(df, geometry=geopandas.points_from_xy(df.lon, df.lat))
df=df.set_crs(epsg=4326, inplace=True)

"""
Explanation: The most reliable Python library to manage spatial data is geopandas. Unfortunately, the instalation of geopandas is not as trivial as the other Python librarys we have seen. For this reason, I leave a blog with a simple way of installing geopandas


Data preprocesing
End of explanation
"""


lat=[4.61083]
lon=[-74.070278]
colp=pd.DataFrame({'lat':lat,'lon':lon})
colp = geopandas.GeoDataFrame(colp , geometry=geopandas.points_from_xy(colp.lon, colp.lat))
df=df.reset_index(drop=True)
colp=colp.set_crs(epsg=4326, inplace=True)
colp=colp.to_crs(epsg=3310)
df=df.to_crs(epsg=3310)
dis=[]
for i in tqdm(df.index):
    dis.append(colp.distance(df['geometry'][i])[0])

df['dis_centro']=dis

"""
Explanation: Let's see if we can use the distance to the center of the city as a feature in our model
End of explanation
"""


estaciones=geopandas.read_file('estaciones.zip')
estaciones=estaciones.to_crs(epsg=4326)
df=df.reset_index(drop=True)
puntos = estaciones['geometry'].tolist()
puntos = MultiPoint(puntos)

"""
Explanation: Import shapefile with geopandas
End of explanation
"""


n=nearest_points(df['geometry'][0],puntos)[1]

estaciones[estaciones['geometry'] == n].index[0]

(estaciones.iloc[[510]].distance(df['geometry'][0]))[510]

distancia_transmi=[]
for i in tqdm(df.index):
    n=nearest_points(df['geometry'][0],puntos)[1]
    y=estaciones[estaciones['geometry'] == n].index[0]
    distancia_transmi.append((estaciones.iloc[[y]].distance(df['geometry'][0]))[y])
    
    

df['distancia_transmi']=distancia_transmi

"""
Explanation: Let´s find the distance of each property to the nearest transmilenio station
End of explanation
"""


df=df.drop(columns=['geometry'])

x_train, x_test, y_train, y_test = train_test_split(df.drop(columns=['price']),df['price'], test_size=0.30,
                                                    random_state=289988888,
                                                    shuffle=True)

folds = KFold(n_splits = 5, shuffle = True, random_state = 100)
lasso_params = {'alpha':np.logspace(-8, 8, 100)}
lasso= linear_model.Lasso()

            
model_cv = GridSearchCV(estimator = lasso, 
                        param_grid = lasso_params, 
                        scoring='neg_mean_squared_error', 
                        cv = folds, 
                        verbose = 1,
                        return_train_score=True
                       ,n_jobs=10)      
bla=model_cv.fit(x_train, y_train)  

bla.best_estimator_

mse(y_test, bla.predict(x_test))

mse(y_train, bla.predict(x_train))

pd.DataFrame(bla.cv_results_)

"""
Explanation: lasso CV

common notation l1=Lasso l2=ridge
End of explanation
"""


folds = KFold(n_splits = 5, shuffle = True, random_state = 100)
Ridge_params = {'alpha':np.logspace(-8, 8, 100)}
Ridge= linear_model.Ridge()

            
model2_cv = GridSearchCV(estimator = Ridge, 
                        param_grid = Ridge_params, 
                        scoring='neg_mean_squared_error', 
                        cv = folds, 
                        verbose = 1,
                        return_train_score=True
                       ,n_jobs=10)      
bla2=model2_cv.fit(x_train, y_train)  

bla2.best_estimator_

mse(y_test, bla2.predict(x_test))

mse(y_train, bla2.predict(x_train))

"""
Explanation: Ridge CV
End of explanation
"""


def entrenar_modelo(modelo,grid,data,nombre):

    x_train, x_test, y_train, y_test = train_test_split(data.drop(columns=['malignant']),data['malignant'], test_size=0.30,
                                                    random_state=28888888,
                                                    shuffle=True)

    gsearch = GridSearchCV(estimator = modelo,
                           param_grid = grid,                         
                           scoring='neg_mean_squared_error', 
                           cv = 5,
                           n_jobs = -1,
                           verbose = 1)
    model=gsearch.fit(x_train,y_train)
    mejor_estimador=bla2.best_estimator_
    in_sample=mse(y_test, bla2.predict(x_test))
    out_of_sample=mse(y_train, bla2.predict(x_train))

   

    
    return model,in_sample,mejor_estimador

"""
Explanation: General function
End of explanation
"""


