Umění najít nejlepší funkce pro strojové učení

Výběr funkcí

V mnoha situacích nebude výsledkem použití všech funkcí dostupných v datovém souboru nejpředvídatelnější model. V závislosti na typu použitého modelu, velikosti datové sady a různých dalších faktorech, včetně nadbytečných rysů, může dojít ke snížení výkonnosti modelu.

Výběr rysů má tři hlavní cíle.

  • Zlepšit přesnost, s níž je model schopen předpovídat pro nová data.
  • Snížit výpočetní náklady.
  • Vytvořit lépe interpretovatelný model.

Existuje řada důvodů, proč můžete odstranit některé funkce místo jiných. Patří sem vztahy, které existují mezi rysy, zda existuje statistický vztah k cílové proměnné nebo zda je dostatečně významný, nebo hodnota informace obsažené v daném rysu.

Výběr rysů lze provést ručně analýzou datového souboru před i po tréninku nebo pomocí automatizovaných statistických metod.

Ruční výběr rysů

Existuje řada důvodů, proč můžete chtít odstranit rys z fáze tréninku. Patří mezi ně:

  • Funkce, která je vysoce korelovaná s jinou funkcí v datové sadě. Pokud tomu tak je, pak oba rysy v podstatě poskytují stejné informace. Některé algoritmy jsou na korelované rysy citlivé.
  • Funkce, které neposkytují téměř žádnou informaci. Příkladem může být rys, u kterého má většina příkladů stejnou hodnotu.
  • Funkce, které mají malý nebo žádný statistický vztah k cílové proměnné.

Funkce mohou být vybrány prostřednictvím analýzy dat provedené buď před trénováním modelu, nebo po něm. Zde je uvedeno několik běžných technik pro ruční provedení výběru prvků.

Korelační graf

Jednou z ručních technik pro provedení výběru prvků je vytvoření vizualizace, která vykreslí míru korelace pro každý prvek v souboru dat. K tomuto účelu lze dobře použít knihovnu Seaborn v jazyce Python. Níže uvedený kód vytvoří korelační graf pro rysy v souboru dat o rakovině prsu, který je k dispozici z rozhraní API scikit-learn.

# library imports
import pandas as pd
from sklearn.datasets import load_breast_cancer
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
import numpy as np# load the breast_cancer data set from the scikit-learn api
breast_cancer = load_breast_cancer()
data = pd.DataFrame(data=breast_cancer, columns = breast_cancer)
data = breast_cancer
data.head()# use the pands .corr() function to compute pairwise correlations for the dataframe
corr = data.corr()
# visualise the data with seaborn
mask = np.triu(np.ones_like(corr, dtype=np.bool))
sns.set_style(style = 'white')
f, ax = plt.subplots(figsize=(11, 9))
cmap = sns.diverging_palette(10, 250, as_cmap=True)
sns.heatmap(corr, mask=mask, cmap=cmap,
square=True,
linewidths=.5, cbar_kws={"shrink": .5}, ax=ax)

Ve výsledné vizualizaci můžeme identifikovat některé rysy, které jsou úzce korelované, a proto můžeme chtít některé z nich odstranit, a některé rysy, které mají velmi nízkou korelaci s cílovou proměnnou, které můžeme chtít také odstranit.

Důležitost prvků

Po natrénování modelu je možné použít další statistickou analýzu, abychom pochopili, jaký vliv mají prvky na výstup modelu, a na základě toho určit, které prvky jsou nejužitečnější.

K určení důležitosti rysů existuje řada nástrojů a technik. Některé techniky jsou jedinečné pro konkrétní algoritmus, zatímco jiné lze použít na širokou škálu modelů a jsou známé jako model agnostické.

Pro ilustraci významnosti rysů použiji vestavěnou metodu významnosti rysů pro klasifikátor náhodného lesa v programu scikit-learn. Níže uvedený kód přizpůsobí klasifikátor a vytvoří graf zobrazující importance rysů.

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split# Spliiting data into test and train sets
X_train, X_test, y_train, y_test = train_test_split(data.drop('target', axis=1), data, test_size=0.20, random_state=0)# fitting the model
model = RandomForestClassifier(n_estimators=500, n_jobs=-1, random_state=42)
model.fit(X_train, y_train)# plotting feature importances
features = data.drop('target', axis=1).columns
importances = model.feature_importances_
indices = np.argsort(importances)plt.figure(figsize=(10,15))
plt.title('Feature Importances')
plt.barh(range(len(indices)), importances, color='b', align='center')
plt.yticks(range(len(indices)), for i in indices])
plt.xlabel('Relative Importance')
plt.show()

Tím získáte dobrý ukazatel těch rysů, které mají na model vliv, a těch, které vliv nemají. Po analýze tohoto grafu se můžeme rozhodnout odstranit některé méně důležité rysy.

Automatický výběr rysů

Existuje řada mechanismů, které používají statistické metody k automatickému nalezení optimální sady rysů, které se použijí v modelu. Knihovna scikit-learn obsahuje řadu metod, které poskytují velmi jednoduchou implementaci mnoha z těchto technik.

Prahová hodnota rozptylu

Ve statistice je rozptyl čtvercová odchylka proměnné od jejího průměru, jinými slovy, jak moc jsou datové body pro danou proměnnou rozprostřeny.

Předpokládejme, že vytváříme model strojového učení pro detekci rakoviny prsu a soubor dat obsahuje logickou proměnnou pro pohlaví. Tento soubor dat se bude pravděpodobně skládat téměř výhradně z jediného pohlaví, a proto by téměř všechny datové body měly hodnotu 1. Tato proměnná by měla extrémně nízký rozptyl a pro predikci cílové proměnné by nebyla vůbec užitečná.

Jedná se o jeden z nejjednodušších přístupů k výběru příznaků. Knihovna scikit-learn obsahuje metodu nazvanou VarianceThreshold . Tato metoda přijme prahovou hodnotu a po dosazení do množiny příznaků odstraní všechny příznaky pod touto prahovou hodnotou. Výchozí hodnota pro práh je 0 a tím se odstraní všechny rysy s nulovým rozptylem, nebo jinými slovy, kde jsou všechny hodnoty stejné.

Použijeme toto výchozí nastavení na soubor dat o rakovině prsu, který jsme použili dříve, abychom zjistili, zda jsou nějaké rysy odstraněny.

from sklearn.feature_selection import VarianceThresholdX = data.drop('target', axis=1)
selector = VarianceThreshold()
print("Original feature shape:", X.shape)new_X = selector.fit_transform(X)
print("Transformed feature shape:", new_X.shape)

Výstup ukazuje, že transformované rysy mají stejný tvar, takže všechny rysy mají alespoň nějaký rozptyl.

Výběr jednorozměrných rysů

Výběr jednorozměrných rysů aplikuje na rysy jednorozměrné statistické testy a vybere ty, které v těchto testech dopadnou nejlépe. Univariační testy jsou testy, které zahrnují pouze jednu závislou proměnnou. Patří sem analýza rozptylu (ANOVA), lineární regrese a t-testy středních hodnot.

Scikit-learn poskytuje řadu metod výběru příznaků, které aplikují řadu různých univariačních testů k nalezení nejlepších příznaků pro strojové učení.

Na soubor dat o rakovině prsu použijeme jednu z nich, známou jako SelectKBest. Tato funkce vybere k nejlepších rysů na základě jednorozměrného statistického testu. Výchozí hodnota k je 10, takže bude zachováno 10 rysů, a výchozí test je f_classif.

Test f_classif se používá pro kategoriální cíle, jako je tomu v případě souboru dat o rakovině prsu. Pokud je cílem spojitá proměnná, měla by se použít f_regression. Test f_classif je založen na statistickém testu analýzy rozptylu (ANOVA), který porovnává průměry několika skupin, nebo v našem případě rysů, a určuje, zda se některý z těchto průměrů od sebe statisticky významně liší.

Následující kód aplikuje tuto funkci s použitím výchozích parametrů na soubor dat o rakovině prsu.

from sklearn.feature_selection import SelectKBestX = data.drop('target', axis=1)
y = data
selector = SelectKBest()
print("Original feature shape:", X.shape)new_X = selector.fit_transform(X, y)
print("Transformed feature shape:", new_X.shape)

Výstup ukazuje, že funkce zredukovala rysy na deset. Můžeme experimentovat s různými hodnotami k, trénovat více modelů, dokud nenajdeme optimální počet funkcí.

Rekurzivní eliminace funkcí

Tato metoda provádí trénování modelu na postupně stále menší a menší sadě funkcí. Pokaždé se vypočítají importance nebo koeficienty rysů a rysy s nejnižším skóre se odstraní. Na konci tohoto procesu je známa optimální sada rysů.

Jelikož tato metoda zahrnuje opakované trénování modelu, musíme nejprve instanciovat odhad. Tato metoda také nejlépe funguje, pokud jsou data nejprve škálována, takže jsem přidal krok předzpracování, který normalizuje rysy.

from sklearn.feature_selection import RFECV
from sklearn.svm import SVR
from sklearn import preprocessingX_normalized = preprocessing.normalize(X, norm='l2')
y = yestimator = SVR(kernel="linear")
selector = RFECV(estimator, step=1, cv=2)
selector = selector.fit(X, y)
print("Features selected", selector.support_)
print("Feature ranking", selector.ranking_)

Níže uvedený výstup ukazuje vybrané rysy a jejich pořadí.

Příznakové inženýrství

Pokud je cílem výběru příznaků snížit dimenzionalitu datové sady odstraněním nepotřebných příznaků, příznakové inženýrství se zabývá transformací stávajících příznaků a konstrukcí nových příznaků s cílem zlepšit výkon modelu.

Existují tři hlavní důvody, proč můžeme potřebovat provést inženýrství příznaků, abychom vytvořili optimální model.

  1. Příznaky nelze použít v jejich surové podobě. To se týká rysů, jako jsou data a časy, kdy model strojového učení může využít informace v nich obsažené pouze tehdy, jsou-li transformovány do číselné reprezentace, např. celočíselné reprezentace dne v týdnu.
  2. Rysy lze použít v jejich surové podobě, ale informace obsažená v rysu je silnější, jsou-li data agregována nebo reprezentována jiným způsobem. Příkladem zde může být rys obsahující věk osoby, agregace věku do kbelíků nebo košů může lépe reprezentovat vztah k cíli.
  3. Rys sám o sobě nemá dostatečně silný statistický vztah k cíli, ale v kombinaci s jiným rysem má smysluplný vztah. Řekněme, že máme soubor dat, který má řadu rysů založených na úvěrové historii skupiny zákazníků a cíl, který označuje, zda nespláceli úvěr. Předpokládejme, že máme výši úvěru a hodnotu platu. Pokud bychom je spojili do nového rysu nazvaného „poměr půjčky a platu“, může to poskytnout více nebo lepší informace než tyto rysy samotné.

Ruční inženýrství rysů

Inženýrství rysů lze provádět pomocí analýzy dat, intuice a znalostí domény. Často se provádějí podobné techniky jako při ručním výběru příznaků.

Například pozorování toho, jak příznaky korelují s cílovou proměnnou a jak si vedou z hlediska důležitosti příznaků, naznačuje, které příznaky je třeba dále zkoumat z hlediska analýzy.

Pokud se vrátíme k příkladu datové sady o půjčkách, představme si, že máme proměnnou věk, která se z korelačního grafu zdá mít určitý vztah k cílové proměnné. Při další analýze tohoto vztahu bychom mohli zjistit, že ti, kteří nesplácejí, jsou vychýleni směrem k určité věkové skupině. V tomto případě bychom mohli vytvořit příznak, který tuto věkovou skupinu vybere, a to může modelu poskytnout lepší informace.

Automatické inženýrství příznaků

Ruční inženýrství příznaků může být extrémně časově náročný proces a vyžaduje velké množství lidské intuice a znalosti domény, aby byl správný. Existují nástroje, které mají schopnost automaticky syntetizovat velké množství nových rysů.

Příkladem nástroje, který může provádět automatizované inženýrství rysů na souboru dat, je knihovna Featuretools v jazyce Python. Nainstalujme si tuto knihovnu a projděme si příklad automatizovaného feature engineeringu na souboru dat o rakovině prsu.

Knihovnu Featuretools lze nainstalovat pomocí pip.

pip install featuretools

Knihovna Featuretools je určena pro práci s relačními soubory dat (tabulky nebo datové rámce, které lze spojit pomocí jedinečného identifikátoru). Knihovna featuretools označuje každou tabulku jako entitu.

Soubor dat o rakovině prsu se skládá pouze z jedné entity, ale přesto můžeme pomocí featuretools generovat rysy. Nejprve však musíme vytvořit nový sloupec obsahující jedinečný identifikátor. Níže uvedený kód použije index datového rámce k vytvoření nového sloupce id.

data = data.index + 1

Následujícím krokem importujeme featuretools a vytvoříme sadu entit.

import featuretools as ftes = ft.EntitySet(id = 'data')
es.entity_from_dataframe(entity_id = 'data', dataframe = data, index = 'id')

Tím získáme následující výstup.

Nyní můžeme použít knihovnu k provedení syntézy rysů.

feature_matrix, feature_names = ft.dfs(entityset=es, 
target_entity = 'data',
max_depth = 2,
verbose = 1,
n_jobs = 3)

Featuretools vytvořil 31 nových funkcí.

Všechny nové funkce můžeme zobrazit spuštěním následujícího příkazu.

feature_matrix.columns

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.