def applyClusteringPartial(L_predict,features,L_train,dicDBvariables,dicAlarmsClusTotal,score,procID): # EL objetivo de este procedimiento es aplicar un número de veces (según la variable proofGroup) el algoritmo de clustering # Gaussian Mixture Models (GMM) aumentanto en cada una de las iteraciones el número de grupos a obtener (2^x). En cada iteración se obtendrá # el grupo al que pertence cada una de las muestras del array a predecir (L_predict) # Se aplicará por columna (column) log.info(procID+" <applyClusteringPartial> Features: "+str(features)) percentSizeTrain=(len(L_train)*100)/(len(L_train)+len(L_predict)) # Antes de dividir tenemos que calcular el % del tamaño del test_size # perCsplit=(percentSizeTrain-int(dicDBvariables["test_size"]))/100 # EJ: 91% - 80% = 11% / 100 --> 0.11 del array a usar como test y 0.89 para train # haciendo justo el 80% (definido por la variable) log.debug(procID+" <applyClusteringPartial> test_size= "+str(perCsplit)) X_train, X_test, y_train, y_test =train_test_split(L_train, L_train, test_size=perCsplit,random_state=33) log.debug(procID+" <applyClusteringPartial> X_train size: before= "+str(len(L_train))+" | now= "+str(len(X_train))) for col in range(len(features)): dicAlarmsClus={} nComp=2 dicResultClusSample={} dicResultClusGroup={} L_1colTR, L_restColTR = usefulLibrary.extractColumnArray(L_train,col,procID) L_1colPR, L_restColPR = usefulLibrary.extractColumnArray(L_predict,col,procID) for proof in range(int(dicDBvariables['proofGroup'])): log.info(procID+" <applyClusteringPartial> Proof level:"+str(proof)+" - n_components: "+str(nComp)+" - COLUMN= "+str(col)) gm = mixture.GMM(n_components=nComp,covariance_type='tied', random_state=42) gm.fit(L_1colTR) y_pred = gm.predict(L_1colPR) usefulLibrary.saveResult(y_pred,dicResultClusSample,dicResultClusGroup,'I'+str(proof),procID) nComp=nComp*2 log.debug(dicResultClusSample) log.debug(dicResultClusGroup) usefulLibrary.applyClusteringAlarm(dicResultClusSample,dicResultClusGroup,dicAlarmsClus,dicDBvariables['clustGroup'],procID) dicAlarmsClusTotal[col]=dicAlarmsClus for alarm in sorted(dicAlarmsClus.keys()): log.info(procID+" <applyClusteringPartial> COLUMN= "+str(col)+" Value:"+str(L_predict[alarm][col])+" - level: "+str(dicAlarmsClus[alarm]))
def applyRegression(dicWrongValues,L2,dicL,L_train,coefVaration,dicAlarmsRegr,score,testSize,analysis,procID): # Esta función tiene como objetivo: # 1º. Sustituir los "wrong" values de la lista L2 por valores predecidos según el resto de características. # NOTA: cuidado cuando existan mas de una característica "wrong" para la misma muestra. # 2º. Validar uno a uno cada valor de la lista L2, es decir, comprobar que el valor real es el "mismo" que obtenemos al predecirlo. En # el caso de que no sea (sea lo suficientemente diferente) generará una alarma. # # Lo idóneo es unir el array sacado de la BD con el del data set a analizar (quitando las muestras cuyas coordenadas tienen valore raro), # y ya con esta lista dividir la en train y test, esto es válido solo para el PASO 1 # NOTA: se podría definir una variable "regressionMinScore" para sólo aplicar la regresión en caso de que el score sea mayor a este valor. features=[] for col in sorted(dicL.keys()): features.append(dicL[col]) feature_names = np.array(features) log.info(procID+" <applyRegression> Features: "+str(feature_names)) if (len(dicWrongValues.keys())>0): L_full = usefulLibrary.unionListsWrong(dicWrongValues,L2,L_train,procID) # L_full contiene un array de la unión del array de # entrenamiento mas el del fichero sin los valores a 0 que tenían strings log.info(procID+" <applyRegression> Num columns L_full: "+str(len(L_full[0]))) # Toca recorrer el array: PASO 1 --> en busca de los "0" que hemos puesto en los valores malos # - la forma de recorrer esta vez no será registro a registro, lo haremos por columna ya que a la hora de aplicar el algoritmo # Sólo podremos aplicar la regresión lineal si se cumple que el tamaño del array L_full es: # 1. Mayor que el valor definido por la variable test_size # 2. Si es mayor lo divideremos hasta tener un array con el valor justo de "test_size", cogiendo muestras aleatorias percentSizeTrain=(len(L_full)*100)/(len(L_full)+len(dicWrongValues.keys())) if int(percentSizeTrain) >= int(testSize): log.info(procID+" <applyRegression> STEP 1: Train array is upper to test_size "+str(testSize)+", the Lineal Regression will be executed.") analysis=True values_X, values_Y = [], [] columns=[] for wrong in sorted(dicWrongValues.keys()): log.info(procID+" <applyRegression> WrongDict key= "+str(wrong)) if dicWrongValues[wrong]["y"] not in columns: columns.append(dicWrongValues[wrong]["y"]) log.info(procID+" <applyRegression> Num columns of wrong values= "+str(len(columns))) for col in columns: log.info(procID+" <applyRegression> Col= "+str(col)) values_Y, values_X = usefulLibrary.extractColumnArray(L_full,col,procID) log.info(procID+" <applyRegression> Num rows values_Y: "+str(len(values_Y))) log.info(procID+" <applyRegression> "+str(values_Y)) log.info(procID+" <applyRegression> Num columns values_X: "+str(len(values_X[0]))) values_X = np.array(values_X) values_Y = np.array(values_Y) # Antes de dividir tenemos que calcular el % del tamaño del test_size # perCsplit=(percentSizeTrain-int(testSize))/100 # EJ: 91% - 80% = 11% / 100 --> 0.11 del array a usar como test y 0.89 para train # haciendo justo el 80% (definido por la variable) log.info(procID+" <applyRegression> test_size= "+str(perCsplit)) X_train, X_test, y_train, y_test =train_test_split(values_X, values_Y, test_size=perCsplit,random_state=33) log.debug(procID+" <applyRegression> X_train size: before= "+str(len(values_X))+" | now= "+str(len(X_train))) # Create linear regression object regr = linear_model.LinearRegression() # Train the model using the training sets regr.fit(X_train, y_train) # Explained variance score: 1 is perfect prediction log.info(procID+" <applyRegression> Variance score: "+str(regr.score(X_test,y_test))) # Ahora tocaría estimar y sustituir for reg in dicWrongValues.keys(): x=dicWrongValues[reg]["x"] y=dicWrongValues[reg]["y"] if L2[x][y] == 0 and y == col: # nosotros le pusimos este valor, así nos aseguramosxº y_pred=regr.predict(usefulLibrary.extractColumnList(L2[x],y,procID)) log.info(procID+" <applyRegression> Value predict for wrong value in coordinates "+str(x)+","+str(y)+": "+str(y_pred)) aprox=round(y_pred,4) log.info(procID+" <applyRegression> Aproximate predict value: "+str(aprox)) # Ahora deberíamos sustituirlo en la Lista definitiva L2[x][y]=aprox else: log.info(procID+" <applyRegression> STEP1: Train array is lower to test_size "+str(testSize)+", the Lineal Regression will not be executed.") # Para el PASO 2 no podemos unir la lista sacada de la BD con la del fichero ya que vamos a ir prediciendo cada valore del array del # fichero y no podemos usar los valores que ya vienen en el. log.info(procID+" <applyRegression> Num columns L_train: "+str(len(L_train[0]))) percentSizeTrain=(len(L_train)*100)/(len(L_train)+len(L2)) if int(percentSizeTrain) >= int(testSize): log.info(procID+" <applyRegression> STEP 2: Train array is upper to test_size "+str(testSize)+", the Lineal Regression will be executed.") analysis=True values_X, values_Y = [], [] # Nos toca recorre todo el array del fichero prediciendo uno a uno cada valor, por columna for colum in range(len(feature_names)): log.info(procID+" <applyRegression> Predict values of Colum= "+str(colum)) values_Y, values_X = usefulLibrary.extractColumnArray(L_train,colum,procID) values_X = np.array(values_X) values_Y = np.array(values_Y) # Antes de dividir tenemos que calcular el % del tamaño del test_size # perCsplit=(percentSizeTrain-int(testSize))/100 # EJ: 91% - 80% = 11% / 100 --> 0.11 del array a usar como test y 0.89 para train # haciendo justo el 80% (definido por la variable) log.info(procID+" <applyRegression> test_size= "+str(perCsplit)) X_train, X_test, y_train, y_test =train_test_split(values_X, values_Y, test_size=perCsplit,random_state=33) log.debug(procID+" <applyRegression> X_train size: before= "+str(len(values_X))+" | now= "+str(len(X_train))) # Create linear regression object regr = linear_model.LinearRegression() # Train the model using the training sets regr.fit(X_train, y_train) # Explained variance score: 1 is perfect prediction score=regr.score(X_test,y_test) log.info(procID+" - Variance score: "+str(score)) # Una vez ya tenemos el estimador entrenado comenzamos a predecir for row in range(len(L2)): subDalarm={} newL = usefulLibrary.extractColumnList(L2[row],colum,procID) log.info(procID+" <applyRegression> List of features to predict: "+str(newL)) y_pred=regr.predict(newL) log.info(procID+" <applyRegression> Value predict for coordinates row,colum "+str(row)+","+str(colum)+" -> REAL: "+str(L2[row][colum])+" PRED: "+str(y_pred)) aprox=round(y_pred,4) log.info(procID+" <applyRegression> Aproximate predict value: "+str(aprox)) coefV = usefulLibrary.desviacionTipica(L2[row][colum],aprox,procID) if coefV > int(coefVaration): # Como el coeficiente de variación es mayor a lo permitido por variable generamos la alarma como posible anomalía subDalarm["x"]=row subDalarm["y"]=colum dicAlarmsRegr[len(dicAlarmsRegr.keys())]=subDalarm log.info(procID+" <applyRegression> Alarm generated...[coefV= "+str(coefV)+"]") else: # Como el coeficiente de variación es menor a lo permitido por variable, consideramos que tanto el valor real como el predecido # son semejantes por lo que no generaremos alarma log.info(procID+" <applyRegression> Element with value between interval...[coefV= "+str(coefV)+"]") else: log.info(procID+" <applyRegression> STEP2: Train array is lower to test_size "+str(testSize)+", the Lineal Regression will not be executed.")