def evaluate_explorer(datos, ponderaciones, silencios, vecindario=False, carga=1): ''' Deuvelve la tasa de acierto y con que clasificador se ha obtenido para una configuracion de pesos y grados. Si vecindario == True, evalua tambien el vecindario de la solucion Devuelve - (tasa de acierto, clasificador) ''' if vecindario: resultado = evaluate(datos, ponderaciones, silencios, carga_computacional=carga) #Evaluate neighbourhood pesos1, pesos2, silencios2 = generar_nuevos(ponderaciones, silencios, list(cl.filter_numerical(datos))) sil1 = evaluate_explorer(datos, pesos1, silencios, False, carga) sil2 = evaluate_explorer(datos, pesos2, silencios,False, carga) sil3 = evaluate_explorer(datos, silencios2[1], silencios2[0], False, carga) vecindario_res = [sil1, sil2, sil3] return resultado, vecindario_res else: return evaluate(datos, ponderaciones, silencios, carga_computacional=carga)
def evaluate(datos, ponderaciones, silencios, carga_computacional=1,tipo_clustering="KMEANS", ncluster = 3, metrica = "SIL"): ''' Dado un clasificador y un conjunto de train y test devuelve su tasa de acierto en test. ''' global light_segs fecha = False if len(ponderaciones) == 0: return 0.0 ligero = np.sign(carga_computacional) < 0 carga_computacional = abs(carga_computacional) if carga_computacional < 1: datos = datos.sample(int(datos.shape[0] * carga_computacional)) datos = datos.sort_index() carga_computacional = 1 fecha = True if carga_computacional>=1: if not ligero: segmentos, _ = sg.segmentate_data_frame(df=datos, montecarlo=1, min_size=4, silence=silencios, vector_importancias=ponderaciones, verbose=False) mean = len(sg.ultra_light_segmentation(datos, fecha=fecha))/2 else: if len(light_segs) == 0: light_segs = sg.ultra_light_segmentation(datos, fecha=fecha) segmentos = light_segs mean = len(segmentos)/2 #mean = int(datos.shape[0]/100) if carga_computacional == 1: segmentados = cl.apply_segmentation(datos, segmentos, silencios, ponderaciones, fecha) if segmentados.shape[0] <= 6: return 0.0 else: std = np.sqrt(mean) nsegs=[] for i in range(segmentados.shape[0]): nsegs.append([i,i+1]) segmentos = sg.join_segments(data=segmentados, o_segments=nsegs, distance=sg.interpretable_distance, threshold=0.5, minimum_size=1,silence=silencios, vector_importancias=ponderaciones)[0] segmentados = cl.apply_segmentation(segmentados, segmentos, silencios, ponderaciones, fecha) return cl.hopkins_statistic(cl.filter_numerical(segmentados),m=int(segmentados.shape[0]*0.5))* normal_correction(mean, std, len(segmentados)) elif carga_computacional==2: if tipo_clustering == "DTW": segmentados = sg.get_segments(datos, segmentos) asignaciones = pam.kmedoids(segmentados, n_clus = ncluster) segments_df = cl.apply_clustering(datos, segmentos, asignaciones[1], asignaciones[2]) elif tipo_clustering == "KMEANS": segments_df = cl.full_clustering(datos, segmentos, n_clus = ncluster, silencio=silencios, pesos = ponderaciones, normalizar=False) if metrica == "SIL": return cl.sil_metric(segments_df[0]) elif metrica == "ENTROPY": return entropy_metric(segments_df)
def nueva_ronda(datos_originales, pesos, silencios, carga=1): ''' Genera nuevos exploradores y devuelve la mejor tasa de acierto encontrada, con sus correspondientes pesos y grados. Tambien actualiza el conteo de clasificadores en caso de querer inhibir los que peor funcionen. Devuelve - (Tasa de acierto, pesos, grados, mejor) ''' if len(silencios) > 0: pesos1, pesos2, silencios2 = generar_nuevos(pesos, silencios, list(cl.filter_numerical(datos_originales))) #Se generan los vecinos else: pesos1, pesos2, silencios2 = generar_nuevos(pesos, [], list(cl.filter_numerical(datos_originales))) #Se generan los vecinos #Se evaluan los exploradores sil1, vec1 = evaluate_explorer(datos_originales, pesos1, silencios, True, carga) sil2, vec2 = evaluate_explorer(datos_originales, pesos2, silencios, True, carga) if len(silencios2[1]) > 0: sil3, vec3 = evaluate_explorer(datos_originales, silencios2[1], silencios2[0], True, carga) #Nos quedamos con la mejor solucion encontrada y el mejor vecindario encontrado. mayor = np.argmax([sil1, sil2, sil3]) else: mayor = np.argmax([sil1, sil2]) if mayor == 2: solucion = [sil3, pesos, silencios2] elif mayor == 1: solucion = [sil2, pesos2, silencios] else: solucion = [sil1, pesos1, silencios] vec_sol1 = [vec1, pesos1, silencios] vec_sol2 = [vec2, pesos2, silencios] if len(silencios2[1]) > 0: vec_sol3 = [vec3, pesos, silencios2] vecs = [vec_sol1, vec_sol2, vec_sol3] else: vecs = [vec_sol1, vec_sol2] solucion.append(vecs) return solucion
def biplot(X, color='cluster'): ''' Prints a biplot with ggplot. Requires color variable: "cluster" in the dataframe. ''' pca = PCA(n_components=2) res = pca.fit_transform(filter_numerical(X)) df = pandas.DataFrame(res) df.columns = ["x", "y"] if color == 'cluster': df['Cluster'] = X[color].values color = 'Cluster' else: c = X[color].values c[c=="1"] = "Normal" c[c=="-1"] = "Anomalia" df['Detectado como:'] = c color = 'Detectado como:' return ggplot(aes("x","y", color=color),df) + geom_point(aes(size=40))
def conjunto_segmentados(segmentados, n=3): import pandas as pd segments_df = pd.DataFrame() lens = [] inicio = 0 for conj in segmentados: segments_df = segments_df.append(conj) lens.append([inicio, conj.shape[0]]) inicio = conj.shape[0] fit = clustering(segments_df, n) segments_df['cluster'] = fit.labels_ segments_df['cluster'] = segments_df['cluster'].astype(str) for x in range(len(lens)): segmentados[x] = segments_df.iloc[lens[x]] confidences = [] for i in range(n): confidences.append( extremos_incertidumbre(fit, filter_numerical(segments_df), i)) return segmentados, fit, confidences, segments_df
def simple_run(data, epochs = 30, reinicio = "random", silencios=["maximo","minimo","var"], carga=1): ''' Realiza el proceso de optimizacion de unos datos etiquetados. epochs - numero de veces a ejecutar el proceso de busqueda. reinicio - politica de reinios si no se encuentra nada mejor en x epochs: -O bien se vuelve a un estado aleatorio. -O bien se vuelve al principio. ''' global heap_vecinos,nombres #Se inician las variables de la solucion basica. rows, cols = cl.filter_numerical(data).shape nombres = list(cl.filter_numerical(data)) pesos = [1] * (cols - (len(silencios)*2)) iters_sin_mejora = 0 #Se inicia la barra de progreso. bar = progressbar.ProgressBar() bar.max_value = epochs bar.min_value = 0 bar.update(0) #Se calcula la solucion basica. mejor_tasa_de_acierto = evaluate_explorer(data, pesos, silencios, carga=carga) pesos_actuales = pesos grados_actuales = silencios grados = silencios #Se inicia el algoritmo for i in range(epochs): #Se evalua la solucion actual junto con sus vecindarios tasa_de_acierto, pesos_nuevos, grados_nuevos, vecindarios = nueva_ronda(data, pesos_actuales, grados_actuales,carga=carga) #Se anyaden los vecindarios al monticulo. add_vecindarios(vecindarios) #Si se mejora la solucion actual, se guarda if tasa_de_acierto > mejor_tasa_de_acierto: pesos = pesos_nuevos grados = grados_nuevos mejor_tasa_de_acierto = tasa_de_acierto iters_sin_mejora = 0 else: #Si no, se anota. iters_sin_mejora += 1 if iters_sin_mejora == 10: heap_vecinos = [] #Se reinicia de acuerdo a la politica de reinicio (solucion basica o aleatoria) if reinicio == "random": pesos_actuales = np.random.randint(low=0, high=10, size=len(pesos)) pesos_actuales = pesos_actuales / 10.0 elif reinicio == "ones": pesos_actuales = [1] * len(pesos) grados_actuales = [1] * (cols -1) #Si el monticulo no esta vacio, se coge el sujeto con mejor vecindario hasta ahora. if len(heap_vecinos)>0: vecino = get_best_vecindario() pesos_actuales = vecino[1][0] grados_actuales = vecino[1][1] if len(grados_actuales) == 2 and isinstance(grados_actuales[0], list): pesos_actuales = grados_actuales[1] grados_actuales = grados_actuales[0] else: print("Se acaba por monticulo vacio") break #Se actualiza la barra de progreso. bar.update(i) #Se finaliza bar.finish() #Se vacia el heap (por si se quiere volver a ejecutar el algoritmo) heap_vecinos = [] #Pequeno informe de como ha ido la ejecucion print("Reinicios %d" % (iters_sin_mejora / 5), "Epochs sin mejora: %d" % iters_sin_mejora, "(%d%%)" % int((100*(iters_sin_mejora*1.0) / epochs))) return mejor_tasa_de_acierto, pesos, grados
def anomaly_detection(X, name='anomaly'): pr = IsolationForest() pr.fit(filter_numerical(X)) x = pr.predict(filter_numerical(X)) X[name] = x X[name] = X[name].astype(str)