def similarity(p1, p2): ''' :param p1: dictionary with the data for a house :param p2: dictionary with the data for a house :returns: a float with the distance between the houses in the input. NOTE: the bigger the number the less the similarity among p1 and p2 Example: In [8]: similarity({"lat" : 123123.2, "lng" : 12321.2, "gross_size" : 123312}, {"lat" : 234323.2, "lng" : 2321.2, "gross_size" : 23423}) Out[8]: 149810.7216490195 ''' return terceroB_ML_banks.pos2dist(p1["lat"], p1["lng"], p2["lat"], p2["lng"])
def train(input_data, house_type="flat", house_subtype=""): ''' :param input_data: Pandas data frame with the input data :param house_type: string with the type of the houses corresponding to this model, houses in input_data with other type will be discarded :param house_subtype: currently not used, in the future will be used like house_type :returns a pair of dictionaries: * the first one is a dictionary for the output model * the second one is a dictionary for the error metrics ''' original_size = len(input_data) # Data load # Drop houses which are not flats # NOTE: originally the encoding flat = 1, house = 2, office = 3 was used # that encoding was probably originated by an enumeration performed by numpy input_data = input_data[input_data["type"] == house_type] type_size = len(input_data) if (len(house_subtype) > 0): input_data = input_data[input_data["subType"] == house_subtype] subtype_size = len(input_data) T = len(input_data) # latitud y longitud tienen que ser números decimales (ojo con el formato idealista) lat = np.array(input_data["lat"], np.float) lgt = np.array(input_data["lng"], np.float) m2 = np.array(input_data["gross_size"], np.float) price = np.array(input_data["price"], np.float) rooms = np.array(input_data["rooms"], np.float) planta= np.array(input_data["planta"],np.float) dist=np.zeros((T,T)) for i in range(T): dist[i][i]=float('Inf') for j in range(i+1, T): dist[i][j]=dist[j][i]=terceroB_ML_banks.pos2dist(lat[i],lgt[i],lat[j],lgt[j]) ##ahora ordenamos la matriz por vecindades n_vecinos=min(T-1, 6) index_vecinos=dist.argsort(axis=1)[:,0:n_vecinos] ############################# SAMPLE ########################### Tr=round(0.75*T) #Muestra de entrenamiento priceTr=price[0:Tr] priceTs=price[Tr+1:T] # [JB] Only take into account the training samples for "planta" Splanta=np.sum(planta[0:Tr]) ############################ MEDIANAS ########################### #obtengo la mediana de los seis vecinos medianvec=np.median(price[index_vecinos], axis=1) #genero las variables en desviaciones con sus medianas desvm2=m2-np.median(m2[index_vecinos], axis=1) desvroom=rooms-np.median(rooms[index_vecinos], axis=1) if Splanta > 0: desvplanta=planta-np.median(planta[index_vecinos], axis=1) else: desvplanta=0 ########################################################################### # Base models ########################################################################### #genero la primera matriz de regresores donde utilizamos la mediana de los #seis vecinos las variables hedonicas y sus interacciones REG_1=np.column_stack(( medianvec,m2,rooms, medianvec*m2, medianvec*rooms, m2*rooms)) # estimo los parámetros param_1=np.transpose(sm.OLS(priceTr,REG_1[:Tr,:]).fit().params) priceEstAll_1=np.dot(REG_1,param_1) # compruebo la bondad de los modelos errorpc_1=np.median(abs(priceTs-priceEstAll_1[Tr+1:T])/priceTs) # initialize with Inf errorpc_1p=float('Inf') if Splanta > 0: REG_1p=np.column_stack(( medianvec,m2,rooms,planta, medianvec*m2, medianvec*rooms, medianvec*planta, m2*rooms, m2*planta, rooms*planta)) # estimo los parámetros param_1p=np.transpose(sm.OLS(priceTr,REG_1p[:Tr,:]).fit().params) priceEstAll_1p=np.dot(REG_1p,param_1p) # compruebo la bondad de los modelos errorpc_1p=np.median(abs(priceTs-priceEstAll_1p[Tr+1:T])/priceTs) ########################################################################### # Adjusted models ########################################################################### # para los siguientes modelos, tengo que trabajar con los datos desvm2plus=np.zeros((T)) desvm2min=np.zeros((T)) desvroomplus=np.zeros((T)) desvroommin=np.zeros((T)) if Splanta > 0: desvplantaplus=np.zeros((T)) desvplantamin=np.zeros((T)) # genero las variables que miden asimetrias positivas frente a negativas for i in range(T): if desvm2[i]>0: desvm2plus[i]=desvm2[i] if desvm2[i]<0: desvm2min[i]=desvm2[i] if desvroom[i]>0: desvroomplus[i]=desvroom[i] if desvroom[i]<0: desvroommin[i]=desvroom[i] if (Splanta > 0 and desvplanta[i]>0): desvplantaplus[i]=desvplanta[i] if (Splanta > 0 and desvplanta[i]<0): desvplantamin[i]=desvplanta[i] ####utilizo como regresores la previsión del modelo 1 y las desviaciones REG_2=np.column_stack(( priceEstAll_1, desvm2plus,desvm2min, desvroomplus,desvroommin)) param_2=np.transpose(sm.OLS(priceTr,REG_2[:Tr,:]).fit().params) priceEstTs_2=np.dot(REG_2[Tr+1:T,:],param_2) # compruebo la bondad de los modelos errorpc_2=np.median(abs(priceTs-priceEstTs_2)/priceTs) # initialize with Inf errorpc_2p=float('Inf') if Splanta > 0: REG_2p=np.column_stack(( priceEstAll_1p, desvm2plus,desvm2min, desvroomplus,desvroommin, desvplantaplus,desvplantamin)) param_2p=np.transpose(sm.OLS(priceTr,REG_2p[:Tr,:]).fit().params) priceTsEstTs_2p=np.dot(REG_2p[Tr+1:T,:],param_2p) # compruebo la bondad de los modelos errorpc_2p=np.median(abs(priceTs-priceTsEstTs_2p)/priceTs) ########################################################################### # Build the return value, which is a pair of dictionaries: ########################################################################### #ordeno los errores de menor a mayor index_err=np.array([errorpc_1,errorpc_1p,errorpc_2,errorpc_2p]).argsort() # the first one is a dictionary for the output model if Splanta > 0: model_dict = {"param_1" : param_1.tolist(), "param_1p": param_1p.tolist(), "param_2" : param_2.tolist(), "param_2p": param_2p.tolist(), "index_err": index_err.tolist()} else: model_dict = {"param_1" : param_1.tolist(), "param_1p": [], "param_2" : param_2.tolist(), "param_2p": [], "index_err": index_err.tolist()} # the second one is a dictionary for the error metrics metrics_dict = {"errorpc_1" : errorpc_1, "errorpc_1p" : errorpc_1p, "errorpc_2" : errorpc_2, "errorpc_2p" : errorpc_2p, "size" : original_size, "type" : type_size, "subt" : subtype_size, "train" : Tr, "test" : (T-Tr)} return (model_dict, metrics_dict)