Lab 09 Wybór cech z sygnału EMG
Lab9. Wybór cech z sygnału EMG
Wprowadzenie
Dzisiejsze zajęcia dotyczą problemu wyboru cech sygnału EMG. Metody były omawiane na wykładzie. W praktyce często używa się metod owijających, których celem jest wybór zestawu cech maksymalizującego dokładność modelu. Z uwagi na dużą złożoność obliczeniową, zajmiemy się metodami wybór cech opartymi o model lasu drzew decyzyjnych.
Poniżej na 3 kolejnych wykresach możesz zobaczyć jakie są wyniki klasyfikacji (z kroswalidacją) dla zbioru,którym dzisiaj będziesz się zajmował,w przypadku, gdy używa się wszystkie cechu (984 -zbiór oznaczony jako all
oraz zredukowany zestaw cech Hudgkin
, Du
, RMS
).
Porównanie kilku klasyfikatorów i cech:
Porównanie skuteczności klasyfikacji dla 24 kanałów:
Porównanie skuteczności klasyfikacji dla 8 kanałów (nr 9-16):
Zadanie
- Dany jest zbiór danych zawierający dwa zbiory danych (każdy zbiór składa się ze zbioru uczącego i testowego). Zbiory zawierają po 984, wyznaczone cechy. Nazwy kolumn zawierających cechy mają formę:
input_(NR)_(cecha)_(kanal)
np.:input_456_MYOP_1
jest cechąMYOP
wyznaczoną dla kanału 1. - Uruchom następujący kod umożliwiający określenie istotnych cech:
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import precision_score
from sklearn.inspection import permutation_importance
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
='.' #dataset folder
path
= pd.read_hdf(f'{path}/train_03_2018-06-14_2_All')
data_train= pd.read_hdf(f'{path}/test_03_2018-06-14_2_All')
data_test= list(data_train.filter(regex='input').columns)
columns
= data_train[columns]
X_train = data_train['output_0']
y_train = data_test[columns]
X_test = data_test['output_0']
y_test
= RandomForestClassifier(random_state=100)
clf = clf.fit(X_train,y_train)
clf_full = clf.predict(X_test)
preds
print(precision_score(preds, y_test, average='macro'))
print(confusion_matrix(y_test, preds))
- Przeanalizuj wyniki oceny ważności cech za pomocą lasu drzew decyzyjnych:
=20 #number of top features to show
top_n= clf.feature_importances_
tree_feature_importances = tree_feature_importances.argsort()
sorted_idx = sorted_idx[-top_n:]
sorted_idx = np.arange(0, len(sorted_idx))
y_ticks = [columns[i] for i in sorted_idx]
cols_ord = plt.subplots()
fig, ax
ax.barh(y_ticks, tree_feature_importances[sorted_idx])
ax.set_yticks(y_ticks)
ax.set_yticklabels(cols_ord)"Random Forest Feature Importances")
ax.set_title(
fig.tight_layout() plt.show()
- Porównaj otrzymane wyniki z oceną istotności cech otrzymaną z testu permutacyjnego dla zbioru testowego:
= permutation_importance(clf, X_test, y_test, n_repeats=10,
result =0, n_jobs=2)
random_state= result.importances_mean.argsort()[-30:]
sorted_idx
= plt.subplots()
fig, ax =False, labels=X_test.columns[sorted_idx])
ax.boxplot(result.importances[sorted_idx].T, vert"Permutation Importances (test set)")
ax.set_title(
fig.tight_layout() plt.show()
- Powodem dla którego test permutacyjny zwraca wynik, nie pozwalający na ocenę istotności cech, jest duża liczba cech skorelowanych. Należy więc usunąć cechy które są silnie zależne od siebie. Proces ten bedzie złożony z 2 faz: wyboru cech oraz wyboru kanałów
- Dokonaj analizy podobieństwa cech za pomocą dendrogramu, zakładając że analizujemy podobieństwo cech wyznaczonych dla jednego kanału:
import numpy as np
from scipy.cluster.hierarchy import dendrogram, linkage, distance, fcluster
from matplotlib import pyplot as plt
= data_train.filter(regex='input.*12$')
df = df.corr().values
corr
= distance.pdist(np.abs(corr))
pdist = linkage(pdist, method='ward')
Z
= list(df.columns)
labelList =(15, 12))
plt.figure(figsize
dendrogram(
Z,='right',
orientation=labelList,
labels='descending',
distance_sort=False
show_leaf_counts
)
plt.show()=2.0
th=th, c='grey', lw=1, linestyle='dashed')
plt.axvline(x
Które cechy są podobne, ile jest różnych klastrów na zaproponowanym poziomie odcięcia?
- Usuń cechy podobne, wybierając jako reprezentanta pierwszą cechę z grupy, następnie wygeneruj cechy dla wszystkich kanałów:
= fcluster(Z, th, 'distance')
idx = [[id, v.split('_')[2]] for id, v in zip(idx, df.columns)]
v = pd.DataFrame(v, columns=['cluster', 'feature']).groupby('cluster').first()
selected_features
#generacja cech dla wszystkich kanałów
= list([])
columns for feature in selected_features['feature']:
= data_train.filter(regex=f'input_\d+_{feature}_').columns
col_f columns.extend(col_f)
- Sprawdź jaki będzie wynik klasyfikacji oraz czy możliwa jest ocena istotności cech za pomocą testu permutacyjnego?
- Analogicznie do procedury z pkt 7. dokonaj redukcji liczby kanałów. Załóż, że ocena będzie prowadzona dla jednej cechy (
RMS
) wyznaczonej dla wszystkich kanałów. Przyjmij próg odcięcia dla wyboru grup cech th=0.2. Zmodyfikuj kod z pkt 7. w taki sposób, by listacolumns
zawierała wyłączenie kolumny zgodne z zredukowaną listą cech oraz elektrod. - Sprawdź jaki będzie wynik klasyfikacji oraz czy możliwa jest ocena istotności cech za pomocą testu permutacyjnego?
- Z listy cech wyznaczonej z testu permutacyjnego i ułożonej w kolejności od najbardziej istotnej do najmniej istotnej wybierz top-15 cech i wyznacz dokładność klasyfikacji, porównaj ją z dokładnością dla zbioru zredukowanego cech (po przycięciu dendrogramu) oraz pełnego zbioru cech?
- Wczytaj dane uczące i testowe zarejestrowane dla tej samej osoby w inny dzień (
train/test_03_2018-05-11_2_All
)i oceń, powtarzając procedurę z pkt 11, czy wybrany zbiór cech działa poprawnie również dla tych danych?