# Statistical tests for Time Series - Using Climatic Data for COVID-19 analysis

```python
import warnings                                  # do not disturbe mode
warnings.filterwarnings('ignore')

# Load packages
import numpy as np                               # vectors and matrices
import pandas as pd                              # tables and data manipulations
import matplotlib.pyplot as plt                  # plots
import seaborn as sns                            # more plots

from dateutil.relativedelta import relativedelta # working with dates with style
from scipy.optimize import minimize              # for function minimization

import statsmodels.formula.api as smf            # statistics and econometrics
import statsmodels.tsa.api as smt
import statsmodels.api as sm
import scipy.stats as scs

from itertools import product                    # some useful functions
from tqdm import tqdm_notebook

%matplotlib inline
# based on https://www.kaggle.com/kashnitsky/topic-9-part-1-time-series-analysis-in-python#Topic-9.-Part-1.-Time-series-analysis-in-Python
```

## Stationarity test

**Augmented Dickey-Fuller test (ADF)**

ADF tests the null hypothesis that a unit root is present in time series sample. ADF statistic is a negative number and more negative it is the stronger the rejection of the hypothesis that there is a unit root.

- Null Hypotehsis (H0): If accepted, it suggests the time series has a unit root, meaning it is non-stationary. It has some time dependent structure.

- Alternate Hypothesis (H1): The null hypothesis is rejected; it suggests the time series does not have a unit root, meaning it is stationary.

p-value > 0.05: Accept H0, the data has a unit root and is non-stationary

p-value ≤ 0.05: Reject H0. the data does not have a unit root and is stationary

## Forecast quality metrics

Before we begin forecasting, let's understand how to measure the quality of our predictions and take a look at the most commonly used metrics.

- [R squared](http://scikit-learn.org/stable/modules/model_evaluation.html#r2-score-the-coefficient-of-determination): coefficient of determination (in econometrics, this can be interpreted as the percentage of variance explained by the model), $(-\infty, 1]$

$R^2 = 1 - \frac{SS_{res}}{SS_{tot}}$

```python
sklearn.metrics.r2_score
```
---
- [Mean Absolute Error](http://scikit-learn.org/stable/modules/model_evaluation.html#mean-absolute-error): this is an interpretable metric because it has the same unit of measurment as the initial series, $[0, +\infty)$

$MAE = \frac{\sum\limits_{i=1}^{n} |y_i - \hat{y}_i|}{n}$

```python
sklearn.metrics.mean_absolute_error
```
---
- [Median Absolute Error](http://scikit-learn.org/stable/modules/model_evaluation.html#median-absolute-error): again, an interpretable metric that is particularly interesting because it is robust to outliers, $[0, +\infty)$

$MedAE = median(|y_1 - \hat{y}_1|, ... , |y_n - \hat{y}_n|)$

```python
sklearn.metrics.median_absolute_error
```
---
- [Mean Squared Error](http://scikit-learn.org/stable/modules/model_evaluation.html#mean-squared-error): the most commonly used metric that gives a higher penalty to large errors and vice versa, $[0, +\infty)$

$MSE = \frac{1}{n}\sum\limits_{i=1}^{n} (y_i - \hat{y}_i)^2$

```python
sklearn.metrics.mean_squared_error
```
---
- [Mean Squared Logarithmic Error](http://scikit-learn.org/stable/modules/model_evaluation.html#mean-squared-logarithmic-error): practically, this is the same as MSE, but we take the logarithm of the series. As a result, we give more weight to small mistakes as well. This is usually used when the data has exponential trends, $[0, +\infty)$

$MSLE = \frac{1}{n}\sum\limits_{i=1}^{n} (log(1+y_i) - log(1+\hat{y}_i))^2$

```python
sklearn.metrics.mean_squared_log_error
```
---
- Mean Absolute Percentage Error: this is the same as MAE but is computed as a percentage, which is very convenient when you want to explain the quality of the model to management, $[0, +\infty)$

$MAPE = \frac{100}{n}\sum\limits_{i=1}^{n} \frac{|y_i - \hat{y}_i|}{y_i}$

```python
def mean_absolute_percentage_error(y_true, y_pred):
    return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
```

## Dataset

```python
capitals_df = pd.read_csv('all_capitals_climate.csv', index_col=['validdate'])

ads = capitals_df
```

```python
ads.rename(columns={'Unnamed: 0': 'city'}, inplace=True)
ads.drop(['Unnamed: 1'], axis=1, inplace=True)
ads = ads[ads['city'] == 'Teresina']
ads = ads[['t_2m:C']]
ads.rename(columns={'t_2m:C':'Ads'}, inplace=True)
```

```python
# currency.head()
ads.head()
```

      Ads

      validdate

      2020-01-01T00:00:00Z
      11.3

      2020-01-02T00:00:00Z
      10.7

      2020-01-03T00:00:00Z
      10.6

      2020-01-04T00:00:00Z
      8.8

      2020-01-05T00:00:00Z
      11.1

### Plots

```python
plt.figure(figsize=(18, 6))
plt.plot(ads.Ads)
plt.title('Ads watched (hourly data)')
plt.grid(True)
plt.show()
```

```python
# plt.figure(figsize=(18, 6))
# plt.plot(currency.GEMS_GEMS_SPENT)
# plt.title('In-game currency spent (daily data)')
# plt.grid(True)
# plt.show()
```

## Moving average, metrics and so on
Let's start with a naive hypothesis: "tomorrow will be the same as today". However, instead of a model like  $\hat{y}_t=y_t−1$ (which is actually a great baseline for any time series prediction problems and sometimes is impossible to beat), we will assume that the future value of our variable depends on the average of its $k$ previous values. Therefore, we will use ***the moving average.***

\begin{equation}
\hat{y}_{t}=\frac{1}{k} \sum_{n=1}^{k} y_{t-n}
\end{equation}

```python
# Importing everything from forecasting quality metrics
from sklearn.metrics import r2_score, median_absolute_error, mean_absolute_error
from sklearn.metrics import median_absolute_error, mean_squared_error, mean_squared_log_error

# MAPE
def mean_absolute_percentage_error(y_true, y_pred):
    return np.mean(np.abs((y_true - y_pred) / y_true)) * 100

def plotMovingAverage(series, window, plot_intervals=False, scale=1.96, plot_anomalies=False):

    """This function calculates moving average and plots with confidence intervals

        series - dataframe with timeseries
        window - rolling window size
        plot_intervals - show confidence intervals
        plot_anomalies - show anomalies
    """

    rolling_mean = series.rolling(window=window).mean()
    rollig_std = series.rolling(window=window).std()

    plt.figure(figsize=(18,6))
    plt.title("Moving average\n window size = {}".format(window))
    plt.plot(rolling_mean, "g", label="Rolling mean trend")

    # Plot confidence intervals for smoothed values
    if plot_intervals:
        mae = mean_absolute_error(series[window:], rolling_mean[window:])
        deviation = np.std(series[window:] - rolling_mean[window:])
        lower_bond = rolling_mean - (mae + scale * deviation)
        upper_bond = rolling_mean + (mae + scale * deviation)
        plt.plot(upper_bond, "r--", label="Upper Bond / Lower Bond")
        plt.plot(lower_bond, "r--")

        # Having the intervals, find abnormal values
        if plot_anomalies:
            anomalies = pd.DataFrame(index=series.index, columns=series.columns)
            anomalies[series<lower_bond] = series[series<lower_bond]
            anomalies[series>upper_bond] = series[series>upper_bond]
            plt.plot(anomalies, "ro", markersize=10)

    plt.plot(series[window:], label="Actual values")
    plt.legend(loc="best")
    plt.grid(True)

def getAnomaliesList(series, window):

    """This function calculates moving average and plots with confidence intervals

        series - dataframe with timeseries
        window - rolling window size
        plot_intervals - show confidence intervals
    """
    scale=1.96
    listAnomalies = []

    rolling_mean = series.rolling(window=window).mean()
    rollig_std = series.rolling(window=window).std()

    # Plot confidence intervals for smoothed values

    mae = mean_absolute_error(series[window:], rolling_mean[window:])
    deviation = np.std(series[window:] - rolling_mean[window:])
    lower_bond = rolling_mean - (mae + scale * deviation)
    upper_bond = rolling_mean + (mae + scale * deviation)

    # Having the intervals, find abnormal values

    anomalies = pd.DataFrame(index=series.index, columns=series.columns)
    anomalies[series<lower_bond] = series[series<lower_bond]
    anomalies[series>upper_bond] = series[series>upper_bond]

    listAnomalies = anomalies

    return listAnomalies

def test_adfuller(series):

    """Augmented Dickey-Fuller test (ADF)

       p-value > 0.05: Accept H0, the data has a unit root and is non-stationary

       p-value ≤ 0.05: Reject H0. the data does not have a unit root and is stationary
    """

    series = series.values
    result = sm.tsa.stattools.adfuller(series)
    print('ADF Statistic: %f' % result[0])
    print('p-value: %f' % result[1])
    print('Critical Values:')
    for key, value in result[4].items():
      print('\t%s: %.3f' % (key, value))
```

```python
test_adfuller(ads.Ads)
```

    ADF Statistic: -5.322615
    p-value: 0.000005
    Critical Values:
    	1%: -3.475
    	5%: -2.881
    	10%: -2.577

```python
plotMovingAverage(ads, 12) # Let's smooth by the previous 12 hours
```

```python
plotMovingAverage(ads, 4) # Let's smooth by the previous 4 hours
```

```python
plotMovingAverage(ads, 4, plot_intervals=True)
```

Now, let's create a simple anomaly detection system with the help of moving average. Unfortunately, in this particular dataset, everything is more or less normal, so we will intentionally make one of the values abnormal in our dataframe ads_anomaly.

```python
ads_anomaly = ads.copy()
ads_anomaly.iloc[-20] = ads_anomaly.iloc[-20] * 0.2 # say we have 80% drop of ads
```

```python
# Let see if the simple method can catch the anomaly
plotMovingAverage(ads_anomaly, 3, plot_intervals=True, plot_anomalies=True)
```

```python
anomaly_points = {}
```

```python
capitals_df = pd.read_csv('all_capitals_climate.csv', index_col=['validdate'])
capitals_df.rename(columns={'Unnamed: 0': 'city', 't_2m:C': 'temp', 'relative_humidity_2m:p': 'humid',
                            'precip_1h:mm': 'prec'}, inplace=True)
capitals_df.drop(['Unnamed: 1'], axis=1, inplace=True)
capital_names = capitals_df.city.unique()

for item in capital_names:

    ads = capitals_df.copy()
    ads = ads[ads['city'] == item]

    feature = 'humid'

    ads = ads[[feature]]
    ads.rename(columns={feature:'Ads'}, inplace=True)

    ads_anomaly = ads.copy()
    ads_anomaly.iloc[-20] = ads_anomaly.iloc[-20] * 0.2

    anomalies_results = getAnomaliesList(ads_anomaly, 4)
    anomalies_values = anomalies_results['Ads'].values

    anomalies_indexes = []

    for i, value in enumerate(anomalies_values):
        if not math.isnan(value):
            anomalies_indexes.append(i)

    if not anomaly_points.get(item):
        anomaly_points[item] = {}
    anomaly_points[item]['anomalous_points_'+feature] = anomalies_indexes
    anomaly_points[item]['timeseries_'+feature] = capitals_df[capitals_df.city == item][feature].values.tolist()

# saving processed data in json format
import json
with open('anomaly_'+feature+'_points.json', 'w', encoding='utf8') as file:
    json.dump(anomaly_points, file, ensure_ascii=False)
```

```python
similarity_series = {}

for item1 in capital_names:
    ads = capitals_df.copy()
    city1 = ads[ads['city'] == item1]

    similarity_series[item1] = {}

    for item2 in capital_names:
        ads = capitals_df.copy()
        city2 = ads[ads['city'] == item2]

        similarity_series[item1][item2] = {}

        list_features = ['temp', 'humid', 'prec']

        for feature in list_features:

            # Calculate euclidean distance to get similatiry between the timeseries
            from sklearn.metrics.pairwise import cosine_similarity

            distance = cosine_similarity(city1[feature].values.reshape(1, -1), city2[feature].values.reshape(1, -1))
            distance = distance[0][0] if distance[0][0] > 0 else 0.01

            similarity_series[item1][item2]['similarity_' + feature] = float(f"{distance:.2f}")

# saving processed data in json format
import json
with open('climatic_similarity.json', 'w', encoding='utf8') as file:
    json.dump(similarity_series, file, ensure_ascii=False)
```

```python
similarity_series
```

    {'Rio Branco': {'Rio Branco': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Maceió': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.12},
      'Macapá': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.14},
      'Manaus': {'similarity_temp': 0.8,
       'similarity_humid': 0.99,
       'similarity_prec': 0.28},
      'Salvador': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Fortaleza': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Brasília': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.34},
      'Vitória': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Goiânia': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.34},
      'São Luís': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Cuiabá': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.34},
      'Campo Grande': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05},
      'Belo Horizonte': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Belém': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.08},
      'João Pessoa': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.19},
      'Recife': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.07},
      'Teresina': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Rio de Janeiro': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05},
      'Natal': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.14},
      'Porto Alegre': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'Porto Velho': {'similarity_temp': 0.92,
       'similarity_humid': 0.99,
       'similarity_prec': 0.48},
      'Boa Vista': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Florianópolis': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'São Paulo': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Aracaju': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.13},
      'Palmas': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04}},
     'Maceió': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.12},
      'Maceió': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Macapá': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.12},
      'Salvador': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Fortaleza': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.26},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'São Luís': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Campo Grande': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Belém': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.23},
      'João Pessoa': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.23},
      'Recife': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.41},
      'Teresina': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.21},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Natal': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.26},
      'Porto Alegre': {'similarity_temp': 0.89,
       'similarity_humid': 0.98,
       'similarity_prec': 0.07},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Boa Vista': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.3},
      'Florianópolis': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'São Paulo': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Aracaju': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.22},
      'Palmas': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04}},
     'Macapá': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.14},
      'Maceió': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Macapá': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.22},
      'Salvador': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Fortaleza': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'São Luís': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.23},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Campo Grande': {'similarity_temp': 0.75,
       'similarity_humid': 0.99,
       'similarity_prec': 0.14},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.08},
      'Belém': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.16},
      'João Pessoa': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.18},
      'Recife': {'similarity_temp': 0.94,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Teresina': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Natal': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.21},
      'Porto Alegre': {'similarity_temp': 0.89,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.35},
      'Boa Vista': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Florianópolis': {'similarity_temp': 0.95,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'São Paulo': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'Aracaju': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'Palmas': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.16}},
     'Manaus': {'Rio Branco': {'similarity_temp': 0.8,
       'similarity_humid': 0.99,
       'similarity_prec': 0.28},
      'Maceió': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.12},
      'Macapá': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.22},
      'Manaus': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Salvador': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Fortaleza': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.14},
      'Brasília': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Vitória': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.17},
      'Goiânia': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'São Luís': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.2},
      'Cuiabá': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Campo Grande': {'similarity_temp': 0.24,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Belo Horizonte': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.08},
      'Belém': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'João Pessoa': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.25},
      'Recife': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.4},
      'Teresina': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.19},
      'Rio de Janeiro': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Natal': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.24},
      'Porto Alegre': {'similarity_temp': 0.04,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Porto Velho': {'similarity_temp': 0.87,
       'similarity_humid': 0.99,
       'similarity_prec': 0.59},
      'Boa Vista': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.2},
      'Florianópolis': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.5},
      'São Paulo': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.06},
      'Aracaju': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.08},
      'Palmas': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1}},
     'Salvador': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Maceió': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Macapá': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Salvador': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Fortaleza': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'São Luís': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Campo Grande': {'similarity_temp': 0.77,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Belém': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'João Pessoa': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Recife': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.12},
      'Teresina': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Natal': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.19},
      'Porto Alegre': {'similarity_temp': 0.89,
       'similarity_humid': 0.98,
       'similarity_prec': 0.08},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.19},
      'Boa Vista': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.16},
      'Florianópolis': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'São Paulo': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Aracaju': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.51},
      'Palmas': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.06}},
     'Fortaleza': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Maceió': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.26},
      'Macapá': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.14},
      'Salvador': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'Fortaleza': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'São Luís': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.22},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Campo Grande': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Belém': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05},
      'João Pessoa': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Recife': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.17},
      'Teresina': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.22},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Natal': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Porto Alegre': {'similarity_temp': 0.88,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Boa Vista': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.41},
      'Florianópolis': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'São Paulo': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Aracaju': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.07},
      'Palmas': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03}},
     'Brasília': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.34},
      'Maceió': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Macapá': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Salvador': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Fortaleza': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Brasília': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Vitória': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.47},
      'Goiânia': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'São Luís': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Cuiabá': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Campo Grande': {'similarity_temp': 0.85,
       'similarity_humid': 0.99,
       'similarity_prec': 0.46},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Belém': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'João Pessoa': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Recife': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Teresina': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Natal': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Porto Alegre': {'similarity_temp': 0.92,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.31},
      'Boa Vista': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Florianópolis': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'São Paulo': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.19},
      'Aracaju': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Palmas': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.23}},
     'Vitória': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Maceió': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Macapá': {'similarity_temp': 0.95,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.17},
      'Salvador': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Fortaleza': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Brasília': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.47},
      'Vitória': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Goiânia': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.47},
      'São Luís': {'similarity_temp': 0.95,
       'similarity_humid': 0.99,
       'similarity_prec': 0.07},
      'Cuiabá': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.47},
      'Campo Grande': {'similarity_temp': 0.87,
       'similarity_humid': 0.99,
       'similarity_prec': 0.37},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Belém': {'similarity_temp': 0.95,
       'similarity_humid': 0.99,
       'similarity_prec': 0.06},
      'João Pessoa': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.21},
      'Recife': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Teresina': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.37},
      'Natal': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Porto Alegre': {'similarity_temp': 0.93,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.16},
      'Boa Vista': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.13},
      'Florianópolis': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'São Paulo': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Aracaju': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Palmas': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.32}},
     'Goiânia': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.34},
      'Maceió': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Macapá': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Salvador': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Fortaleza': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Brasília': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Vitória': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.47},
      'Goiânia': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'São Luís': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Cuiabá': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Campo Grande': {'similarity_temp': 0.85,
       'similarity_humid': 0.99,
       'similarity_prec': 0.46},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Belém': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'João Pessoa': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Recife': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Teresina': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Natal': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Porto Alegre': {'similarity_temp': 0.92,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.31},
      'Boa Vista': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Florianópolis': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'São Paulo': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.19},
      'Aracaju': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Palmas': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.23}},
     'São Luís': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Maceió': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Macapá': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.23},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.2},
      'Salvador': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Fortaleza': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.22},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.99,
       'similarity_prec': 0.07},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'São Luís': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Campo Grande': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Belo Horizonte': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Belém': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.38},
      'João Pessoa': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.41},
      'Recife': {'similarity_temp': 0.93,
       'similarity_humid': 0.98,
       'similarity_prec': 0.18},
      'Teresina': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.62},
      'Rio de Janeiro': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Natal': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.32},
      'Porto Alegre': {'similarity_temp': 0.87,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.18},
      'Boa Vista': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.3},
      'Florianópolis': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'São Paulo': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Aracaju': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.06},
      'Palmas': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13}},
     'Cuiabá': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.34},
      'Maceió': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Macapá': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Salvador': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Fortaleza': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Brasília': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Vitória': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.47},
      'Goiânia': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'São Luís': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Cuiabá': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Campo Grande': {'similarity_temp': 0.85,
       'similarity_humid': 0.99,
       'similarity_prec': 0.46},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Belém': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'João Pessoa': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Recife': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Teresina': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Natal': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Porto Alegre': {'similarity_temp': 0.92,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.31},
      'Boa Vista': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Florianópolis': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'São Paulo': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.19},
      'Aracaju': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Palmas': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.23}},
     'Campo Grande': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05},
      'Maceió': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Macapá': {'similarity_temp': 0.75,
       'similarity_humid': 0.99,
       'similarity_prec': 0.14},
      'Manaus': {'similarity_temp': 0.24,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Salvador': {'similarity_temp': 0.77,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Fortaleza': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Brasília': {'similarity_temp': 0.85,
       'similarity_humid': 0.99,
       'similarity_prec': 0.46},
      'Vitória': {'similarity_temp': 0.87,
       'similarity_humid': 0.99,
       'similarity_prec': 0.37},
      'Goiânia': {'similarity_temp': 0.85,
       'similarity_humid': 0.99,
       'similarity_prec': 0.46},
      'São Luís': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Cuiabá': {'similarity_temp': 0.85,
       'similarity_humid': 0.99,
       'similarity_prec': 0.46},
      'Campo Grande': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Belo Horizonte': {'similarity_temp': 0.8,
       'similarity_humid': 0.99,
       'similarity_prec': 0.31},
      'Belém': {'similarity_temp': 0.78,
       'similarity_humid': 0.99,
       'similarity_prec': 0.22},
      'João Pessoa': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.13},
      'Recife': {'similarity_temp': 0.89,
       'similarity_humid': 0.99,
       'similarity_prec': 0.14},
      'Teresina': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.07},
      'Rio de Janeiro': {'similarity_temp': 0.81,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Natal': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Porto Alegre': {'similarity_temp': 0.91,
       'similarity_humid': 0.99,
       'similarity_prec': 0.25},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.21},
      'Boa Vista': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Florianópolis': {'similarity_temp': 0.87,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'São Paulo': {'similarity_temp': 0.83,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Aracaju': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Palmas': {'similarity_temp': 0.83,
       'similarity_humid': 0.99,
       'similarity_prec': 0.14}},
     'Belo Horizonte': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Maceió': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Macapá': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.08},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.08},
      'Salvador': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Fortaleza': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Brasília': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Vitória': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Goiânia': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'São Luís': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Cuiabá': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Campo Grande': {'similarity_temp': 0.8,
       'similarity_humid': 0.99,
       'similarity_prec': 0.31},
      'Belo Horizonte': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Belém': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'João Pessoa': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Recife': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.07},
      'Teresina': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Rio de Janeiro': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.2},
      'Natal': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Porto Alegre': {'similarity_temp': 0.91,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.12},
      'Boa Vista': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Florianópolis': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.02},
      'São Paulo': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.18},
      'Aracaju': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Palmas': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.08}},
     'Belém': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.08},
      'Maceió': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.23},
      'Macapá': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.16},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Salvador': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Fortaleza': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.99,
       'similarity_prec': 0.06},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'São Luís': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.38},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Campo Grande': {'similarity_temp': 0.78,
       'similarity_humid': 0.99,
       'similarity_prec': 0.22},
      'Belo Horizonte': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Belém': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'João Pessoa': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.17},
      'Recife': {'similarity_temp': 0.93,
       'similarity_humid': 0.98,
       'similarity_prec': 0.14},
      'Teresina': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.37},
      'Rio de Janeiro': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Natal': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.13},
      'Porto Alegre': {'similarity_temp': 0.87,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Boa Vista': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Florianópolis': {'similarity_temp': 0.93,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'São Paulo': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Aracaju': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'Palmas': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1}},
     'João Pessoa': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.19},
      'Maceió': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.23},
      'Macapá': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.18},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.25},
      'Salvador': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Fortaleza': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.21},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'São Luís': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.41},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Campo Grande': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.13},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Belém': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.17},
      'João Pessoa': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Recife': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Teresina': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.19},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Natal': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.61},
      'Porto Alegre': {'similarity_temp': 0.88,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Boa Vista': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.54},
      'Florianópolis': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.07},
      'São Paulo': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Aracaju': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.06},
      'Palmas': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05}},
     'Recife': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.07},
      'Maceió': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.41},
      'Macapá': {'similarity_temp': 0.94,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.4},
      'Salvador': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.12},
      'Fortaleza': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.17},
      'Brasília': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Vitória': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Goiânia': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'São Luís': {'similarity_temp': 0.93,
       'similarity_humid': 0.98,
       'similarity_prec': 0.18},
      'Cuiabá': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Campo Grande': {'similarity_temp': 0.89,
       'similarity_humid': 0.99,
       'similarity_prec': 0.14},
      'Belo Horizonte': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.07},
      'Belém': {'similarity_temp': 0.93,
       'similarity_humid': 0.98,
       'similarity_prec': 0.14},
      'João Pessoa': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Recife': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Teresina': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Rio de Janeiro': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.07},
      'Natal': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.12},
      'Porto Alegre': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.28},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.35},
      'Boa Vista': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Florianópolis': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.59},
      'São Paulo': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Aracaju': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Palmas': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11}},
     'Teresina': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Maceió': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.21},
      'Macapá': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.19},
      'Salvador': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Fortaleza': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.22},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'São Luís': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.62},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Campo Grande': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.07},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Belém': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.37},
      'João Pessoa': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.19},
      'Recife': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Teresina': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Natal': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Porto Alegre': {'similarity_temp': 0.88,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.19},
      'Boa Vista': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.17},
      'Florianópolis': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.07},
      'São Paulo': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Aracaju': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.08},
      'Palmas': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.07}},
     'Rio de Janeiro': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05},
      'Maceió': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Macapá': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Salvador': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Fortaleza': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Brasília': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Vitória': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.37},
      'Goiânia': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'São Luís': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Cuiabá': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Campo Grande': {'similarity_temp': 0.81,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Belo Horizonte': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.2},
      'Belém': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'João Pessoa': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Recife': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.07},
      'Teresina': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Rio de Janeiro': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Natal': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.13},
      'Porto Alegre': {'similarity_temp': 0.91,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Boa Vista': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Florianópolis': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.01},
      'São Paulo': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.5},
      'Aracaju': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.08},
      'Palmas': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05}},
     'Natal': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.14},
      'Maceió': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.26},
      'Macapá': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.21},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.24},
      'Salvador': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.19},
      'Fortaleza': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'São Luís': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.32},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Campo Grande': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Belém': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.13},
      'João Pessoa': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.61},
      'Recife': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.12},
      'Teresina': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.13},
      'Natal': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Porto Alegre': {'similarity_temp': 0.88,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.19},
      'Boa Vista': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.37},
      'Florianópolis': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'São Paulo': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Aracaju': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Palmas': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05}},
     'Porto Alegre': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'Maceió': {'similarity_temp': 0.89,
       'similarity_humid': 0.98,
       'similarity_prec': 0.07},
      'Macapá': {'similarity_temp': 0.89,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Manaus': {'similarity_temp': 0.04,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Salvador': {'similarity_temp': 0.89,
       'similarity_humid': 0.98,
       'similarity_prec': 0.08},
      'Fortaleza': {'similarity_temp': 0.88,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Brasília': {'similarity_temp': 0.92,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Vitória': {'similarity_temp': 0.93,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Goiânia': {'similarity_temp': 0.92,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'São Luís': {'similarity_temp': 0.87,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Cuiabá': {'similarity_temp': 0.92,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Campo Grande': {'similarity_temp': 0.91,
       'similarity_humid': 0.99,
       'similarity_prec': 0.25},
      'Belo Horizonte': {'similarity_temp': 0.91,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Belém': {'similarity_temp': 0.87,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'João Pessoa': {'similarity_temp': 0.88,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Recife': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.28},
      'Teresina': {'similarity_temp': 0.88,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Rio de Janeiro': {'similarity_temp': 0.91,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'Natal': {'similarity_temp': 0.88,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Porto Alegre': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.16},
      'Boa Vista': {'similarity_temp': 0.89,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Florianópolis': {'similarity_temp': 0.97,
       'similarity_humid': 1.0,
       'similarity_prec': 0.18},
      'São Paulo': {'similarity_temp': 0.93,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Aracaju': {'similarity_temp': 0.89,
       'similarity_humid': 0.98,
       'similarity_prec': 0.01},
      'Palmas': {'similarity_temp': 0.91,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05}},
     'Porto Velho': {'Rio Branco': {'similarity_temp': 0.92,
       'similarity_humid': 0.99,
       'similarity_prec': 0.48},
      'Maceió': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Macapá': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.35},
      'Manaus': {'similarity_temp': 0.87,
       'similarity_humid': 0.99,
       'similarity_prec': 0.59},
      'Salvador': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.19},
      'Fortaleza': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Brasília': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.31},
      'Vitória': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.16},
      'Goiânia': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.31},
      'São Luís': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.18},
      'Cuiabá': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.31},
      'Campo Grande': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.21},
      'Belo Horizonte': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.12},
      'Belém': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.2},
      'João Pessoa': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Recife': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.35},
      'Teresina': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.19},
      'Rio de Janeiro': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Natal': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.19},
      'Porto Alegre': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.16},
      'Porto Velho': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Boa Vista': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.18},
      'Florianópolis': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.46},
      'São Paulo': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Aracaju': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.2},
      'Palmas': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.18}},
     'Boa Vista': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Maceió': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.3},
      'Macapá': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.2},
      'Salvador': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.16},
      'Fortaleza': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.41},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.13},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'São Luís': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.3},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Campo Grande': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Belém': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'João Pessoa': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.54},
      'Recife': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Teresina': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.17},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Natal': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.37},
      'Porto Alegre': {'similarity_temp': 0.89,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.18},
      'Boa Vista': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Florianópolis': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'São Paulo': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Aracaju': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.15},
      'Palmas': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05}},
     'Florianópolis': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Maceió': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.06},
      'Macapá': {'similarity_temp': 0.95,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.5},
      'Salvador': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Fortaleza': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Brasília': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'Vitória': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'Goiânia': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'São Luís': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.11},
      'Cuiabá': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'Campo Grande': {'similarity_temp': 0.87,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Belo Horizonte': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.02},
      'Belém': {'similarity_temp': 0.93,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'João Pessoa': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.07},
      'Recife': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.59},
      'Teresina': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.07},
      'Rio de Janeiro': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.01},
      'Natal': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.16},
      'Porto Alegre': {'similarity_temp': 0.97,
       'similarity_humid': 1.0,
       'similarity_prec': 0.18},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.46},
      'Boa Vista': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.1},
      'Florianópolis': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'São Paulo': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.02},
      'Aracaju': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.01},
      'Palmas': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03}},
     'São Paulo': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Maceió': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Macapá': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.06},
      'Salvador': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.09},
      'Fortaleza': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Brasília': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.19},
      'Vitória': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Goiânia': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.19},
      'São Luís': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Cuiabá': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.19},
      'Campo Grande': {'similarity_temp': 0.83,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Belo Horizonte': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.18},
      'Belém': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'João Pessoa': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Recife': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.15},
      'Teresina': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Rio de Janeiro': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.5},
      'Natal': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Porto Alegre': {'similarity_temp': 0.93,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Boa Vista': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Florianópolis': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.02},
      'São Paulo': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Aracaju': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Palmas': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12}},
     'Aracaju': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.13},
      'Maceió': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.22},
      'Macapá': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.08},
      'Salvador': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.51},
      'Fortaleza': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.07},
      'Brasília': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Vitória': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.15},
      'Goiânia': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'São Luís': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.06},
      'Cuiabá': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Campo Grande': {'similarity_temp': 0.76,
       'similarity_humid': 0.98,
       'similarity_prec': 0.02},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Belém': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'João Pessoa': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.06},
      'Recife': {'similarity_temp': 0.94,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Teresina': {'similarity_temp': 0.99,
       'similarity_humid': 0.99,
       'similarity_prec': 0.08},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.98,
       'similarity_prec': 0.08},
      'Natal': {'similarity_temp': 1.0,
       'similarity_humid': 0.99,
       'similarity_prec': 0.09},
      'Porto Alegre': {'similarity_temp': 0.89,
       'similarity_humid': 0.98,
       'similarity_prec': 0.01},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.98,
       'similarity_prec': 0.2},
      'Boa Vista': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 0.15},
      'Florianópolis': {'similarity_temp': 0.95,
       'similarity_humid': 0.98,
       'similarity_prec': 0.01},
      'São Paulo': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Aracaju': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0},
      'Palmas': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.01}},
     'Palmas': {'Rio Branco': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.04},
      'Maceió': {'similarity_temp': 0.97,
       'similarity_humid': 0.98,
       'similarity_prec': 0.04},
      'Macapá': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.16},
      'Manaus': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'Salvador': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.06},
      'Fortaleza': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.03},
      'Brasília': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.23},
      'Vitória': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.32},
      'Goiânia': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.23},
      'São Luís': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.13},
      'Cuiabá': {'similarity_temp': 0.99,
       'similarity_humid': 1.0,
       'similarity_prec': 0.23},
      'Campo Grande': {'similarity_temp': 0.83,
       'similarity_humid': 0.99,
       'similarity_prec': 0.14},
      'Belo Horizonte': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.08},
      'Belém': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.1},
      'João Pessoa': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Recife': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.11},
      'Teresina': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.07},
      'Rio de Janeiro': {'similarity_temp': 0.98,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05},
      'Natal': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Porto Alegre': {'similarity_temp': 0.91,
       'similarity_humid': 0.99,
       'similarity_prec': 0.05},
      'Porto Velho': {'similarity_temp': 0.01,
       'similarity_humid': 0.99,
       'similarity_prec': 0.18},
      'Boa Vista': {'similarity_temp': 0.96,
       'similarity_humid': 0.98,
       'similarity_prec': 0.05},
      'Florianópolis': {'similarity_temp': 0.96,
       'similarity_humid': 0.99,
       'similarity_prec': 0.03},
      'São Paulo': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.12},
      'Aracaju': {'similarity_temp': 0.97,
       'similarity_humid': 0.99,
       'similarity_prec': 0.01},
      'Palmas': {'similarity_temp': 1.0,
       'similarity_humid': 1.0,
       'similarity_prec': 1.0}}}

```python

```

    [15.6,
     14.1,
     16.2,
     11.9,
     14.2,
     14.1,
     14.9,
     12.5,
     11.3,
     15.1,
     14.5,
     14.7,
     15.1,
     16.5,
     14.2,
     12.8,
     13.7,
     14.0,
     14.9,
     15.4,
     14.7,
     14.7,
     16.0,
     17.4,
     14.0,
     13.2,
     16.5,
     17.4,
     16.1,
     17.4,
     14.2,
     15.9,
     18.3,
     15.7,
     15.0,
     12.1,
     11.6,
     14.9,
     16.6,
     16.2,
     16.8,
     17.8,
     14.8,
     13.0,
     12.6,
     13.2,
     14.2,
     14.5,
     16.0,
     15.9,
     15.4,
     16.8,
     14.9,
     15.3,
     16.0,
     16.9,
     14.1,
     15.3,
     16.3,
     17.1,
     18.0,
     16.9,
     16.9,
     16.1,
     17.0,
     17.9,
     14.4,
     13.7,
     16.1,
     17.9,
     14.8,
     15.3,
     14.9,
     13.7,
     14.5,
     17.4,
     15.4,
     16.8,
     15.7,
     15.4,
     16.1,
     15.6,
     18.7,
     15.9,
     13.8,
     14.9,
     16.0,
     14.2,
     14.9,
     15.4,
     12.3,
     17.4,
     18.2,
     14.0,
     15.5,
     12.7,
     13.0,
     16.3,
     16.7,
     15.5,
     15.3,
     13.2,
     13.6,
     14.1,
     16.2,
     14.4,
     15.1,
     13.8,
     17.6,
     11.4,
     11.2,
     15.3,
     15.2,
     15.5,
     16.2,
     15.2,
     11.9,
     14.7,
     16.1,
     14.1,
     14.5,
     15.2,
     11.6,
     13.0,
     15.3,
     16.5,
     16.8,
     13.8,
     15.5,
     17.2,
     13.0,
     12.4,
     13.2,
     14.1,
     14.8,
     12.8,
     16.4,
     13.6,
     13.4,
     16.3,
     11.9,
     10.2,
     14.2,
     14.8,
     12.6,
     9.6,
     14.7,
     15.3,
     14.6,
     14.9,
     15.8,
     14.4]

```python

```


# Multivariate Linear Mixed Models (MLMM)

## Flexible Algorithm by Multivariate Linear Mixed Model for QTL Analysis

A problem that arises in plant breeding is to understand individual genetic regions contributing to trait variation across
geographic space.  The data are high-dimensional and structured by a host of growing season phenotypes of plants, for instance,
switchgrass, screened for a series of high-throughput physiological measurements in 10 different latitudes for multiple years [1](#gxe).

One is interested in determining the genomic regions underlying upland/lowland ecotype divergence and adaptation for switchgrass by
assessing gene by environment interactions (GxE) across space and climate variation.  A high-dimensional multivariate linear mixed
model assuming phenotypes are correlated due to genetic similarity, measured by genome-wide markers, and environmental similarity, by
climatic or edaphic information, is built as follows:

\begin{equation}
                     Y=XBZ'+R+E,
\end{equation}

or implicitly
\begin{equation}
                    Y^v\sim MVN((Z\otimes X) B^v,\tau^2 K_C\otimes K_G+\Sigma\otimes I_n),
\end{equation}

where the superscript $v$ means the vectorized form of a matrix, $Y_{n\times m}$, $X_{n\times p}$, $Z_{m\times q}$ are $n$ phenotypic
trait values over $m$ environments, $p$ genotypes of genotype probabilities (with covariates) with the intercept for a candidate
marker,  $q$ phenotypic low-dimensional covariates, respectively.  $R$, $E$  are GxE random effects including high-dimensional column
covariates, model or residual errors, respectively.

Incorporating genetic background information, kinship matrix ($K_G$) with climate
information over multiple environments ($K_C$) generates an infinitesimal random GxE effects.  Meanwhile, a functional phenotypic
trend along the environments, interactions between an individual genetic marker and multiple environments can be accounted using the
fixed column covariates ($Z$).  This novelty can significantly reduce the size of parameters to estimate and gives yet flexibility
applicable to a wider variety of data, such as MLMM for multiple traits, time-valued phenotypic curves, or accelerometer data, etc.

The algorithm is developed in Julia using an Expectation Conditional Maximization (ECM) [4](#ecm) with a Speed Restarting Nesterov’s Accelerated
Gradient method [5](#nest).  Extensive simulations show that the results are relatively insensitive to different $K_C$’s; $K_C=I$ can be
used for fast computation to have a rough idea on initial analysis.  Based on on-going analyses of the switchgrass data containing 4
traits measured in 10 sites on the latitude by 3 years ($m =30$ per trait), the results depending on $K_C$’s are expected to show
discrepancy for higher dimensional environments ($m>30$).  As expected, the low fixed column covariates ($Z$) show better performance
than the conventional model, i.e. $Z=I$, in power analysis.

Furthermore, the analyses of fitness in Arabidopsis thaliana with climate
information in 2 sites by 3 years ($m = 6$) [6](#agren) and weekly weight growth rate in island mice from 1 to 16 weeks of age ($m =16$) [7](#goughF2)
using the model developed are not only consistent with those published in the papers but detected more QTL than those.  In addition to
collaborating with Dr. Thomas Jeunger in Integrated Biology department at the University of Texas at Austin on the switchgrass data, I
am working on the data analysis of Outbred Diversity/Heterogeneous Stock (DO/HS) mouse data on travel distance measured in each
miniute with Dr. Vivek Philip at Jackson laboratory using the model developed with some tweaks.\\

* [Preprint](https://doi.org/10.1101/2020.03.27.012690) is available in BioRxiv.

* Presentation slides can be found [here.](p30_gxe.pdf)

* Github repository : [FlxQTL.jl](https://github.com/hkim89/FlxQTL.jl)

---

[1] D. B. Lowry, J. T. Lovell, L. Zhang, J. Bonnette, P. A. Fay, R. B. Mitchell, J. Lloyd-Reilley, A. R. Boe, Y. Wu, F. M. Rouquette Jr, R. L. Wynia, X. Weng, K. D. Behrman, A. Healey, K. Barry, A. Lipzen, D. Bauer, A. Sharma, J. Jenkins, J. Schmutz, F. B. Fritschi, and T. E. Juenger. QTL x environment interactions underlie adaptive divergence in switchgrass across a large latitudinal gradient. PNAS, 116(26):12933-12941, 2019.

[2] X. Zhou and M. Stephens. Efficient multivariate linear mixed model algorithms for genome-wide association studies. Nature Methods, 11(4):407-409, 2014.

[3] C. Lippert, J. Listgarten, Y. Liu, C. M. Kadie, R. I. Davidson, and D. Heckerman. FaST linear mixed models for genome-wide association studies. Nature Methods, 8(10):833-835, 2011.

[4] X. L. Meng and D. B. Rubin. Maximum likelihood estimation via the ECM algorithm: A general framework. Biometrica, 80(2):267-278, 1993.

[5] W. Su, S. Boyd and E. Candès. A differential equation for modeling Nesterov’s accelerated gradient method: Theory and Insights. In Advances in Neural Information Processing Systems, pages 2510-2518, 2014.

[6] J. Ågren, C. G. Oakley, J. K. McKay, J. T. Lovell, and D. W. Schemske. Genetic mapping of adaptation
         reveals fitness tradeoffs in Arabidopsis thaliana. PNAS, 110(52): 21077-21082, 2013.

[7] M. M. Gray, M. D. Parmenter, C. A. Hogan, I. Ford, R. J. Cuthbert, P. G. Ryan, K. Broman, and B. A.
        Payseur. Genetics of rapid and extreme size evolution in island mice. Genetics, 201(1):213-228, 2015.


# Quasar Gate Library
Any function which can generate a $2^N \times 2^N$ unitary matrix $\hat U$ for $N\in\{1,2\}$ from an `OrderedDict` of parameters can be adapted to be used as a `Gate` object within quasar (see the custom gate demo: [quasar-custom-gates.ipynb](quasar-custom-gates.ipynb)). However, in QIS, there are a handful of extremely common gates that one expects in any quantum simulator environment. We provide these as static attributes (for parameter-free gates) or static methods (for parameter-including gates) of the `Gate` class. This tutorial enumerates the existing names quasar gate library.

Note: quasar uses the convention $\hat R_{\hat P} (\theta) \equiv \exp(-i \theta \hat P)$ to define rotation matrices. Other codes may use the "half-turn notation" $\hat R_{\hat P} (\theta) \equiv \exp(-i (\theta / 2) \hat P)$.

```python
import numpy as np
import quasar
```

## 1-Qubit Parameter-Free Gates
The $\hat I$ (identity) gate:

```python
print(quasar.Gate.I.operator)
```

The $\hat X$ (NOT) gate:

```python
print(quasar.Gate.X.operator)
```

The $\hat Y$ gate:

```python
print(quasar.Gate.Y.operator)
```

The $\hat Z$ gate:

```python
print(quasar.Gate.Z.operator)
```

The $\hat H$ (Hadamard) gate:

```python
print(quasar.Gate.H.operator)
```

The $\hat S$ (phase) gate:

```python
print(quasar.Gate.S.operator)
```

The $\hat S^{\adjoint}$ (phase-adjoint) gate:

```python
print(quasar.Gate.ST.operator)
```

The $\hat T$ gate:

```python
print(quasar.Gate.T.operator)
```

The $\hat T^{\adjoint}$ gate:

```python
print(quasar.Gate.TT.operator)
```

The $\hat R_x (\theta = -\pi / 4) = \exp(+i (\pi / 4) \hat X)$ gate (transforms to $\hat Y$ basis):

```python
print(quasar.Gate.Rx2.operator)
```

The $\hat R_x (\theta = +\pi / 4) = \exp(-i (\pi / 4) \hat X)$ gate (transforms from the $\hat Y$ basis):

```python
print(quasar.Gate.Rx2T.operator)
```

## 1-Qubit Parameter-Based Gates
The $\hat R_x (\theta) \equiv \exp(-i \theta \hat X)$ gate:

```python
print(quasar.Gate.Rx(theta=np.pi/4.0).operator)
```

The $\hat R_y (\theta) \equiv \exp(-i \theta \hat Y)$ gate:

```python
print(quasar.Gate.Ry(theta=np.pi/4.0).operator)
```

The $\hat R_z (\theta) \equiv \exp(-i \theta \hat Z)$ gate:

```python
print(quasar.Gate.Rz(theta=np.pi/4.0).operator)
```

The $u3(\theta, \phi, \lambda)$ gate:
\begin{equation}
u3(\theta, \phi, \lambda)
\equiv
\left [
\begin{array}{cc}
\cos(\theta / 2) & -e^{i \phi} \sin(\theta / 2) \\
+e^{i \lambda} \sin(\theta / 2) & e^{i(\phi + \lambda)} \cos(\theta / 2) \\
\end{array}
\right ]
\end{equation}

```python
print(quasar.Gate.u3(theta=0.5, phi=0.4, lam=0.3).operator)
```

The $u2(\phi, \lambda) \equiv u3(\pi/2, \phi, \lambda)$ gate:
\begin{equation}
u2(\phi, \lambda)
\equiv
\frac{1}{\sqrt{2}}
\left [
\begin{array}{cc}
1 & -e^{i \phi}  \\
+e^{i \lambda} & e^{i(\phi + \lambda)} \\
\end{array}
\right ]
\end{equation}

```python
print(quasar.Gate.u2(phi=0.4, lam=0.3).operator)
print(quasar.Gate.u3(theta=np.pi / 2.0, phi=0.4, lam=0.3).operator)
```

The $u1(\lambda) \equiv u3(0, 0, \lambda)$ gate:
\begin{equation}
u1(\lambda)
\equiv
\left [
\begin{array}{cc}
1 & 0  \\
0 & e^{i\lambda} \\
\end{array}
\right ]
\end{equation}

```python
print(quasar.Gate.u1(lam=0.3).operator)
print(quasar.Gate.u3(lam=0.3).operator)
```

## 2-Qubit Parameter-Free Gates

The controlled $\hat X$ (aka CNOT) gate:

```python
print(quasar.Gate.CX.operator)
```

The controlled $\hat Y$ gate:

```python
print(quasar.Gate.CY.operator)
```

The controlled $\hat Z$ gate:

```python
print(quasar.Gate.CZ.operator)
```

The controlled $\hat S$ gate:

```python
print(quasar.Gate.CS.operator)
```

The controlled $\hat S^{\adjoint}$ gate:

```python
print(quasar.Gate.CST.operator)
```

The SWAP gate:

```python
print(quasar.Gate.SWAP.operator)
```

## 2-Qubit Parameter-Based Gates
The controlled $\hat F$ gate:
\begin{equation}
\hat U_{\mathrm{CF}} (\theta)
\equiv
\left [
\begin{array}{cccc}
1 & 0 & 0 & 0 \\
0 & 1 & 0 & 0 \\
0 & 0 & +\cos(\theta) & +\sin(\theta) \\
0 & 0 & +\sin(\theta) & -\cos(\theta) \\
\end{array}
\right ]
\end{equation}

```python
print(quasar.Gate.CF(theta=np.pi/4.0).operator)
```

The exponential parametrization of $SO(4)$: https://arxiv.org/pdf/1901.01234.pdf

```python
print(quasar.Gate.SO4(A=0.1, B=0.2, C=0.3, D=0.4, E=0.5, F=0.6).operator)
```

An alternative parametrization of $SO(4)$:

```python
print(quasar.Gate.SO42(thetaIY=0.1, thetaYI=0.2, thetaXY=0.3, thetaYX=0.4, thetaZY=0.5, thetaYZ=0.6).operator)
```

## Special Parameter-Free Gates
Sometimes the user has a known, parameter-free unitary matrix $\hat U$, and wants a gate corresponding to this. To help in this case, we provide the simple `U1` and `U2` methods to construct custom parameter-free gates:

```python
print(quasar.Gate.U1(U=np.eye(2, dtype=np.complex128)).operator)
```

```python
print(quasar.Gate.U2(U=np.eye(4, dtype=np.complex128)).operator)
```

The updated gate library can be found by looking at the documentation of the `Gate` class:

```python
help(quasar.Gate)
```

## Matrix Library
We also provide a utility library of common matrices used to build many of the above gates in the `Matrix` class. For instance:

```python
print(quasar.Matrix.CX)
```

```python
print(quasar.Matrix.Rx(theta=np.pi/4.0))
```

```python
print(quasar.Matrix.u3(theta=0.3, phi=0.2, lam=0.1))
```

To see the list of available matrices:

```python
help(quasar.Matrix)
```