Lineární regrese TensorFlow s fazetou a termínem interakce

⚡ Chytré shrnutí

Lineární regrese na datech o bydlení v Bostonu se zlepšuje, když jsou nejprve nalezeny správné interakční členy. Google Fasety tyto vztahy vizuálně odhalují a dva zkřížené prvky snížily ztrátu v testu TensorFlow z 1650 na 1515.

  • 🔘 Data jako první: Pochopení distribucí a odlehlých hodnot předchází jakémukoli modelu, protože model pouze zobecňuje vzorec, který jste již našli.
  • ☑️ Přehled aspektů: Statistiky pro jednotlivé funkce odhalují chybějící hodnoty, sloupce s nulovým počtem hodnot a posun v rozdělení typu „train versus test“ v jedné tabulce.
  • (Tj. Hloubkový ponor do Facet: Fasetování pomocí X a Y promění třícestné vztahy v čitelný 2D graf obarvený cenovým kvartilem.
  • 🧪 Korelační odečet: Teplotní mapa a párová mřížka označují INDUS s NOX a DIS s oběma jako kandidáty na interakci.
  • 🛠️ Standardizace: Funkce preprocessing.scale vycentruje dvanáct souvislých sloupců dříve, než je odhad uvidí, a ponechá tak CHAS a PRICE nedotčené.
  • 📈 Naměřený zisk: Sečtením INDUS_NOS a INDUS_NOS_DIS se průměrná ztráta na testovacím splitu zvýšila z 86.89361 na 79.78876.

Lineární regrese TensorFlow s fazetou a interakčním členem

Lineární regrese TensorFlow

V tomto tutoriálu se naučíte, jak zkontrolovat data a připravit je k vytvoření jednoduché úlohy lineární regrese.

Tento tutoriál je rozdělen do dvou částí:

  • Hledejte interakci
  • Otestujte model

v předchozí tutoriál, použili jste bostonskou datovou sadu k odhadu střední ceny domu. Bostonská datová sada má malou velikost, pouze 506 pozorování. Tato datová sada je považována za měřítko pro vyzkoušení nových lineárních regresních algoritmů.

Datová sada se skládá z:

Proměnlivý Description
zn Podíl obytných pozemků v zónách pro pozemky o rozloze více než 25,000 XNUMX čtverečních stop.
indus Podíl nemaloobchodních obchodních akrů na město.
nox koncentrace oxidů dusnatých
rm průměrný počet pokojů na byt
stáří podíl vlastnických jednotek postavených před rokem 1940
dis vážené vzdálenosti do pěti pracovních center v Bostonu
daň sazba daně z nemovitosti v plné hodnotě za 10,000 XNUMX dolarů
ptratio poměr žáků a učitelů podle města
medv Střední hodnota domů obývaných vlastníky v tisících dolarech
zločin kriminalita na obyvatele podle města
Chas Dummy proměnná Charles River (1, pokud ohraničuje řeku, 0 v opačném případě)
B podíl černochů ve městě

V tomto tutoriálu odhadneme střední cenu pomocí lineárního regresoru, ale zaměřujeme se na jeden konkrétní proces strojové učení: "příprava dat."

Model zobecňuje vzor v datech. Chcete-li zachytit takový vzor, ​​musíte jej nejprve najít. Osvědčeným postupem je provést analýzu dat před spuštěním jakéhokoli algoritmu strojového učení.

Výběr správných funkcí má zásadní vliv na úspěch vašeho modelu. Představte si, že se snažíte odhadnout mzdu lidí, pokud neuvedete pohlaví jako kovariát, skončíte se špatným odhadem.

Dalším způsobem, jak vylepšit model, je podívat se na korelaci mezi nezávislou proměnnou. Zpět k příkladu, vzdělání si můžete představit jako vynikajícího kandidáta na předpovídání mzdy, ale i povolání. Je spravedlivé říci, že povolání závisí na úrovni vzdělání, totiž vyšší vzdělání často vede k lepšímu povolání. Pokud tuto myšlenku zobecníme, můžeme říci, že korelace mezi závisle proměnnou a vysvětlující proměnnou může být umocněna ještě další vysvětlující proměnnou.

Pro zachycení omezeného vlivu vzdělání na povolání můžeme použít interakční termín.

Interakční člen mezi vzděláním a povoláním znázorněný na mzdové křivce

Když se podíváte na mzdovou rovnici, vypadá to takto:

Mzdová rovnice rozšířená o interakční člen vzdělání krát povolání

If Symbol beta koeficientu pro interakční člen je pozitivní, pak to znamená, že další úroveň vzdělání přináší vyšší nárůst střední hodnoty domu pro vysokou úroveň obsazenosti. Jinými slovy, existuje interakční efekt mezi vzděláním a povoláním.

Stejná rodina odhadů také pohání lineární klasifikátor když je popisek třída, nikoli cena. V tomto tutoriálu se pokusíme zjistit, které proměnné mohou být vhodnými kandidáty pro interakční členy. Otestujeme, zda přidání tohoto druhu informací vede k lepší predikci ceny.

Souhrnná statistika

Než přistoupíte k modelu, můžete provést několik kroků. Jak již bylo zmíněno, model je zobecněním dat. Nejlepší je nejprve porozumět datům a poté provést predikci. Pokud neznáte svá data, máte malou šanci na vylepšení svého modelu.

Jako první krok načtěte data jako datový rámec pandas a vytvořte trénovací a testovací sadu.

Tipy: Pro tento tutoriál potřebujete mít nainstalované matplotlib a seaborn. PythonMůžete si nainstalovat Python balíček za letu s Jupyter. Vy Neměl by Udělej to

!conda install -- yes matplotlib

ale

import sys
!{sys.executable} -m pip install matplotlib # Already installed
!{sys.executable} -m pip install seaborn 

Všimněte si, že tento krok není nutný, pokud máte nainstalovaný matplotlib a seaborn.

Matplotlib je knihovna pro vytvoření grafu PythonSeaborn je knihovna pro statistickou vizualizaci postavená na knihovně matplotlib. Poskytuje...tractivní a krásné zápletky.

Níže uvedený kód importuje potřebné knihovny.

import pandas as pd
from sklearn import datasets
import tensorflow as tf
from sklearn.datasets import load_boston
import numpy as np

Knihovna sklearn obsahuje datovou sadu Boston. Pro import dat můžete zavolat jeho API.

Poznámka k verzi: load_boston byl zastaralý ve verzi scikit-learn 1.0 a odstraněno ve verzi scikit-learn 1.2 protože datová sada kóduje rasově zatíženou funkci. V aktuální instalaci použijte fetch_california_housing nebo si načtěte nezpracovaný soubor sami. Níže uvedený pracovní postup se nezměnil; liší se pouze zavaděč.

boston = load_boston()
df = pd.DataFrame(boston.data)

Názvy prvků jsou uloženy v objektu feature_names jako pole.

boston.feature_names

Výstup

array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')

Sloupce můžete přejmenovat.

df.columns = boston.feature_names
df['PRICE'] = boston.target
df.head(2)

První dva řádky datového rámce Boston po přejmenování sloupců

Převedete proměnnou CHAS jako řetězcovou proměnnou a označíte ji ano, pokud CHAS = 1 a ne, pokud CHAS = 0

df['CHAS'] = df['CHAS'].map({1:'yes', 0:'no'})
df['CHAS'].head(5)
0    no
1    no
2    no
3    no
4    no
Name: CHAS, dtype: object

U pand je rozdělení datové sady jednoduché. Náhodně rozdělíte datovou sadu na 80 procent trénovací sady a 20 procent testovací sady. Pandy má vestavěnou funkci vzorkování pro rozdělení datového rámce.

První parametr frac je hodnota od 0 do 1. Nastavíte ho na 0.8, abyste náhodně vybrali 80 procent datového rámce.

Funkce random_state opravuje náhodné zamíchání, takže pro všechny se vrátí stejné řádky.

### Create train/test set
df_train=df.sample(frac=0.8,random_state=200)
df_test=df.drop(df_train.index)

Můžete získat tvar dat. To by mělo být:

  • Souprava vlaku: 506*0.8 = 405
  • Testovací sada: 506*0.2 = 101
print(df_train.shape, df_test.shape)

Výstup

(405, 14) (101, 14)
df_test.head(5)

Výstup

CRIM ZN INDUS CHAS NOX RM STÁŘÍ DIS RAD DAŇ PTRATIO B LSTAT CENA
0 0.00632 18.0 2.31 Ne 0.538 6.575 65.2 4.0900 1.0 296.0 15.3 396.90 4.98 24.0
1 0.02731 0.0 7.07 Ne 0.469 6.421 78.9 4.9671 2.0 242.0 17.8 396.90 9.14 21.6
3 0.03237 0.0 2.18 Ne 0.458 6.998 45.8 6.0622 3.0 222.0 18.7 394.63 2.94 33.4
6 0.08829 12.5 7.87 Ne 0.524 6.012 66.6 5.5605 5.0 311.0 15.2 395.60 12.43 22.9
7 0.14455 12.5 7.87 Ne 0.524 6.172 96.1 5.9505 5.0 311.0 15.2 396.90 19.15 27.1

Data jsou chaotická; je často nevyvážený a posetý odlehlými hodnotami, které shazují analýzu a trénink strojového učení.

Prvním krokem k vyčištění datové sady je pochopení, kde je potřeba vyčistit. Čištění datové sady může být složité, zejména jakýmkoli zobecněným způsobem

Jedno Google Výzkumný tým pro tuto práci vyvinul nástroj s názvem Fazety což vám pomůže vizualizovat data a rozdělit je různými způsoby. To je dobrý výchozí bod pro pochopení uspořádání datové sady.

Fasety vám umožňují najít místa, kde data nevypadají zcela podle vašich očekávání.

Kromě jejich webové aplikace, Google usnadňuje vložení sady nástrojů do Jupyter notebooku.

Fazety mají dvě části:

  • Přehled faset
  • Fasets Deep Dive

Přehled faset

Přehled fazet poskytuje přehled datové sady. Přehled fazet rozděluje sloupce dat do řádků zobrazujících nejdůležitější informace

  1. procento chybějících pozorování
  2. minimální a maximální hodnoty
  3. statistiky, jako je průměr, medián a standardní odchylka.
  4. Přidá také sloupec, který ukazuje procento hodnot, které jsou nuly, což je užitečné, když je většina hodnot nula.
  5. Tato distribuce je možné vidět na testovací datové sadě i na trénovací sadě pro každou funkci. To znamená, že můžete znovu zkontrolovat, že test má podobnou distribuci jako tréninková data.

Toto je alespoň minimum, které je třeba udělat před jakýmkoli úkolem strojového učení. S tímto nástrojem vám tento zásadní krok neunikne a upozorní na některé abnormality.

Fasets Deep Dive

Facets Deep Dive je skvělý nástroj. Umožňuje vám získat přehled o vaší datové sadě a přiblížit si ji tak, abyste viděli jednotlivé části dat. To znamená, že můžete data rozebrat po řádcích a sloupcích napříč libovolnými prvky datové sady.

Tyto dva nástroje použijeme s datasetem Boston.

Hodnocení: Nemůžete používat Facets Overview a Facets Deep Dive současně. Chcete-li vyměnit nástroj, musíte nejprve vyčistit notebook.

Než bude možné použít kterýkoli z těchto nástrojů, je nutné do prostředí poznámkového bloku nainstalovat Facets.

Nainstalujte Facet

Pro většinu analýz můžete použít webovou aplikaci Facet. V tomto tutoriálu uvidíte, jak jej používat v rámci a Jupyter Notebook.

Nejprve musíte nainstalovat nbextensions. To se provádí pomocí tohoto kódu. Následující kód zkopírujete a vložíte do terminálu svého počítače.

pip install jupyter_contrib_nbextensions

Hned poté musíte naklonovat úložiště ve vašem počítači. Máte dvě možnosti:

Možnost 1) Zkopírujte a vložte tento kód do terminálu (Doporučeno)

Pokud nemáte na svém počítači nainstalovaný Git, přejděte sem URL Git pro Windows stránku pro stažení a postupujte podle pokynů. Jakmile budete hotovi, můžete použít příkaz git v terminálu pro uživatele Mac nebo výzvu Anaconda Windows uživatel

git clone https://github.com/PAIR-code/facets

Možnost 2) Přejít repozitář PAIR-code/fasets a stáhněte si úložiště.

Stránka repozitáře aspektů PAIR-code na GitHubu

Na stránce úložiště výše se nachází tlačítko pro stažení, které používá možnost 2. Pokud zvolíte první možnost, soubor skončí ve složce stažených souborů. Soubor můžete buď nechat stáhnout, nebo jej přetáhnout do jiné cesty.

Pomocí tohoto příkazového řádku můžete zkontrolovat, kde jsou fazety uloženy:

echo `pwd`/`ls facets`

Nyní, když jste našli Facets, musíte je nainstalovat Jupyter Notebook. Musíte nastavit pracovní adresář na cestu, kde jsou umístěny fazety.

Váš současný pracovní adresář a umístění Facets zip by měly být stejné.

Terminál zobrazující složku fasets v aktuálním pracovním adresáři

Výpis terminálu výše potvrzuje, že se Facet nachází v aktuálním pracovním adresáři. Musíte nasměrovat pracovní adresář na Facet:

cd facets

Chcete-li nainstalovat Facets Jupyter, máte dvě možnosti. Pokud jste nainstalovali Jupyter s Conda pro všechny uživatele zkopírujte tento kód:

jupyter nbextension install facets-dist/

Jinak použijte:

jupyter nbextension install facets-dist/ --user

Dobře, vše je připraveno. Otevřeme Přehled fazet.

Přehled faset v Jupyter

Přehled použití a Python skript pro výpočet statistik. Musíte importovat skript s názvem generic_feature_statistics_generator Jupyter. Nebojte se; skript je umístěn v souborech fazet.

Musíte najít jeho cestu. Dělá se to snadno. Otevřete fazety, otevřete soubor facets_overview a pak python. Zkopírujte cestu

Cesta k souboru složky facets_overview v jazyce Python

Poté se vraťte do Jupytera napište následující kód. Změňte cestu '/Users/Thomas/facets/facets_overview/python' na svou cestu.

# Add the facets overview python code to the python path# Add t 
import sys
sys.path.append('/Users/Thomas/facets/facets_overview/python')

Skript můžete importovat pomocí níže uvedeného kódu.

from generic_feature_statistics_generator import 
GenericFeatureStatisticsGenerator

Ve Windows se stane stejný kód

import sys
sys.path.append(r"C:\Users\Admin\Anaconda3\facets-master\facets_overview\python")

from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator

Chcete-li vypočítat statistiku funkcí, musíte použít funkci GenericFeatureStatisticsGenerator() a použijete objekt ProtoFromDataFrames. Datový rámec můžete předat ve slovníku. Pokud chceme například vytvořit souhrnnou statistiku pro vlakovou soupravu, můžeme si informace uložit do slovníku a použít je v objektu `ProtoFromDataFrames

'name': 'train', 'table': df_train

Název je název zobrazené tabulky a použijete název tabulky, pro kterou chcete vypočítat souhrn. Ve vašem příkladu je tabulka obsahující data df_train

# Calculate the feature statistics proto from the datasets and stringify it for use in facets overview
import base64

gfsg = GenericFeatureStatisticsGenerator()

proto = gfsg.ProtoFromDataFrames([{'name': 'train', 'table': df_train},
                                  {'name': 'test', 'table': df_test}])

#proto = gfsg.ProtoFromDataFrames([{'name': 'train', 'table': df_train}])
protostr = base64.b64encode(proto.SerializeToString()).decode("utf-8")

Nakonec stačí zkopírovat a vložit níže uvedený kód. Kód pochází přímo z GitHubu. Měli byste vidět toto:

Přehledová tabulka faset se souhrnnými statistikami pro jednotlivé funkce

# Display the facets overview visualization for this data# Displ 
from IPython.core.display import display, HTML

HTML_TEMPLATE = """<link rel="import" href="/nbextensions/facets-dist/facets-jupyter.html" >
        <facets-overview id="elem"></facets-overview>
        <script>
          document.querySelector("#elem").protoInput = "{protostr}";
        </script>"""
html = HTML_TEMPLATE.format(protostr=protostr)
display(HTML(html))

Korelační graf a párová mřížka

Po kontrole dat a jejich rozdělení můžete vykreslit korelační matici. Korelační matice vypočítá Pearsonův koeficient. Tento koeficient je omezený na -1 a 1, kde kladná hodnota značí kladnou korelaci a záporná hodnota negativní korelaci.

Zajímá vás, které proměnné mohou být dobrým kandidátem na termíny interakce.

Poznámka k verzi: maska ​​níže volá np.bool, alias, který byl v NumPy 1.20 zastaralý a odstraněno v NumPy 1.24Na nedávném NumPy stejný řádek vyvolává AttributeError: module 'numpy' has no attribute 'bool'vestavěný bool je náhrada za příchod.

## Choose important feature and further check with Dive
%matplotlib inline  
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="ticks")
# Compute the correlation matrix
corr = df.corr('pearson')
# Generate a mask for the upper triangle
mask = np.zeros_like(corr, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True
# Set up the matplotlib figure
f, ax = plt.subplots(figsize=(11, 9))

# Generate a custom diverging colormap
cmap = sns.diverging_palette(220, 10, as_cmap=True)

# Draw the heatmap with the mask and correct aspect ratio
sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,annot=True,
            square=True, linewidths=.5, cbar_kws={"shrink": .5})

Výstup

<matplotlib.axes._subplots.AxesSubplot at 0x1a184d6518>

Seabornova korelační tepelná mapa bostonských proměnných

Na výše uvedené tepelné mapě tmavší čtverce označují silnější korelace. Z matice můžete vidět:

  • LSTAT
  • RM

Silně korelují s PRICE. Dalším zajímavým rysem je silná pozitivní korelace mezi NOX a INDUS, což znamená, že se tyto dvě proměnné pohybují stejným směrem. Obě také korelují s PRICE. DIS také silně koreluje s INDUS a NOX.

Máte první náznak, že INDUS a NOX mohou být dobrými kandidáty na interakční termín a že by se mohlo zaměřit i na DIS.

Můžete jít trochu hlouběji vykreslením párové mřížky. Bude podrobněji ilustrovat korelační mapu, kterou jste předtím nakreslili.

Párová mřížka je složena následovně:

  • Horní část: Bodový pozemek s nasazenou čarou
  • Diagonální: Graf hustoty jádra
  • Spodní část: Graf hustoty s více proměnnými jádra

Zaměřujete se na čtyři nezávislé proměnné. Výběr odpovídá proměnným se silnou korelací s PRICE.

  • INDUS
  • NOX
  • RM
  • LSTAT

navíc CENA.

Hodnocení že standardní chyba je standardně přidána do bodového grafu.

attributes = ["PRICE", "INDUS", "NOX", "RM", "LSTAT"]

g = sns.PairGrid(df[attributes])
g = g.map_upper(sns.regplot, color="g")
g = g.map_lower(sns.kdeplot,cmap="Reds", shade=True, shade_lowest=False)
g = g.map_diag(sns.kdeplot)

Výstup

Párová mřížka Seaborn pro PRICE, INDUS, NOX, RM a LSTAT

Začněme horní částí:

  • Cena je negativně korelována s INDUS, NOX a LSTAT; pozitivně koreluje s RM.
  • Mezi LSTAT a PRICE existuje mírná nelinearita.
  • Existuje jako přímka, když je cena rovna 50. Z popisu datové sady byla PRICE zkrácena na hodnotu 50

Úhlopříčka: Zdá se, že NOX má dva shluky, jeden kolem 0.5 a jeden kolem 0.85.

Chcete-li se o tom dozvědět více, můžete se podívat na spodní část. Vícerozměrná hustota jádra je zajímavá v tom smyslu, že vybarvuje tam, kde je většina bodů. Rozdíl oproti bodovému grafu vykresluje hustotu pravděpodobnosti, i když v souboru dat pro danou souřadnici není žádný smysl. Když je barva silnější, znamená to vysokou koncentraci bodu kolem této oblasti.

Pokud zkontrolujete vícerozměrnou hustotu pro INDUS a NOX, můžete vidět pozitivní korelaci a dva shluky. Když je podíl průmyslu vyšší než 18, je koncentrace oxidů dusnatých vyšší než 0.6.

Můžete uvažovat o přidání interakce mezi INDUS a NOX v lineárním vztahu.

Nakonec můžete použít druhý nástroj vytvořený uživatelem Google, Hluboký pohled na fazety. Rozhraní je rozděleno do čtyř hlavních sekcí. Centrální oblast uprostřed je přizpůsobitelné zobrazení dat. V horní části panelu se nachází rozbalovací nabídka, kde můžete změnit uspořádání dat a ovládat fazety, umístění a barvu. Vpravo je podrobný pohled na konkrétní řádek dat. To znamená, že kliknutím na libovolný bod dat ve střední vizualizaci zobrazíte podrobnosti o daném datovém bodě.

Během kroku vizualizace dat vás zajímá párová korelace mezi nezávislou proměnnou na ceně domu. Zahrnuje však minimálně tři proměnné a práce s 3D grafy je komplikovaná.

Jedním ze způsobů, jak tento problém vyřešit, je vytvořit kategoriální proměnnou. To znamená, že můžeme vytvořit 2D graf a vybarvit tečky. Proměnnou PRICE můžete rozdělit do čtyř kategorií, přičemž každá kategorie je kvartil (tj. 0.25, 0.5, 0.75). Tuto novou proměnnou nazvete Q_PRICE.

## Check non linearity with important features
df['Q_PRICE'] =  pd.qcut(df['PRICE'], 4, labels=["Lowest", "Low", "Upper", "upper_plus"])
## Show non linearity between RM and LSTAT
ax = sns.lmplot(x="DIS", y="INDUS", hue="Q_PRICE", data=df, fit_reg = False,palette="Set3")

Bodový graf DIS oproti INDUS barevně definovaný cenovým kvartilem

Hloubkový pohled na používání Facet

Pro otevření Deep Dive je potřeba transformovat data do formátu JSON. Pandas na to má metodu: volání to_json na DataFrame.

První řádek kódu nastavuje velikost sprite podle toho, kolik řádků datová sada obsahuje.

df['Q_PRICE'] =  pd.qcut(df['PRICE'], 4, labels=["Lowest", "Low", "Upper", "upper_plus"])
sprite_size = 32 if len(df.index)>50000 else 64
jsonstr = df.to_json(orient='records')

Níže uvedený kód pochází z Google GitHub. Po spuštění kódu byste měli vidět toto:

Fasety Hluboký pohled na fasetovaný bodový pohled datové sady Boston

# Display thde Dive visualization for this data
from IPython.core.display import display, HTML

# Create Facets template  
HTML_TEMPLATE = """<link rel="import" href="/nbextensions/facets-dist/facets-jupyter.html">
        <facets-dive sprite-image-width="{sprite_size}" sprite-image-height="{sprite_size}" id="elem" height="600"></facets-dive>
        <script>
          document.querySelector("#elem").data = {jsonstr};
        </script>"""

# Load the json dataset and the sprite_size into the template
html = HTML_TEMPLATE.format(jsonstr=jsonstr, sprite_size=sprite_size)

# Display the template
display(HTML(html))

Zajímá vás, zda existuje souvislost mezi mírou odvětví, koncentrací oxidů, vzdáleností od úřadu práce a cenou domu.

Za tímto účelem nejprve rozdělíte data podle oborového rozsahu a barvy s cenovým kvartilem:

  • Vyberte fasetování X a zvolte INDUS.
  • Vyberte Display a zvolte DIS. Zabarví tečky s kvartilem ceny domu

Tmavší barvy zde znamenají větší vzdálenost k prvnímu úřadu práce.

Zatím to opět ukazuje, co víte, nižší míra odvětví, vyšší cena. Nyní se můžete podívat na rozdělení podle INDUX, podle NOX.

Vyberte fasetování Y a zvolte NOX.

Nyní můžete vidět, že dům daleko od prvního úřadu práce má nejnižší průmyslový podíl, a tedy nejnižší koncentraci oxidů. Pokud zvolíte zobrazení typu s Q_PRICE a přiblížíte levý dolní roh, uvidíte, o jaký typ ceny se jedná.

Máte další náznak, že interakce mezi IND, NOX a DIS mohou být dobrými kandidáty na vylepšení modelu.

Průzkum přinesl dvě kandidátské interakce, takže dalším krokem je jejich otestování v reálném modelu.

Lineární regrese s TensorFlow

V této části odhadnete lineární regresní model s TensorFlow API pro odhady. Postupujte následovně:

  • Připravte data
  • Odhadněte srovnávací model: Žádná interakce
  • Odhadněte model pomocí interakce

Poznámka k verzi: ο tf-estimator Balíček byl dodán ve finální verzi s TensorFlow 2.15 a chybí od verze TensorFlow 2.16 a novějších, takže tf.estimator.LinearRegressor běží pouze na TensorFlow 1.x, pokud jej nemigrujete do lineárního modelu Keras.

Nezapomeňte, že cílem strojového učení je minimalizovat chybu. V tomto případě zvítězí model s nejnižší střední kvadratickou chybou. Odhad TensorFlow tuto metriku automaticky vypočítá.

Údaje o přípravě

Ve většině případů je potřeba data transformovat. Proto je Přehled Facet fascinující. Z souhrnné statistiky jste viděli, že existují odlehlé hodnoty. Tyto hodnoty ovlivňují odhady, protože nevypadají jako populace, kterou analyzujete. Odlehlé hodnoty obvykle zkreslují výsledky. Například kladná odlehlá hodnota má tendenci koeficient nadhodnocovat.

Dobrým řešením tohoto problému je standardizace proměnné. Standardizace znamená směrodatnou odchylku jedna a průměr nula. Proces standardizace zahrnuje dva kroky. Za prvé, podřízenýtracts je průměrná hodnota proměnné. Za druhé, vydělí se směrodatnou odchylkou tak, aby rozdělení mělo jednotkovou směrodatnou odchylku.

Knihovna scikit-učit se je užitečné pro standardizaci proměnných. Pro tento účel můžete použít předzpracování modulů s objektovým měřítkem.

Ke škálování datové sady můžete použít funkci níže. Všimněte si, že neměníte měřítko sloupce štítku a kategoriálních proměnných.

from sklearn import preprocessing
def standardize_data(df): 
    X_scaled = preprocessing.scale(df[['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
       'TAX', 'PTRATIO', 'B', 'LSTAT']])
    X_scaled_df = pd.DataFrame(X_scaled, columns = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
       'TAX', 'PTRATIO', 'B', 'LSTAT'])
    df_scale = pd.concat([X_scaled_df,
                       df['CHAS'],
                       df['PRICE']],axis=1, join='inner')
    return df_scale

Funkci můžete použít k sestavení škálovaného vlaku/testovací sady.

df_train_scale = standardize_data(df_train)
df_test_scale = standardize_data(df_test)

Základní regrese: Benchmark

V první řadě trénujete a testujete model bez interakce. Účelem je zobrazit metriku výkonu modelu.

Způsob trénování modelu je přesně stejný jako v tutoriálu na API na vysoké úrovni. Budete používat TensorFlow estimator LinearRegressor.

Pro připomenutí, musíte vybrat:

  • funkce, které je třeba do modelu vložit
  • transformovat vlastnosti
  • sestrojte lineární regresor
  • vytvořte funkci input_fn
  • trénovat modelku
  • otestovat model

Všechny proměnné v datové sadě použijete k trénování modelu. Celkem existuje dvanáct spojitých proměnných a jedna kategoriální proměnná.

## Add features to the bucket: 
### Define continuous list
CONTI_FEATURES  = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT']
CATE_FEATURES = ['CHAS']

Prvky převedete na číselný sloupec nebo kategorický sloupec

continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]
#categorical_features = tf.feature_column.categorical_column_with_hash_bucket(CATE_FEATURES, hash_bucket_size=1000)
categorical_features = [tf.feature_column.categorical_column_with_vocabulary_list('CHAS', ['yes','no'])]

Model vytvoříte pomocí linearRegressor. Model uložíte do složky train_Boston

model = tf.estimator.LinearRegressor(    
	model_dir="train_Boston",     
    feature_columns=categorical_features + continuous_features)

Výstup

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train_Boston', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a19e76ac8>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

Každý sloupec ve vlakových nebo testovacích datech je převeden na tenzor pomocí funkce get_input_fn.

FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT', 'CHAS']
LABEL= 'PRICE'
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
    return tf.estimator.inputs.pandas_input_fn(
       x=pd.DataFrame({k: data_set[k].values for k in FEATURES}),
       y = pd.Series(data_set[LABEL].values),
       batch_size=n_batch,   
       num_epochs=num_epochs,
       shuffle=shuffle)

Model odhadnete na datech vlaku.

model.train(input_fn=get_input_fn(df_train_scale, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Výstup

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into train_Boston/model.ckpt.
INFO:tensorflow:loss = 56417.703, step = 1
INFO:tensorflow:global_step/sec: 144.457
INFO:tensorflow:loss = 76982.734, step = 101 (0.697 sec)
INFO:tensorflow:global_step/sec: 258.392
INFO:tensorflow:loss = 21246.334, step = 201 (0.383 sec)
INFO:tensorflow:global_step/sec: 227.998
INFO:tensorflow:loss = 30534.78, step = 301 (0.439 sec)
INFO:tensorflow:global_step/sec: 210.739
INFO:tensorflow:loss = 36794.5, step = 401 (0.477 sec)
INFO:tensorflow:global_step/sec: 234.237
INFO:tensorflow:loss = 8562.981, step = 501 (0.425 sec)
INFO:tensorflow:global_step/sec: 238.1
INFO:tensorflow:loss = 34465.08, step = 601 (0.420 sec)
INFO:tensorflow:global_step/sec: 237.934
INFO:tensorflow:loss = 12241.709, step = 701 (0.420 sec)
INFO:tensorflow:global_step/sec: 220.687
INFO:tensorflow:loss = 11019.228, step = 801 (0.453 sec)
INFO:tensorflow:global_step/sec: 232.702
INFO:tensorflow:loss = 24049.678, step = 901 (0.432 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train_Boston/model.ckpt.
INFO:tensorflow:Loss for final step: 23228.568.


<tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a19e76320>

Nakonec odhadnete výkony modelu na testovací sadě

model.evaluate(input_fn=get_input_fn(df_test_scale, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Výstup

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-29-02:40:43
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train_Boston/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-29-02:40:43
INFO:tensorflow:Saving dict for global step 1000: average_loss = 86.89361, global_step = 1000, loss = 1650.9785


{'average_loss': 86.89361, 'global_step': 1000, 'loss': 1650.9785}

Ztráta modelu je 1650.9785. Toto je metrika, kterou je třeba překonat v další části

Vylepšit model: Interakční termín

V první části tutoriálu jste si všimli zajímavého vztahu mezi proměnnými. Různé vizualizační techniky odhalily, že INDUS a NOX jsou vzájemně propojeny a zesilují svůj vliv na cenu. Interakce mezi INDUS a NOX nejen ovlivňuje cenu, ale tento efekt je také silnější, když interaguje s DIS.

Je čas zobecnit tuto myšlenku a zjistit, zda lze vylepšit predikci modelu.

Do každé datové sady je třeba přidat dva nové sloupce: train a test. Za tímto účelem vytvoříte jednu funkci pro výpočet interakčního členu a druhou pro výpočet trojitého interakčního členu. Každá funkce vygeneruje jeden sloupec. Po vytvoření nových proměnných je můžete zřetězit do trénovací a testovací datové sady.

Nejprve musíte vytvořit novou proměnnou pro interakci mezi INDUS a NOX.

Funkce níže vrací dva datové rámce, vlak a test, s interakcí mezi var_1 a var_2, ve vašem případě INDUS a NOX.

def interaction_term(var_1, var_2, name):
    t_train = df_train_scale[var_1]*df_train_scale[var_2]
    train = t_train.rename(name)
    t_test = df_test_scale[var_1]*df_test_scale[var_2]
    test = t_test.rename(name)
    return train, test

Uložíte dva nové sloupce

interation_ind_ns_train, interation_ind_ns_test= interaction_term('INDUS', 'NOX', 'INDUS_NOS')
interation_ind_ns_train.shape
(325,)

Za druhé, vytvoříte druhou funkci pro výpočet členu trojité interakce.

def triple_interaction_term(var_1, var_2,var_3, name):
    t_train = df_train_scale[var_1]*df_train_scale[var_2]*df_train_scale[var_3]
    train = t_train.rename(name)
    t_test = df_test_scale[var_1]*df_test_scale[var_2]*df_test_scale[var_3]
    test = t_test.rename(name)
    return train, test
interation_ind_ns_dis_train, interation_ind_ns_dis_test= triple_interaction_term('INDUS', 'NOX', 'DIS','INDUS_NOS_DIS')

Nyní, když máte všechny potřebné sloupce, můžete je přidat do trénovací a testovací datové sady. Tyto dva nové datové rámce pojmenujete:

  • df_train_new
  • df_test_new
df_train_new = pd.concat([df_train_scale,
                          interation_ind_ns_train,
                          interation_ind_ns_dis_train],
                         axis=1, join='inner')
df_test_new = pd.concat([df_test_scale,
                         interation_ind_ns_test,
                         interation_ind_ns_dis_test],
                         axis=1, join='inner')
df_train_new.head(5)

Výstup

Trénovací datový rámec s připojenými sloupci INDUS_NOS a INDUS_NOS_DIS

To je vše: můžete odhadnout nový model s interakčními členy a zjistit, jaká je metrika výkonu.

CONTI_FEATURES_NEW  = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT',
                       'INDUS_NOS', 'INDUS_NOS_DIS']
### Define categorical list
continuous_features_new = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES_NEW]
model = tf.estimator.LinearRegressor(
    model_dir="train_Boston_1", 
    feature_columns= categorical_features + continuous_features_new)

Výstup

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train_Boston_1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a1a5d5860>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

Code

FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT','INDUS_NOS', 'INDUS_NOS_DIS','CHAS']
LABEL= 'PRICE'
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
    return tf.estimator.inputs.pandas_input_fn(
       x=pd.DataFrame({k: data_set[k].values for k in FEATURES}),
       y = pd.Series(data_set[LABEL].values),
       batch_size=n_batch,   
       num_epochs=num_epochs,
       shuffle=shuffle)
model.train(input_fn=get_input_fn(df_train_new, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Výstup

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into train_Boston_1/model.ckpt.
INFO:tensorflow:loss = 56417.703, step = 1
INFO:tensorflow:global_step/sec: 124.844
INFO:tensorflow:loss = 65522.3, step = 101 (0.803 sec)
INFO:tensorflow:global_step/sec: 182.704
INFO:tensorflow:loss = 15384.148, step = 201 (0.549 sec)
INFO:tensorflow:global_step/sec: 208.189
INFO:tensorflow:loss = 22020.305, step = 301 (0.482 sec)
INFO:tensorflow:global_step/sec: 213.855
INFO:tensorflow:loss = 28208.812, step = 401 (0.468 sec)
INFO:tensorflow:global_step/sec: 209.758
INFO:tensorflow:loss = 7606.877, step = 501 (0.473 sec)
INFO:tensorflow:global_step/sec: 196.618
INFO:tensorflow:loss = 26679.76, step = 601 (0.514 sec)
INFO:tensorflow:global_step/sec: 196.472
INFO:tensorflow:loss = 11377.163, step = 701 (0.504 sec)
INFO:tensorflow:global_step/sec: 172.82
INFO:tensorflow:loss = 8592.07, step = 801 (0.578 sec)
INFO:tensorflow:global_step/sec: 168.916
INFO:tensorflow:loss = 19878.56, step = 901 (0.592 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train_Boston_1/model.ckpt.
INFO:tensorflow:Loss for final step: 19598.387.


<tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a1a5d5e10>
model.evaluate(input_fn=get_input_fn(df_test_new, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

Výstup

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-29-02:41:14
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train_Boston_1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-29-02:41:14
INFO:tensorflow:Saving dict for global step 1000: average_loss = 79.78876, global_step = 1000, loss = 1515.9863


{'average_loss': 79.78876, 'global_step': 1000, 'loss': 1515.9863}

Nová ztráta je 1515.9863. Pouhým přidáním dvou nových proměnných jste byli schopni snížit ztrátu. To znamená, že můžete udělat lepší předpověď než s modelem benchmarku.

Model Sada funkcí Adresář modelů průměrná_ztráta pryč
měřítko 12 standardizovaných kontinuálních kolon plus CHAS vlak_Boston 86.89361 1650.9785
S interakcí Benchmark plus INDUS_NOS a INDUS_NOS_DIS vlak_Boston_1 79.78876 1515.9863

Oba údaje pocházejí ze stejného 101řádkového testovacího rozdělení, takže pokles průměrné ztráty o zhruba 8 procent lze připsat pouze dvěma sloupcům interakcí.

Nejčastější dotazy

Ve verzi scikit-learn 1.0 byla tato funkce zastaralá a ve verzi 1.2 odstraněna. Datová sada obsahuje funkci založenou na předpokladu o rasové sebesegregaci a cenách domů a původní studie nikdy neověřila její předpoklad týkající se kvality ovzduší. Obvyklými náhradami jsou bydlení v Kalifornii nebo Ames.

Polynomický člen umocní nebo umocní jednu proměnnou na třetí mocninu, aby ohnul svou vlastní křivku. Interakce násobí dvě různé proměnné, takže sklon jedné závisí na úrovni druhé. Tento tutoriál vytvoří druhý druh, INDUS krát NOX.

Hledejte páry, které korelují navzájem a s cílem. Pearsonova tepelná mapa a párová mřížka to dělají vizuálně; zde se INDUS a NOX shlukují a oba... track PRICE, což je signál ospravedlňující jejich překročení.

Automatizované knihovny pro inženýrství prvků generují kandidátské transformace a křížení, porovnávají každý z nich s rezervou a ponechávají pouze ty, které snižují chybu. To nahrazuje ruční čtení tepelné mapy, které je zde zobrazeno, i když člověk musí stále ověřit, co znamenají vygenerované sloupce.

Copilot si dobře poradí s repetitivními šablonami pro vykreslování – párové mřížky, maskované tepelné mapy, HTML šablony pro Facet. Podívejte se na argumenty, které navrhuje, protože Seaborn jich několik přejmenoval a Copilot rád zkombinuje staré a současné signatury.

Ne. Ztráty musí být porovnávány na stejném stanoveném rozdělení, jako je tomu zde. Ztráta, která připadá pouze na trénovací data, signalizuje přeplnění a přidání sloupců téměř vždy zlepšuje trénovací splnění, ať už obsahují skutečné informace, nebo ne.

Maska používá np.bool, alias, který byl v NumPy 1.20 zastaralý a v 1.24 odstraněn. Nedávné instalace vyvolávají AttributeError. Nahrazení vestavěného bool ponechává chování stejné; np.bool_ funguje také, pokud potřebujete skalární typ NumPy.

CHAS je kategorický příznak ano/ne a PRICE je popisek. Centrování a škálování figuríny ztěžuje čtení jejího koeficientu bez změny přizpůsobení a škálování popisku by jednoduše změnilo škálování hlášené ztráty. Standardizováno je pouze dvanáct spojitých prediktorů.

Shrňte tento příspěvek takto: