def default_params_forecasts(model): ''' Our baseline: forecasts with default SWAN params ''' closest_params = model.closest_params( params=SWANParams(drf=1.0, cfw=0.015, stpm=0.00302)) default_params = SWANParams(drf=closest_params[0], cfw=closest_params[1], stpm=closest_params[2]) drf_idx, cfw_idx, stpm_idx, fid_time_idx, fid_space_idx = model.params_idxs( default_params) forecasts = model.grid[drf_idx, cfw_idx, stpm_idx, fid_time_idx, fid_space_idx] return forecasts
def save_archive_history(history, file_name='history.csv'): test_model = model_all_stations() with open(file_name, 'w', newline='') as csvfile: fieldnames = ['idx', 'gen_idx'] + [f'err_{idx + 1}' for idx in range(len(ALL_STATIONS))] \ + ['drf', 'stpm', 'cfw'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() for gen_idx, gen in enumerate(history): for ind_idx, ind in enumerate(gen): row_to_write = {} idx = gen_idx * len(gen) + ind_idx row_to_write['idx'] = idx row_to_write['gen_idx'] = gen_idx params = test_model.closest_params(ind.genotype) closest_params = SWANParams(drf=params[0], cfw=params[1], stpm=params[2], fidelity_time=params[3], fidelity_space=params[4]) # TODO: bug here metrics = test_model.output(params=closest_params) for err_idx, err_value in enumerate(metrics): row_to_write[f'err_{err_idx + 1}'] = err_value row_to_write['drf'] = ind.genotype.drf row_to_write['stpm'] = ind.genotype.stpm row_to_write['cfw'] = ind.genotype.cfw writer.writerow(row_to_write)
def error_grid(noise_case=0): grid = CSVGridFile('../../samples/wind-exp-params-new.csv') stations = [1, 2, 3, 4, 5, 6, 7, 8, 9] ww3_obs_all = \ [obs.time_series() for obs in wave_watch_results(path_to_results='../../samples/ww-res/', stations=stations)] model_all = FidelityFakeModel(grid_file=grid, observations=ww3_obs_all, stations_to_out=stations, error=error_rmse_all, forecasts_path='../../../wind-postproc/out') with open(f'../../samples/params_rmse_{noise_case}.csv', mode='w', newline='') as csv_file: writer = csv.writer(csv_file, delimiter=',') header = ['DRF', 'CFW', 'STPM'] error_columns = [f'ERROR_K{station}' for station in stations] header.extend(error_columns) writer.writerow(header) fidelity = 240 for row in grid.rows: metrics = model_all.output( params=SWANParams(drf=row.model_params.drf, cfw=row.model_params.cfw, stpm=row.model_params.stpm, fidelity_time=fidelity)) row_to_write = row.model_params.params_list() row_to_write.extend(metrics) writer.writerow(row_to_write)
def train(self, mode='lhs', **kwargs): target = [] if mode is 'lhs': for feature in self.features: params = SWANParams(drf=feature[0], cfw=feature[1], stpm=feature[2], fidelity_time=self.fidelity[0], fidelity_space=self.fidelity[1]) target.append( self.fake_model.output_from_model( params=params)[self.station]) target = np.asarray(target) start_time = datetime.now().strftime(DATE_FORMAT) print( f'{start_time}: starting to train kriging model ' f'with {self.points_to_train} points for station: {self.station}') krig = kriging(self.features, target, name='multikrieg') krig.train(optimizer='ga') self.krig = krig end_time = datetime.now().strftime(DATE_FORMAT) print(f'{end_time}: finished to train kriging model with' f' {self.points_to_train} points for station: {self.station}')
def run_genetic_opt(max_gens, pop_size, archive_size, crossover_rate, mutation_rate, mutation_value_rate, stations, **kwargs): grid = CSVGridFile('../../samples/wind-exp-params-new.csv') ww3_obs = \ [obs.time_series() for obs in wave_watch_results(path_to_results='../../samples/ww-res/', stations=stations)] train_model = FidelityFakeModel(grid_file=grid, observations=ww3_obs, stations_to_out=stations, error=error_rmse_all, forecasts_path='../../../wind-fidelity/*') test_range = (0, 1) test_model = model_all_stations(forecasts_range=test_range) operators = default_operators() history, archive_history = DefaultSPEA2( params=DefaultSPEA2.Params(max_gens=max_gens, pop_size=pop_size, archive_size=archive_size, crossover_rate=crossover_rate, mutation_rate=mutation_rate, mutation_value_rate=mutation_value_rate), objectives=partial(calculate_objectives_interp, train_model), evolutionary_operators=operators).solution(verbose=False) exptime2 = str(datetime.datetime.now().time()).replace(":", "-") # save_archive_history(archive_history, f'rob-exp-bl-{exptime2}.csv') params = history.last().genotype if 'save_figures' in kwargs and kwargs['save_figures'] is True: params = test_model.closest_params(params) closest_params = SWANParams(drf=params[0], cfw=params[1], stpm=params[2], fidelity_time=params[3], fidelity_space=params[4]) drf_idx, cfw_idx, stpm_idx, fid_time_idx, fid_space_idx = test_model.params_idxs( closest_params) forecasts = test_model.grid[drf_idx, cfw_idx, stpm_idx, fid_time_idx, fid_space_idx] plot_results(forecasts=forecasts, observations=wave_watch_results( path_to_results='../../samples/ww-res/', stations=ALL_STATIONS), baseline=default_params_forecasts(test_model), save=True, file_path=kwargs['figure_path'], values_range=test_range) return history.last()
def _fixed_params(self, params): params_fixed = SWANParams( drf=min(max(params.drf, min(self.grid_file.drf_grid)), max(self.grid_file.drf_grid)), cfw=min(max(params.cfw, min(self.grid_file.cfw_grid)), max(self.grid_file.cfw_grid)), stpm=min(max(params.stpm, min(self.grid_file.stpm_grid)), max(self.grid_file.stpm_grid)), fidelity_time=params.fid_time, fidelity_space=params.fid_space) return params_fixed
def crossover(p1, p2, rate): if random.random() >= rate: return p1 part1_rate = abs(random.random()) part2_rate = 1 - part1_rate child_params = SWANParams( drf=abs(p1.drf * part1_rate + p2.drf * part2_rate), cfw=abs(p1.cfw * part1_rate + p2.cfw * part2_rate), stpm=abs(p1.stpm * part1_rate + p2.stpm * part2_rate)) return child_params
def params_and_error_grid(model, station_index, stpm_index): drf, cfw = np.meshgrid(model.grid_file.drf_grid, model.grid_file.cfw_grid) stpm_fixed = model.grid_file.stpm_grid[stpm_index] error = np.ones(shape=drf.shape) for i in range(drf.shape[0]): for j in range(drf.shape[1]): out_by_stations = model.output(params=SWANParams( drf=drf[i, j], cfw=cfw[i, j], stpm=stpm_fixed)) error[i, j] = out_by_stations[station_index] return drf, cfw, error
def default_points_by_fidelity(size=10): points_by_fidelity = {} for fidelity in fidelity_combinations(): points = [] for _ in range(size): params = SWANParams.new_instance() params.fid_time = fidelity[0] params.fid_space = fidelity[1] points.append(params) points_by_fidelity[fidelity] = points return points_by_fidelity
def retrain_with_new_points(self, new_points): extended_features = self.features.tolist() for point in new_points: extended_features.append([point.drf, point.cfw, point.stpm]) params = SWANParams(drf=point.drf, cfw=point.cfw, stpm=point.stpm, fidelity_time=self.fidelity[0], fidelity_space=self.fidelity[1]) print(self.fake_model.output_from_model(params=params)[0]) self.points_to_train += len(new_points) print(f'retrain with new {len(new_points)} features') self.features = np.asarray(extended_features) self.train()
def initial_pop_lhs(size, **kwargs): samples_grid = lhs(PARAMS, size, 'center') for idx, params_range in enumerate([drf_range, cfw_range, stpm_range]): samples_grid[:, idx] = norm(loc=np.mean(params_range), scale=np.std(params_range)).ppf( samples_grid[:, idx]) population = [ SWANParams(drf=sample[0], cfw=sample[1], stpm=sample[2]) for sample in samples_grid ] # population = [SWANParams(drf=1.0, cfw=0.015, stpm=0.00302) for sample in samples_grid] if 'dump' in kwargs and kwargs['dump'] is True: dump_population(population, kwargs['file_path']) return population
def plot_params_space(): grid = CSVGridFile('../../samples/wind-exp-params.csv') forecasts_path = '../../../samples/wind-noice-runs/results/1/' fake = FidelityFakeModel(grid_file=grid, forecasts_path=forecasts_path) drf, cfw = np.meshgrid(fake.grid_file.drf_grid, fake.grid_file.cfw_grid) stpm_fixed = fake.grid_file.stpm_grid[0] stations = 3 error = np.ones(shape=(stations, drf.shape[0], drf.shape[1])) for i in range(drf.shape[0]): for j in range(drf.shape[1]): diff = fake.output(params=SWANParams( drf=drf[i, j], cfw=cfw[i, j], stpm=stpm_fixed)) for station in range(stations): error[station, i, j] = diff[station]
def optimize_test(train_stations, max_gens, pop_size, archive_size, crossover_rate, mutation_rate, mutation_value_rate, sur_points, plot_figures=True): train_range = (0, 1) test_range = (0, 1) grid = CSVGridFile('../../samples/wind-exp-params-new.csv') ww3_obs = \ [obs.time_series() for obs in wave_watch_results(path_to_results='../../samples/ww-res/', stations=train_stations)] error = error_rmse_all train_model = FidelityFakeModel(grid_file=grid, observations=ww3_obs, stations_to_out=train_stations, error=error, forecasts_path='../../../2fidelity/*', forecasts_range=train_range, is_surrogate=True, sur_points=sur_points) operators = default_operators() history, archive_history = DefaultSPEA2( params=DefaultSPEA2.Params(max_gens, pop_size=pop_size, archive_size=archive_size, crossover_rate=crossover_rate, mutation_rate=mutation_rate, mutation_value_rate=mutation_value_rate), objectives=partial(calculate_objectives_interp, train_model), evolutionary_operators=operators).solution(verbose=True) params = history.last().genotype if plot_figures: test_model = model_all_stations(forecasts_range=test_range) params = test_model.closest_params(params) closest_params = SWANParams(drf=params[0], cfw=params[1], stpm=params[2], fidelity_time=params[3], fidelity_space=params[4]) drf_idx, cfw_idx, stpm_idx, fid_time_idx, fid_space_idx = test_model.params_idxs( closest_params) forecasts = test_model.grid[drf_idx, cfw_idx, stpm_idx, fid_time_idx, fid_space_idx] plot_results(forecasts=forecasts, observations=wave_watch_results( path_to_results='../../samples/ww-res/', stations=ALL_STATIONS), baseline=default_params_forecasts(test_model)) plot_population_movement(archive_history, grid) return history.last().error_value
def reference_metrics(): return all_error_metrics(params=SWANParams(drf=1.0, cfw=0.015, stpm=0.00302), models_to_tests=init_models_to_tests())
def default_initial_pop(size): return [SWANParams.new_instance() for _ in range(size)]
def _swan_params(cls, csv_row): return SWANParams(drf=float(csv_row['DRF']), cfw=float(csv_row['CFW']), stpm=float(csv_row['STPM']))
def _init_grids(self): self.grid = self._empty_grid() files = forecast_files_from_dir(self.forecasts_path) if not files: raise FileNotFoundError("EMPTY FORECAST") stations = files_by_stations( files, noise_run=self.noise_run, stations=[str(st) for st in self.stations]) files_by_run_idx = dict() for station in stations: for file in station: _, name = os.path.split(file) _, _, run_idx = extracted_forecast_params(file_name=name) files_by_run_idx[file] = run_idx for row in self.grid_file.rows: run_idx = row.id forecasts_files = sorted([ key for key in files_by_run_idx.keys() if files_by_run_idx[key] == run_idx ]) files_by_fidelity = self._files_by_fidelity(forecasts_files) for fidelity in files_by_fidelity: files = files_by_fidelity[fidelity] forecasts = [] for idx, file_name in enumerate(files): forecasts.append( FidelityFakeModel.Forecast( self.stations[idx], ForecastFile(path=file_name), range_values=self.forecasts_range)) fid_time, fid_space = fidelity drf_idx, cfw_idx, stpm_idx, fid_time_idx, fid_space_idx = self.params_idxs( params=SWANParams(drf=row.model_params.drf, cfw=row.model_params.cfw, stpm=row.model_params.stpm, fidelity_time=fid_time, fidelity_space=fid_space)) self.grid[drf_idx, cfw_idx, stpm_idx, fid_time_idx, fid_space_idx] = forecasts # empty array self.err_grid = np.zeros(shape=self.grid.shape + (len(stations), )) # calc fitness for every point st_set_id = ("-".join(str(self.stations))) file_path = f'grid-saved-{self.error.__name__}_range_{self.forecasts_range}_st{st_set_id}.pik' grid_file_path = os.path.join(GRID_PATH, file_path) if not os.path.isfile(grid_file_path): grid_idxs = self.__grid_idxs() for i, j, k, m, n in grid_idxs: forecasts = [forecast for forecast in self.grid[i, j, k, m, n]] for forecast, observation in zip(forecasts, self.observations): station_idx = forecasts.index(forecast) obs_in_range = observations_from_range( observation, self.forecasts_range) self.err_grid[i, j, k, m, n, station_idx] = self.error( forecast, obs_in_range) pickle_out = open(grid_file_path, 'wb') pickle.dump(self.err_grid, pickle_out) pickle_out.close() print(f"FITNESS GRID SAVED, file_name: {grid_file_path}") else: with open(grid_file_path, 'rb') as f: self.err_grid = pickle.load(f)