def oneVarInterpolation(hp, pCentroids, pMeasure, optimisationIteration, lastMeasure, distrib, m, precisionCheck, structureCheck, var=None): ''' Use interpolation to estimate the optimal value of a randomly chosen variable. ''' # Note: tried applying the function recursively on its local minima, not a good idea # (lack of precision+infinite time) if var == None: i = np.random.random_integers(0, len(hp) - 1) j = np.random.random_integers(0, len(hp[0]) - 1) else: i = var[0] j = var[1] var = hp[i][j] x = [] y = [] for k in [ -30., -20., -10., -5., -2., -1.5, -1., -0.75, -0.5, 0.01, 0.25, 0.5, 0.75, 1., 1.5, 2., 3., 6., 10., 20., 30., 40., 50. ]: direction = hp direction[i][j] = var * k x.append(var * k) y.append(ms.measure(m, direction, pCentroids, pMeasure, distrib)) #take successive 4 x's to interpolate xmins = [] #np.zeros(0) ymins = [] #np.zeros(0) for k in range(len(x) - 3): xReduced = x[k:k + 4] yReduced = y[k:k + 4] fApprox = interp1d(xReduced, yReduced, kind='cubic') xnew = np.linspace(min(xReduced), max(xReduced), num=100, endpoint=True) ynew = fApprox(xnew) xmins.append(xnew[np.argmin(ynew)]) ymins.append(min(ynew)) smallestValues = [[xmins[l] for l in np.argpartition(ymins, 5)[:5]], [ymins[l] for l in np.argpartition(ymins, 5)[:5]]] smallestValuesMeasure = [] smallDirections = [] for smallX in smallestValues[0]: direction = hp direction[i][j] = smallX smallDirections.append(direction) smallestValuesMeasure.append( ms.measure(m, direction, pCentroids, pMeasure * 10, distrib)) n = np.argmin(smallestValuesMeasure) return smallDirections[n], smallestValuesMeasure[n]
def mseEstimations(numberOfEstimations,m="mse"): ''' estimations of MSE on the same set of points to visualise its variance ''' e=[] hp = init.normal(3,2) for k in range(numberOfEstimations): e.append(ms.measure(m,hp,1000,10000,'gaussian')) plt.figure(); plt.plot(e); plt.title('%d mse estimations')%numberOfEstimations; plt.show()
def updateHyperplanes(hp, pCentroids, pMeasure, optimisationIteration, lastMSE, updateFunction, distrib, m, precisionCheck, structureCheck): ''' Actually update the hyperplanes by selecting the lowest MSE between several directions. Only uses MSE as measure. ''' # generate directions to test if updateFunction == 'globalRandom': directions = directionsGlobalRandom(hp, 10 + 10 * optimisationIteration, optimisationIteration) elif updateFunction == 'varByVar': directions = directionsVarByVar(hp, 10 + 10 * optimisationIteration, optimisationIteration, distrib, pCentroids, structureCheck) elif updateFunction == 'indVarByVar': directions = directionsIndVarByVar(hp, 10 + 10 * optimisationIteration, optimisationIteration) # evaluate distortion if m == 'mse': directionsMeasure = ms.MSEforDirection(directions, pCentroids, pMeasure, distrib) elif m == 'entropy': print('il y a un probleme') # select the lowest MSE configuration indexMin = np.argmin(directionsMeasure) newMSE = ms.measure(m, directions[indexMin], pCentroids, pMeasure * 2, distrib) return checkPrecision(hp, pCentroids, pMeasure, optimisationIteration, distrib, m, directions, precisionCheck, newMSE, lastMSE, indexMin)
def poolSelect(nHyperplanes, nDimensions, pCentroids, pMeasure, poolSize, distrib, m, initType='doublePoint'): ''' Initialize hyperplanes by generating a pool of poolSize random configurations and selecting the one with lowest measure of distortion. ''' for k in range(poolSize): if initType == 'normal': hps = normal(nHyperplanes, nDimensions) elif initType == 'doublePoint': hps = doublePoint(nHyperplanes, nDimensions, distrib) else: print("ERROR! invalid initialization type") e = ms.measure(m, hps, pCentroids, pMeasure, distrib) if k < 1: minDistortion = e minConfig = hps else: if minDistortion >= e: minDistortion = e minConfig = hps return minConfig
def getMaxMeasureVariations(hp, pCentroids, pMeasure, distrib): ''' Returns the maximal variation of the Distortion measure given the parameters minus 50%, as an estimation of distortion function. ''' e = [] for k in range(40): e.append(ms.measure("mse", hp, pCentroids, pMeasure, distrib)) e = np.array(e) e = (e - np.mean(e))**2 return np.sqrt(np.max(e)) * 0.5
# Import from measures import measure measures = 5 print("aur:") sum = 0 for e in range(measures): sum += measure(2) print("avg:") print(sum/measures) print("aur+sent:") sum = 0 for e in range(measures): sum += measure(1) print(sum/measures) print("aur+sent+day_of_week:") sum = 0 for e in range(measures): sum += measure(0) print(sum/measures)
def genetic(nHyperplanes, nDimensions, pCentroids, pMeasureInit, distrib, m, nConfigs, pGenetic, crossover, mutation, order='dissimilarity', selection='rank', initType='doublePoint', mutationPercentage=50): ''' Generates a partially optimized configuration of hyperplanes, with the goal of having an approximatively equal repartition of the input distribution over the regions. Here one hyperplane = one gene. At every iteration, one half of the old configs is kept and used to generate the next generation by crossover. -nConfigs is the number of configurations to generate and cross -pGenetic is the number of iterations -order is the type of ordering used to order hyperplanes before crossover -crossover is the number of crossing points in the crossover operations -mutation is the mutation method and intensity -selection is the selection method used to chose the configs that are reproduced ''' print('start initialisation (genetic)') configs = [] measures = [] geneticMeasureEvolution = [] # Step 1: generate random configurations for k in range(nConfigs): if initType == 'normal': config = normal(nHyperplanes, nDimensions) elif initType == 'doublePoint': config = doublePoint(nHyperplanes, nDimensions, distrib) else: print("ERROR! invalid initialization type") configs.append(config) print('finished generating random configurations') for k in range(pGenetic): pMeasure = (k + 1) * pMeasureInit print('genetic: iteration ' + str(k + 1) + ' of ' + str(pGenetic)) measures = [ ms.measure(m, config, pCentroids, pMeasure, distrib) for config in configs ] geneticMeasureEvolution.append(np.min(measures)) # Step 2: selecting configs to reproduce configs, measures = select(selection, configs, measures, percentageToKeep=80) # Step 3: crossing configurations newConfigs = cross(nDimensions, distrib, crossover, copy.deepcopy(configs), order, outputSize=nConfigs) configs = np.concatenate((configs, newConfigs), axis=0) # Step 4: mutation if mutationPercentage == 100: configs = mutateAll(mutation, configs) else: measures = [ ms.measure(m, config, pCentroids, pMeasure, distrib) for config in configs ] configs = mutate(mutation, configs, measures, mutationPercentage) # Step 5: return the best config measures = [ ms.measure(m, config, pCentroids, pMeasure, distrib) for config in configs ] print('final: ', np.min(measures)) print('end initialisation') return configs[np.argmin(measures)], geneticMeasureEvolution
def optimisation(hp, pCentroids, pMeasure, pOptimisation, visualisation=[False, False, 10], wTitle='', distrib='gaussian', m='mse', updateMethod='random directions', precisionCheck=False, structureCheck=False): ''' Uses an update function to update the hyperplanes hp, with pCentroids and pMeasure as parametersof the functions centroids() and measure() pOptimisation: number of iterations visualisation = [bool visualiseInitial, bool visualiseSteps, int stepsInterval] wTitle: the title used for visualisation distrib: the random distribution studied updateMethod: the method to use If precisionCheck, it is checked wether or not the new config generated is better than the previous one. If structureCheck, it is checked wether or not the structure of the new config (hyperplanes intersections, regions) is different from the previous one. ''' measureEvolution = [ms.measure(m, hp, pCentroids, pMeasure, distrib)] saveHyperplanes = [hp] if visualisation[0]: visu.visualiseHyperplanes( hp, wTitle + ', iteration= %d, error= %f' % (0, measureEvolution[-1]), 5, distrib) # optimization steps for k in range(1, pOptimisation + 1): print('optimisation function: iteration', k, 'of', pOptimisation) u = update.choseUpdateFunction(updateMethod, k) if u == 'oneVarInterpolation': for i in range(len(hp)): for j in range(len(hp[i])): hp, newMeasure = update.oneVarInterpolation( hp, pCentroids, pMeasure * k, k, measureEvolution[-1], distrib, m, precisionCheck, structureCheck, var=[i, j]) elif u == 'indVarByVar': for i in range(len(hp)): for j in range(len(hp[i])): hp, newMeasure = update.updateHyperplanes( hp, pCentroids, pMeasure * k, k, measureEvolution[-1], u, distrib, m, precisionCheck, structureCheck, var=[i, j]) else: hp, newMeasure = update.updateHyperplanes( hp, pCentroids, pMeasure * k, k, measureEvolution[-1], u, distrib, m, precisionCheck, structureCheck) measureEvolution.append(newMeasure) saveHyperplanes.append(copy.deepcopy(hp)) # display result if (k % visualisation[2] == 0) and visualisation[1]: visu.visualiseHyperplanes( hp, wTitle + ', iteration= %d, error= %f' % (k, measureEvolution[-1]), 5, distrib) print('measureEvolution[-1]', measureEvolution[-1]) return measureEvolution, saveHyperplanes