Regresia liniară TensorFlow cu fațetă și termen de interacțiune
⚡ Rezumat inteligent
Regresia liniară asupra datelor privind locuințele din Boston se îmbunătățește atunci când se găsesc mai întâi termenii de interacțiune corecți. Google Fațetele expun vizual aceste relații, iar două caracteristici încrucișate reduc pierderea testului TensorFlow de la 1650 la 1515.
Regresie liniară TensorFlow
În acest tutorial, veți învăța cum să verificați datele și să le pregătiți pentru a crea o sarcină simplă de regresie liniară.
Acest tutorial este împărțit în două părți:
- Căutați interacțiune
- Testați modelul
În tutorialul anterior, ați folosit setul de date Boston pentru a estima prețul mediu al unei case. Setul de date Boston are o dimensiune mică, cu doar 506 observații. Acest set de date este considerat un punct de referință pentru a încerca noi algoritmi de regresie liniară.
Setul de date este compus din:
| Variabil | Descriere |
|---|---|
| zn | Proporția de teren rezidențial zonat pentru loturi de peste 25,000 mp. |
| Indus | Proporția de acri comerciale non-retail pe oraș. |
| nox | concentrația de oxizi nitrici |
| rm | numărul mediu de camere pe locuință |
| vârstă | proporția unităților ocupate de proprietar construite înainte de 1940 |
| spune | distanțe ponderate până la cinci centre de angajare din Boston |
| impozit | cota de impozit pe proprietate la valoarea întreagă pe 10,000 de dolari |
| ptratio | raportul elev-profesor de către un oraș |
| medv | Valoarea mediană a caselor ocupate de proprietari în mii de dolari |
| crim | rata criminalității pe cap de locuitor pe oraș |
| Chas | Variabila inactivă Charles River (1 dacă limitează râul; 0 în caz contrar) |
| B | proporția negrilor de la oraș |
În acest tutorial, vom estima prețul mediu folosind un regresor liniar, dar accentul se pune pe un anumit proces de masina de învățare: „pregătirea datelor”.
Un model generalizează modelul în date. Pentru a captura un astfel de model, trebuie să-l găsiți mai întâi. O bună practică este să efectuați o analiză a datelor înainte de a rula orice algoritm de învățare automată.
Alegerea caracteristicilor potrivite face diferența în succesul modelului dvs. Imaginați-vă că încercați să estimați salariul unui popor, dacă nu includeți genul ca covariabilă, ajungeți cu o estimare slabă.
O altă modalitate de a îmbunătăți modelul este să se uite la corelația dintre variabila independentă. Revenind la exemplu, te poți gândi la educație ca la un candidat excelent pentru a prezice salariul, dar și ocupația. Este corect să spunem că ocupația depinde de nivelul de studii, și anume studiile superioare conduc adesea la o ocupație mai bună. Dacă generalizăm această idee, putem spune că corelația dintre variabila dependentă și o variabilă explicativă poate fi mărită de încă o variabilă explicativă.
Pentru a surprinde efectul limitat al educației asupra ocupației, putem folosi un termen de interacțiune.
Dacă te uiți la ecuația salariului, aceasta devine:
If este pozitivă, atunci implică că un nivel suplimentar de educație generează o creștere mai mare a valorii mediane a unei case pentru un nivel de ocupare ridicat. Cu alte cuvinte, există un efect de interacțiune între educație și ocupație.
Aceeași familie de estimatori alimentează și clasificator liniar când eticheta este o clasă și nu un preț. În acest tutorial, vom încerca să vedem ce variabile pot fi un bun candidat pentru termeni de interacțiune. Vom testa dacă adăugarea acestui tip de informații duce la o predicție mai bună a prețului.
Rezumat statistici
Există câțiva pași pe care îi puteți urma înainte de a trece la model. După cum am menționat anterior, modelul este o generalizare a datelor. Cea mai bună practică este să înțelegeți mai întâi datele și apoi să faceți o predicție. Dacă nu vă cunoașteți datele, aveți șanse mici să vă îmbunătățiți modelul.
Ca prim pas, încărcați datele ca un cadru de date panda și creați un set de antrenament și un set de testare.
Sfaturi: Pentru acest tutorial, trebuie să aveți instalate matplotlib și seaborn în PythonPuteți instala un Python pachet din zbor cu Jupyter. Tu Nu ar trebui fa asta
!conda install -- yes matplotlib
dar
import sys !{sys.executable} -m pip install matplotlib # Already installed !{sys.executable} -m pip install seaborn
Rețineți că acest pas nu este necesar dacă aveți instalate matplotlib și seaborn.
Matplotlib este biblioteca în care se creează un grafic PythonSeaborn este o bibliotecă de vizualizare statistică construită pe matplotlib. Aceasta oferă latracintrigi pozitive și frumoase.
Codul de mai jos importă bibliotecile necesare.
import pandas as pd from sklearn import datasets import tensorflow as tf from sklearn.datasets import load_boston import numpy as np
Biblioteca sklearn include setul de date Boston. Puteți apela API-ul său pentru a importa datele.
Notă privind versiunea: load_boston a fost depreciat în scikit-learn 1.0 și eliminat în scikit-learn 1.2 deoarece setul de date codifică o caracteristică cu încărcare rasială. Pe o instalare curentă, utilizați fetch_california_housing în schimb, sau încărcați fișierul brut singur. Fluxul de lucru prezentat mai jos este neschimbat; diferă doar încărcătorul.
boston = load_boston() df = pd.DataFrame(boston.data)
Numele caracteristicilor sunt stocate în obiectul feature_names ca o matrice.
boston.feature_names
producție
array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')
Puteți redenumi coloanele.
df.columns = boston.feature_names
df['PRICE'] = boston.target
df.head(2)
Convertiți variabila CHAS ca variabilă șir și o etichetați cu da dacă CHAS = 1 și nu dacă 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
Cu panda, este simplu să împărțiți setul de date. Împărțiți aleatoriu setul de date cu 80% set de antrenament și 20% set de testare. ursi panda are o funcție de eșantionare încorporată pentru a diviza un cadru de date.
Primul parametru frac este o valoare de la 0 la 1. Îl setați la 0.8 pentru a selecta aleatoriu 80 la sută din cadrul de date.
`random_state` corectează amestecarea, astfel încât aceleași rânduri sunt returnate pentru toată lumea.
### Create train/test set
df_train=df.sample(frac=0.8,random_state=200)
df_test=df.drop(df_train.index)
Puteți obține forma datelor. Ar trebui să fie:
- Set tren: 506*0.8 = 405
- Set de testare: 506*0.2 = 101
print(df_train.shape, df_test.shape)
producție
(405, 14) (101, 14)
df_test.head(5)
producție
| CRIM | ZN | INDUS | CHAS | NOX | RM | VÂRSTĂ | DIS | RAD | TAX | PTRATIO | B | LSTAT | PRET | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.00632 | 18.0 | 2.31 | Nu. | 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 | Nu. | 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 | Nu. | 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 | Nu. | 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 | Nu. | 0.524 | 6.172 | 96.1 | 5.9505 | 5.0 | 311.0 | 15.2 | 396.90 | 19.15 | 27.1 |
Datele sunt dezordonate; este adesea dezechilibrat și presărat cu valori aberante care aruncă în afara analizei și instruirii în învățarea automată.
Primul pas pentru curățarea setului de date este să înțelegeți unde are nevoie de curățare. Curățarea unui set de date poate fi dificil de făcut, mai ales în orice mod generalizabil
Google Echipa de cercetare a dezvoltat un instrument pentru această sarcină numit faţetele care te ajută să vizualizezi datele și să le segmentezi în tot felul de moduri. Acesta este un bun punct de plecare pentru a înțelege cum este structurat setul de date.
Fațetele vă permit să găsiți locurile în care datele nu arată exact așa cum vă așteptați.
Cu excepția aplicației lor web, Google facilitează integrarea setului de instrumente într-un Jupyter caiet.
Există două părți în fațete:
- Prezentare generală a fațetelor
- Facets Deep Dive
Prezentare generală a fațetelor
Prezentare generală a fațetelor oferă o prezentare generală a setului de date. Prezentare generală a fațetelor împarte coloanele de date în rânduri de informații importante afișate
- procentul de observație lipsă
- valori minime și maxime
- statistici precum media, mediana și abaterea standard.
- De asemenea, adaugă o coloană care arată procentul de valori care sunt zero, ceea ce este util atunci când majoritatea valorilor sunt zero.
- Este posibil să vedeți aceste distribuții pe setul de date de testare, precum și setul de antrenament pentru fiecare caracteristică. Înseamnă că puteți verifica din nou dacă testul are o distribuție similară cu datele de antrenament.
Acesta este cel puțin minimul de făcut înainte de orice sarcină de învățare automată. Cu acest instrument, nu ratați acest pas crucial și evidențiază unele anomalii.
Facets Deep Dive
Facets Deep Dive este un instrument interesant. Îți permite să obții mai multă claritate asupra setului de date și să mărești complet imaginea pentru a vedea o anumită porțiune de date. Asta înseamnă că poți faceta datele pe rânduri și coloane în oricare dintre caracteristicile setului de date.
Vom folosi aceste două instrumente cu setul de date Boston.
notițe: Nu puteți utiliza Facets Overview și Facets Deep Dive în același timp. Mai întâi trebuie să ștergeți notebook-ul pentru a schimba instrumentul.
Înainte de a putea fi utilizat oricare dintre instrumente, Facets trebuie instalat în mediul notebook.
Instalați Facet
Puteți utiliza aplicația web Facet pentru cea mai mare parte a analizei. În acest tutorial, veți vedea cum să îl utilizați într-un Jupyter Caiet.
În primul rând, trebuie să instalați nbextensions. Se face cu acest cod. Copiați și lipiți următorul cod în terminalul mașinii dvs.
pip install jupyter_contrib_nbextensions
Imediat după aceea, trebuie să clonați depozitele de pe computer. Aveți două opțiuni:
Opțiunea 1) Copiați și lipiți acest cod în terminal (Recomandat)
Dacă nu aveți Git instalat pe calculatorul dvs., vă rugăm să accesați acest link. URL Git pentru Windows pagina de descărcare și urmați instrucțiunile. După ce ați terminat, puteți utiliza comanda git în terminalul pentru utilizatorul Mac sau promptul Anaconda pentru Windows utilizator
git clone https://github.com/PAIR-code/facets
Opțiunea 2) Accesează depozitul PAIR-code/fațete și descărcați depozitele.
Pagina depozitului de mai sus conține butonul de descărcare utilizat de opțiunea 2. Dacă alegeți prima opțiune, fișierul ajunge în folderul de descărcare. Puteți fie să lăsați fișierul în descărcare, fie să îl trageți într-o altă cale.
Puteți verifica unde este stocată Facets cu această linie de comandă:
echo `pwd`/`ls facets`
Acum că ați localizat Facets, trebuie să îl instalați în Jupyter Caiet. Trebuie să setați directorul de lucru pe calea în care se află fațetele.
Directorul de lucru actual și locația zipului Facets ar trebui să fie aceleași.
Lista de terminale de mai sus confirmă că facets se află în directorul de lucru curent. Trebuie să indicați directorul de lucru către Facet:
cd facets
Pentru a instala Facets în Jupyter, ai doua variante. Daca ai instalat Jupyter cu Conda pentru toți utilizatorii, copiați acest cod:
jupyter nbextension install facets-dist/
În caz contrar, utilizați:
jupyter nbextension install facets-dist/ --user
În regulă, ești gata. Să deschidem Facet Overview.
Prezentare generală a fațetelor de rulare în Jupyter
Prezentare generală utilizează a Python script pentru a calcula statisticile. Trebuie să importați scriptul numit generic_feature_statistics_generator în Jupyter. Nu vă faceți griji; scriptul se află în fișierele de fațete.
Trebuie să-i găsiți calea. Se face usor. Deschideți fațete, deschideți fișierul facets_overview și apoi python. Copiați calea
După aceea, întoarce-te la Jupyter, și scrieți următorul cod. Schimbați calea „/Users/Thomas/facets/facets_overview/python” la calea dvs.
# Add the facets overview python code to the python path# Add t import sys sys.path.append('/Users/Thomas/facets/facets_overview/python')
Puteți importa scriptul cu codul de mai jos.
from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator
În Windows, același cod devine
import sys sys.path.append(r"C:\Users\Admin\Anaconda3\facets-master\facets_overview\python") from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator
Pentru a calcula statisticile caracteristicilor, trebuie să utilizați funcția GenericFeatureStatisticsGenerator(), și utilizați obiectul ProtoFromDataFrames. Puteți trece cadrul de date într-un dicționar. De exemplu, dacă dorim să creăm o statistică rezumată pentru garnitura de tren, putem stoca informațiile într-un dicționar și le putem folosi în obiectul „ProtoFromDataFrames“
'name': 'train', 'table': df_train
Nume este numele tabelului afișat și utilizați numele tabelului pe care doriți să îl calculați rezumatul. În exemplul dvs., tabelul care conține datele este 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")
În cele din urmă, trebuie doar să copiați și să lipiți codul de mai jos. Codul vine direct din GitHub. Ar trebui să poți vedea asta:
# 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))
Grafic de corelație și grilă de perechi
După ce verificați datele și distribuția lor, puteți trasa o matrice de corelație. Matricea de corelație calculează coeficientul Pearson. Acest coeficient este limitat între -1 și 1, unde o valoare pozitivă indică o corelație pozitivă, iar o valoare negativă indică o corelație negativă.
Sunteți interesat să vedeți care variabile pot fi un bun candidat pentru termenii de interacțiune.
Notă privind versiunea: masca de dedesubt cheamă np.bool, un alias care a fost depreciat în NumPy 1.20 și eliminat în NumPy 1.24Într-un NumPy recent, aceeași linie ridică AttributeError: module 'numpy' has no attribute 'bool'încorporat bool este înlocuitorul drop-in.
## 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})
producție
<matplotlib.axes._subplots.AxesSubplot at 0x1a184d6518>
În harta termică de mai sus, pătratele mai închise la culoare marchează corelații mai puternice. Din matrice, puteți vedea:
- LSTAT
- RM
Sunt puternic corelate cu PRICE. O altă caracteristică interesantă este corelația pozitivă puternică dintre NOX și INDUS, ceea ce înseamnă că aceste două variabile se mișcă în aceeași direcție. Ambele sunt, de asemenea, corelate cu PRICE. DIS este, de asemenea, puternic corelat cu INDUS și NOX.
Ai un prim indiciu că INDUS și NOX pot fi candidați buni pentru un termen de interacțiune, iar DIS ar putea fi, de asemenea, interesant de urmărit.
Puteți merge puțin mai adânc prin reprezentarea unei grile de perechi. Acesta va ilustra mai detaliat harta de corelație pe care ați trasat-o înainte.
Grila de perechi este compusă după cum urmează:
- Partea superioară: diagramă de dispersie cu linie montată
- Diagonală: diagrama densității nucleului
- Partea inferioară: diagramă multivariată a densității nucleului
Te concentrezi pe patru variabile independente. Alegerea corespunde variabilelor cu o corelație puternică cu PRICE.
- INDUS
- NOX
- RM
- LSTAT
mai mult, PREȚUL.
notițe că eroarea standard este adăugată implicit la graficul de dispersie.
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)
producție
Să începem cu partea de sus:
- Prețul este corelat negativ cu INDUS, NOX și LSTAT; corelat pozitiv cu RM.
- Există o ușoară neliniaritate între LSTAT și PRICE
- Există ca o linie dreaptă când prețul este egal cu 50. Din descrierea setului de date, PRICE a fost trunchiat la valoarea de 50.
Diagonală: NOX pare să aibă două grupuri, unul în jur de 0.5 și unul în jurul valorii de 0.85.
Pentru a verifica mai multe despre el, puteți să vă uitați la partea de jos. Densitatea nucleului multivariată este interesantă într-un sens, colorează acolo unde sunt majoritatea punctelor. Diferența cu diagrama de dispersie atrage o densitate de probabilitate, chiar dacă nu există niciun punct în setul de date pentru o anumită coordonată. Când culoarea este mai puternică, indică o concentrație mare de punct în jurul acestei zone.
Dacă verificați densitatea multivariată pentru INDUS și NOX, puteți vedea corelația pozitivă și cele două clustere. Când ponderea industriei este peste 18, concentrația de oxizi nitrici este peste 0.6.
Vă puteți gândi la adăugarea unei interacțiuni între INDUS și NOX în relația liniară.
În cele din urmă, puteți utiliza al doilea instrument creat de GoogleAnaliză detaliată a fațetelor. Interfața este împărțită în patru secțiuni principale. Zona centrală din centru este o afișare cu zoom a datelor. În partea de sus a panoului, există meniul derulant unde puteți schimba aranjamentul datelor pentru a controla fațetarea, poziționarea și culoarea. În dreapta, există o vizualizare detaliată a unui anumit rând de date. Aceasta înseamnă că puteți face clic pe orice punct de date din vizualizarea centrală pentru a vedea detalii despre acel punct de date.
În timpul etapei de vizualizare a datelor, sunteți interesat să căutați corelația perechi între variabila independentă asupra prețului casei. Cu toate acestea, implică cel puțin trei variabile, iar diagramele 3D sunt complicate de lucrat.
O modalitate de a aborda această problemă este de a crea o variabilă categorială. Adică, putem crea un grafic 2D și colora punctele. Puteți împărți variabila PRICE în patru categorii, fiecare categorie fiind un quartil (de exemplu, 0.25, 0.5, 0.75). Numiți această nouă variabilă 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")
Analiză detaliată a fațetelor
Pentru a deschide Deep Dive, trebuie să transformați datele într-un format json. Pandas are o metodă pentru asta: apelați to_json pe DataFrame.
Prima linie de cod setează dimensiunea sprite-ului în funcție de numărul de rânduri pe care le conține setul de date.
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')
Codul de mai jos provine de la Google GitHub. După ce rulați codul, ar trebui să puteți vedea acest lucru:
# 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))
Sunteți interesat să vedeți dacă există o legătură între rata industriei, concentrația de oxid, distanța până la centrul de locuri de muncă și prețul casei.
Pentru aceasta, mai întâi împărțiți datele în funcție de intervalul de industrie și de culoare cu quartila prețului:
- Selectați fațeta X și alegeți INDUS.
- Selectați Afișare și alegeți DIS. Va colora punctele cu quartila prețului casei
Aici, culorile mai închise înseamnă că distanța până la primul centru de angajare este mai mare.
Până acum, arată din nou ceea ce știți, rată mai mică din industrie, preț mai mare. Acum puteți vedea defalcarea după INDUX, după NOX.
Selectați fațeta Y și alegeți NOX.
Acum puteți vedea că casa departe de primul centru de locuri de muncă are cea mai mică cotă din industrie și, prin urmare, cea mai mică concentrație de oxid. Dacă alegeți să afișați tipul cu Q_PRICE și să măriți colțul din stânga jos, puteți vedea ce tip de preț este.
Aveți un alt indiciu că interacțiunea dintre IND, NOX și DIS poate fi candidați buni pentru îmbunătățirea modelului.
Explorarea a produs două interacțiuni candidate, așa că următorul pas este testarea lor într-un model real.
Regresia liniară cu TensorFlow
În această secțiune, veți estima modelul de regresie liniară cu TensorFlow API-ul Estimator. Veți proceda după cum urmează:
- Pregătiți datele
- Estimați un model de referință: fără interacțiune
- Estimați un model cu interacțiune
Notă privind versiunea: il tf-estimator pachetul a fost livrat în versiunea finală odată cu TensorFlow 2.15 și lipsește de la TensorFlow 2.16 încoace, deci tf.estimator.LinearRegressor rulează doar pe TensorFlow 1.x, cu excepția cazului în care îl migrați către un model liniar Keras.
Rețineți că scopul învățării automate este de a minimiza eroarea. În acest caz, modelul cu cea mai mică eroare medie pătratică va câștiga. Estimatorul TensorFlow calculează automat această metrică.
Date de pregătire
În majoritatea cazurilor, trebuie să transformați datele. De aceea, Facets Overview este fascinant. Din statistica rezumativă, ați observat că există valori aberante. Aceste valori afectează estimările, deoarece nu seamănă cu populația pe care o analizați. Valorile aberante de obicei influențează rezultatele. De exemplu, o valoare aberantă pozitivă tinde să supraestimeze coeficientul.
O soluție bună pentru a rezolva această problemă este standardizarea variabilei. Standardizarea înseamnă o deviație standard de unu și o medie de zero. Procesul de standardizare implică doi pași. În primul rând, se subordonează...tracts este valoarea medie a variabilei. În al doilea rând, se împarte prin abaterea standard, astfel încât distribuția să aibă o abatere standard unitară.
Librăria scikit-learn este util pentru standardizarea variabilelor. Puteți utiliza preprocesarea modulului cu scalarea obiectului în acest scop.
Puteți utiliza funcția de mai jos pentru a scala un set de date. Rețineți că nu scalați coloana de etichetă și variabilele categoriale.
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
Puteți utiliza funcția pentru a construi trenul la scară/setul de testare.
df_train_scale = standardize_data(df_train) df_test_scale = standardize_data(df_test)
Regresie de bază: Benchmark
În primul rând, antrenezi și testezi un model fără interacțiune. Scopul este de a vedea metrica de performanță a modelului.
Modul de antrenare a modelului este exact ca în tutorialul de pe API de nivel înalt. Veți folosi estimatorul TensorFlow LinearRegressor.
Ca reamintire, trebuie să alegeți:
- caracteristicile de pus în model
- transforma caracteristicile
- construiți regresorul liniar
- construiți funcția input_fn
- antrenează modelul
- testați modelul
Folosești toate variabilele din setul de date pentru a antrena modelul. În total, există doisprezece variabile continue și o variabilă categorică.
## 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']
Convertiți caracteristicile într-o coloană numerică sau coloană categorială
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'])]
Creați modelul cu linearRegressor. Stocați modelul în folderul train_Boston
model = tf.estimator.LinearRegressor(
model_dir="train_Boston",
feature_columns=categorical_features + continuous_features)
producție
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}
Fiecare coloană din tren sau din datele de test este convertită într-un Tensor cu funcția 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)
Estimați modelul pe datele trenului.
model.train(input_fn=get_input_fn(df_train_scale,
num_epochs=None,
n_batch = 128,
shuffle=False),
steps=1000)
producție
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>
În sfârșit, estimați performanțele modelului pe setul de testare
model.evaluate(input_fn=get_input_fn(df_test_scale,
num_epochs=1,
n_batch = 128,
shuffle=False),
steps=1000)
producție
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}
Pierderea modelului este de 1650.9785. Aceasta este metrica care trebuie depășită în secțiunea următoare
Îmbunătățiți modelul: termen de interacțiune
În prima parte a tutorialului, ați observat o relație interesantă între variabile. Diferitele tehnici de vizualizare au relevat faptul că INDUS și NOX sunt legate între ele și își amplifică reciproc efectul asupra prețului. Nu numai că interacțiunea dintre INDUS și NOX afectează prețul, dar acest efect este și mai puternic atunci când interacționează cu DIS.
Este timpul să generalizăm această idee și să vedem dacă putem îmbunătăți predicția modelului.
Trebuie să adăugați două coloane noi la fiecare set de date: train și test. Pentru aceasta, creați o funcție pentru a calcula termenul de interacțiune și o alta pentru a calcula termenul de interacțiune triplă. Fiecare funcție produce o singură coloană. După ce noile variabile sunt create, le puteți concatena la setul de date de training și la setul de date de test.
În primul rând, trebuie să creați o nouă variabilă pentru interacțiunea dintre INDUS și NOX.
Funcția de mai jos returnează două cadre de date, train și test, cu interacțiunea dintre var_1 și var_2, în cazul dvs. INDUS și 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
Stocați cele două coloane noi
interation_ind_ns_train, interation_ind_ns_test= interaction_term('INDUS', 'NOX', 'INDUS_NOS') interation_ind_ns_train.shape (325,)
În al doilea rând, creați o a doua funcție pentru a calcula termenul de interacțiune triplă.
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')
Acum că aveți toate coloanele necesare, le puteți adăuga la setul de date de instruire și testare. Numiți aceste două cadre de date noi:
- 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)
producție
Asta e tot: poți estima noul model cu termenii de interacțiune și poți vedea cum arată metrica de performanță.
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)
producție
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)
producție
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)
producție
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}
Noua pierdere este 1515.9863. Doar prin adăugarea a două variabile noi, ați reușit să reduceți pierderea. Înseamnă că puteți face o predicție mai bună decât cu modelul de referință.
| Model | Set de caracteristici | Directorul de modele | pierdere_medie | de pe |
|---|---|---|---|---|
| Benchmark | 12 coloane continue standardizate plus CHAS | tren_Boston | 86.89361 | 1650.9785 |
| Cu interacțiune | Benchmark plus INDUS_NOS și INDUS_NOS_DIS | tren_Boston_1 | 79.78876 | 1515.9863 |
Ambele cifre provin din aceeași divizare a testului pe 101 rânduri, așadar scăderea de aproximativ 8% a pierderii medii este atribuibilă exclusiv celor două coloane de interacțiune.











