domenica 4 marzo 2018

Supervised Classification USGS Spectral Library

Dopo aver letto le note introduttive di TensorFlow (l'insieme di librerie di Machine Learning di Google) ed in particolar modo l'esempio sulla classificazione degli Iris sulla base di elementi morfologici mi e' venuta la domanda se il metodo era applicabile anche al telerilevamento iperspettrale, oggetto della mia tesi di dottorato.

Il problema a questo punto era prima di tutto trovare una base dati di training il piu' possibile popolata di elementi (in dottorato ho fatto collezione di spettri ma non organizzate in modo tale da essere utili allo scopo) e la scelta e' caduta su USGS Spectral Libray (gia' usata qui) in particolare per la sezione degli spettri del satellite Hyperion, oramai dismesso ma che e' stato anche lui oggetto di parte della tesi

Visto che a lavoro mi sto occupando in questi di minerali della famiglia dell'asbesto (http://debiaonoldcomputers.blogspot.it/2018/02/actinolite-e-tremolite-ad-impruneta.html) ho provato ad estrarre gli spettri di actinolite, tremolite e serpentino.
In totale il dataset, costituito dalle 3 classi, e' da 23 campioni da 234 bande (nel database gli spettri sono in numero maggiore ma sono stati scelti solo quelli che avevano un campionamento omogeneo)

Gli spettri sono stati tutti normalizzati prima di entrare nel file del dataset.
Si poteva a questo punto si fare l'analisi con le sole componenti principali (PCA analysis) per rendere il dataset piu' piccolo eliminando tutti i dati autocorrelati oppure dare in pasto all'algoritmo tutto lo spettro; ho provato con la seconda strada per vedere come si comportava il codice di calcolo

Nel dettaglio sono stati scelti

Actinolite
s07HYPRN_Actinolite_HS22.1B_ASDFRb_AREF
s07HYPRN_Actinolite_HS22.2B_ASDFRb_AREF
s07HYPRN_Actinolite_HS22.3B_ASDFRb_AREF
s07HYPRN_Actinolite_HS22.4B_ASDFRb_AREF
s07HYPRN_Actinolite_HS116.1B_ASDFRb_AREF
s07HYPRN_Actinolite_HS116.2B_ASDFRb_AREF
s07HYPRN_Actinolite_HS116.3B_ASDFRb_AREF
s07HYPRN_Actinolite_HS116.4B_ASDFRb_AREF
s07HYPRN_Actinolite_HS315.1B_ASDFRb_AREF
s07HYPRN_Actinolite_HS315.2B_ASDFRb_AREF

Tremolite

s07HYPRN_Tremolite_HS18.1B_ASDFRc_AREF
s07HYPRN_Tremolite_HS18.2B_ASDFRc_AREF
s07HYPRN_Tremolite_HS18.3_BECKc_AREF
s07HYPRN_Tremolite_HS18.3B_ASDFRc_AREF
s07HYPRN_Tremolite_HS18.3B_NIC4ccc_RREF
s07HYPRN_Tremolite_HS18.4B_ASDFRc_AREF
s07HYPRN_Tremolite_NMNH117611.HCl_BECKb_AREF
s07HYPRN_Tremolite_NMNH117611.HCL_NIC4bb_RREF

Serpentino
s07HYPRN_Serpentine_HS8.2B_ASDFRc_AREF
s07HYPRN_Serpentine_HS8.3B_ASDFRc_AREF
s07HYPRN_Serpentine_HS8.3B_BECKc_AREF
s07HYPRN_Serpentine_HS8.4B_ASDFRc_AREF
s07HYPRN_Serpentine_HS8.6_ASDFRc_AREF
s07HYPRN_Serpentine_HS318.1B_ASDFRc_AREF
s07HYPRN_Serpentine_HS318.2B_ASDFRc_AREF
s07HYPRN_Serpentine_HS318.3B_ASDFRc_AREF
s07HYPRN_Serpentine_HS318.4B_ASDFRc_AREF
s07HYPRN_Serpentine_HS318.4B_BECKc_AREF
s07HYPRN_Serpentine_HS318.6_ASDFRc_AREF



Ho provato ad usare TensorFlow per il calcolo ma mi e' decisamente ostico. Ho trovato che l'analisi del dataset Iris era stato trattato in questo post trattato con la libreria SkLearn,  con associate le librerie esterne Pandas e NumPy. I data sono tutti contenuti in un file, sia il training che il test dataset; il dataset sara' diviso in due dalla funzione train_test_split (in questo caso su 23 campioni viene scelto il 20% dei dati come parte di test del modello)

La prima riga del file all_data.txt e' costituito da un header con i nome delle 234 bande e un campo finale del nome (quindi la tabella e' di 235x24 celle)

-----------------------------------------
import pandas as pd
import numpy as np

dataset = pd.read_csv("all_data.txt")

X = dataset.iloc[:,:233].values
y = dataset['classe'].values

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = 82)

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

# Fitting Multiclass Logistic Classification to the Training set
from sklearn.linear_model import LogisticRegression

logisticregression = LogisticRegression()
logisticregression.fit(X_train, y_train)

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
verbose=0, warm_start=False)

# Predicting the Test set results
y_pred = logisticregression.predict(X_test)
print(y_pred)

#lets see the actual and predicted value side by side
y_compare = np.vstack((y_test,y_pred)).T

#actual value on the left side and predicted value on the right hand side
#printing the top 5 values
y_compare[:5,:]

# Making the Confusion Matrix
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
print(cm)

#finding accuracy from the confusion matrix.
a = cm.shape
corrPred = 0
falsePred = 0

for row in range(a[0]):
for c in range(a[1]):
if row == c:
corrPred +=cm[row,c]
else:
falsePred += cm[row,c]
print('Correct predictions: ', corrPred)
print('False predictions', falsePred)
print ('Accuracy of the multiclass logistic classification is: ', corrPred/(cm.sum()))
------------------------------

Il risultato finale e' seguente

[[2 0 0]
 [0 2 0]
 [0 0 1]]
('Correct predictions: ', 5)
('False predictions', 0)

('Accuracy of the multiclass logistic classification is: ', 1)


Per prova ho deliberatamente messo nel test dataset uno spettro con una classificazione sbagliata. Il risultato e' che l'algoritmo mi ha riportato un errore di classificazione...quindi direi che funziona

Il dataset e' sicuramente modesto e si possono fare miglioramenti ma direi che lo scopo e' stato raggiunto. La cosa interessante sarebbe ripetere questa esperienza con TensorFlow









Nessun commento:

Posta un commento