# read the frequency and get a pandas serie
frequency = pd.read_csv('data/freq.csv')['freqs']

# read all data for training
filenames = ['data/spectra_{}.csv'.format(i)
             for i in range(4)]

spectra, concentration, molecule = [], [], []
for filename in filenames:
    spectra_file, concentration_file, molecule_file = read_spectra(filename)
    spectra.append(spectra_file)
    concentration.append(concentration_file)
    molecule.append(molecule_file)

# Concatenate in single DataFrame and Serie
spectra = pd.concat(spectra)
concentration = pd.concat(concentration)
molecule = pd.concat(molecule)

"""
Explanation: IO: Reading and preprocess the data
We can define a function which will read the data and process them.
End of explanation
"""


plot_spectra(frequency, spectra, 'All training spectra')

plot_spectra_by_type(frequency, spectra, molecule,
                     'Mean spectra in function of the molecules')

plot_spectra_by_type(frequency, spectra, concentration,
                     'Mean spectra in function of the concentrations')

"""
Explanation: Plot helper functions
We can create two functions: (i) to plot all spectra and (ii) plot the mean spectra with the std intervals.
We will make a "private" function which will be used by both plot types.
End of explanation
"""


spectra_test, concentration_test, molecule_test = read_spectra('data/spectra_4.csv')

plot_spectra(frequency, spectra_test,
             'All training spectra')
plot_spectra_by_type(frequency, spectra_test, molecule_test,
                     'Mean spectra in function of the molecules')
plot_spectra_by_type(frequency, spectra_test, concentration_test,
                     'Mean spectra in function of the concentrations')

"""
Explanation: Reusability for new data:
End of explanation
"""


for clf in [RandomForestClassifier(random_state=0),
            LinearSVC(random_state=0)]:
    
    pipeline = make_pipeline(StandardScaler(),
                             PCA(n_components=100, random_state=0),
                             clf)
    y_pred = pipeline.fit(spectra, molecule).predict(spectra_test)
    plot_cm(confusion_matrix(molecule_test, y_pred),
            pipeline.classes_,
            'Confusion matrix using {}'.format(clf.__class__.__name__))
    print('Accuracy score: {0:.2f}'.format(pipeline.score(spectra_test,
                                                          molecule_test)))

"""
Explanation: Training and testing a machine learning model for classification
End of explanation
"""


regression_experiment(spectra, spectra_test,
                      concentration, concentration_test)

# compute the statistics on the training data
med, var = fit_params(spectra)
# transform the training and testing data
spectra_scaled = transform(spectra, med, var)
spectra_test_scaled = transform(spectra_test, med, var)

regression_experiment(spectra_scaled, spectra_test_scaled,
                      concentration, concentration_test)

"""
Explanation: Training and testing a machine learning model for regression
End of explanation
"""


