GLM u R-u: Generalizirani linearni model i logistička regresija

⚡ Pametni sažetak

Generalizirani linearni model (GLM) u R-u proširuje običnu regresiju na ishode koji su binarni, temeljeni na broju ili nisu normalni. Ovaj vodič gradi logistički GLM na skupu podataka o dohotku odraslih i procjenjuje ga s točnošću, preciznošću, prisjećanjem i ROC-om.

  • 📐 Osnovna definicija: GLM povezuje linearni prediktor s odgovorom putem funkcije povezivanja i eksponencijalne distribucije obitelji odabrane argumentom obitelji.
  • 🧮 Sintaksa modela: Pozovite glm(formula, podaci, obitelj = 'binom') tako da logit veza pretvara linearni prediktor u vjerojatnost između 0 i 1.
  • 🧹 Priprema podataka: Standardizirajte kontinuirane stupce, skratite gornji percentil radnog vremena i preoblikujte obrazovanje i bračni status u manji broj razina.
  • 📊 Mjerni podaci o izvedbi: Prvo pročitajte matricu zbunjenosti, zatim preciznost, prisjećanje i F1 rezultat, jer sirova točnost skriva dominantnu klasu.
  • 🔁 Očitavanje koeficijenta: Potencirajte svaki koeficijent pomoću exp() kako biste pretvorili logaritamske izglede u omjer izglede koji razumiju i netehnički čitatelji.
  • 🔧 Poboljšanje modela: Dodajte interakcijske pojmove poput dob:sati.tjedno i usporedite F1 rezultate kako biste potvrdili da se dodatna složenost isplati.

GLM u R generaliziranom linearnom modelu

Što je generalizirani linearni model (GLM) u R-u?

A Generalizirani linearni model (GLM) proširuje običnu linearnu regresiju tako da varijabla odziva može slijediti distribuciju koja nije normalna. U R, ugradite jedan s ugrađenim glm() funkcija iz paketa statistike.

Svaki GLM definiran je s tri komponente:

  • Slučajna komponenta: distribucija vjerojatnosti odzivne varijable, uzeta iz eksponencijalne obitelji (binomna, Poissonova, Gama, Gaussova i druge).
  • Sustavna komponenta: linearni prediktor, odnosno ponderirana kombinacija vaših objašnjavajućih varijabli.
  • Funkcija veze: funkcija koja povezuje srednju vrijednost odgovora s linearnim prediktorom, na primjer logit veza za binarne podatke ili logaritamska veza za brojanje.

Ta struktura čini model „generaliziranim“. Umjesto nametanja normalno distribuiranog ishoda, deklarirate ispravnu distribuciju putem obitelj argument, a R procjenjuje koeficijente metodom maksimalne vjerojatnosti. Logistička regresija je jednostavno GLM s binomnom obitelji i logit vezom, pa je prirodna polazna točka.

Što je logistička regresija u R-u?

Logistička regresija se koristi za predviđanje klase, tj. vjerojatnosti. Logistička regresija može točno predvidjeti binarni ishod.

Zamislite da želite predvidjeti hoće li zajam biti odbijen/prihvaćen na temelju mnogih atributa. Logistička regresija je oblika 0/1. y = 0 ako je posudba odbijena, y = 1 ako je prihvaćena.

Logistički regresijski model razlikuje se od linearnog regresijskog modela na dva načina.

  • Prije svega, logistička regresija prihvaća samo dihotomni (binarni) input kao zavisnu varijablu (tj. vektor od 0 i 1).
  • Drugo, ishod se mapira putem probabilističke funkcije povezivanja koja se naziva sigmoidni (logistička) funkcija zbog svog S-oblika:

Logistička regresija

Izlaz funkcije uvijek je između 0 i 1. Provjerite sliku ispod

Logistička regresija

Sigmoidna funkcija vraća vrijednosti od 0 do 1. Za zadatak klasifikacije potreban nam je diskretni izlaz od 0 ili 1.

Za pretvaranje kontinuiranog protoka u diskretnu vrijednost, možemo postaviti ograničenje odluke na 0.5. Sve vrijednosti iznad ovog praga klasificiraju se kao 1

Logistička regresija

Sada kada je funkcija poveznice jasna, usporedite generalizirani model s običnim linearnim modelom koji već poznajete.

GLM vs. linearna regresija: Ključne razlike u R-u

Prije nego što napišete bilo kakav kod, korisno je znati točno kada je standard Linearna regresija Funkcija lm() više nije prikladna i glm() bi je trebao zamijeniti.

Kriteriji Linearna regresija (lm) Generalizirani linearni model (glm)
Varijabla odgovora Kontinuirano i neograničeno Binarni, brojački, proporcionalni ili pozitivni kontinuirani broj
Raspodjela pogrešaka Samo normalno Bilo koji eksponencijalni član obitelji
Funkcija povezivanja Identitet (implicitni) Eksplicitno: logit, logaritam, inverz, probit
Metoda procjene Obični najmanji kvadrati Maksimalna vjerojatnost (IRLS)
Pretpostavka o varijanci Konstantno kroz promatranja Dopušteno je ovisiti o srednjoj vrijednosti
Mjera usklađenosti R-kvadrat AIC i rezidualna devijacija
R funkcija lm(formula, podaci) glm(formula, podaci, obitelj)

Ukratko, odaberite lm() kada je ishod normalno distribuirano mjerenje i glm() kada je ishod odluka da/ne, zadatak koji biste inače mogli prepustiti stablo odluke klasifikator, broj događaja ili strogo pozitivna veličina čiji raspon raste sa srednjom vrijednošću.

Kako stvoriti generalizirani linearni model (GLM) u R-u

Nakon što je teorija riješena, ostatak ovog tutorijala primjenjuje binomni GLM od početka do kraja na stvarni skup podataka.

Koristimo se odrasla osoba skup podataka za ilustraciju logističke regresije. „Odrasla osoba“ je izvrstan skup podataka za zadatak klasifikacije. Cilj je predvidjeti hoće li godišnji prihod pojedinca u američkim dolarima premašiti 50,000. Skup podataka sadrži 48,842 opažanja i deset varijabli:

  • starost: starost pojedinca. Numerički
  • obrazovanje: Obrazovna razina pojedinca. Faktor.
  • bračni.status: Maritalni status pojedinca. Čimbenik tj. nikad u braku, u braku-građanski supružnik, …
  • spol: Spol pojedinca. Faktor tj. Muško ili Žensko
  • prihod: Target varijabla. Prihod iznad ili ispod 50K. Faktor tj. >50K, <=50K

između ostalog

library(dplyr)
data_adult <-read.csv("https://raw.githubusercontent.com/guru99-edu/R-Programming/master/adult.csv")
glimpse(data_adult)

Izlaz:

Observations: 48,842
Variables: 10
$ x               <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,...
$ age             <int> 25, 38, 28, 44, 18, 34, 29, 63, 24, 55, 65, 36, 26...
$ workclass       <fctr> Private, Private, Local-gov, Private, ?, Private,...
$ education       <fctr> 11th, HS-grad, Assoc-acdm, Some-college, Some-col...
$ educational.num <int> 7, 9, 12, 10, 10, 6, 9, 15, 10, 4, 9, 13, 9, 9, 9,...
$ marital.status  <fctr> Never-married, Married-civ-spouse, Married-civ-sp...
$ race            <fctr> Black, White, White, Black, White, White, Black, ...
$ gender          <fctr> Male, Male, Male, Male, Female, Male, Male, Male,...
$ hours.per.week  <int> 40, 50, 40, 40, 30, 30, 40, 32, 40, 10, 40, 40, 39...
$ income          <fctr> <=50K, <=50K, >50K, >50K, <=50K, <=50K, <=50K, >5...

Postupit ćemo na sljedeći način:

  • Korak 1: Provjerite kontinuirane varijable
  • Korak 2: Provjerite faktorske varijable
  • Korak 3: Inženjering značajki
  • Korak 4: Zbirna statistika
  • Korak 5: Skup za obuku/testiranje
  • Korak 6: Izgradite model
  • Korak 7: Procijenite izvedbu modela
  • Korak 8: Poboljšajte model

Vaš zadatak je predvidjeti koja će osoba imati prihod veći od 50K.

U ovom vodiču detaljno će biti opisan svaki korak za izvođenje analize na stvarnom skupu podataka.

Korak 1) Provjerite kontinuirane varijable

U prvom koraku možete vidjeti distribuciju kontinuiranih varijabli.

continuous <-select_if(data_adult, is.numeric)
summary(continuous)

Code Objašnjenje

  • kontinuirano <- select_if(data_adult, is.numeric): Koristite funkciju select_if() iz biblioteke dplyr za odabir samo numeričkih stupaca
  • sažetak (kontinuirano): Ispis sažete statistike

Izlaz:

##        X              age        educational.num hours.per.week 
##  Min.   :    1   Min.   :17.00   Min.   : 1.00   Min.   : 1.00  
##  1st Qu.:11509   1st Qu.:28.00   1st Qu.: 9.00   1st Qu.:40.00  
##  Median :23017   Median :37.00   Median :10.00   Median :40.00  
##  Mean   :23017   Mean   :38.56   Mean   :10.13   Mean   :40.95  
##  3rd Qu.:34525   3rd Qu.:47.00   3rd Qu.:13.00   3rd Qu.:45.00  
##  Max.   :46033   Max.   :90.00   Max.   :16.00   Max.   :99.00	

Iz gornje tablice možete vidjeti da podaci imaju potpuno različite skale i sati.po.tjednima imaju velike odstupanja (tj. pogledajte zadnji kvartil i maksimalnu vrijednost).

S tim se možete nositi u dva koraka:

  • Nacrtajte raspodjelu sati tjedno
  • Standardizirajte kontinuirane varijable
  1. Nacrtajte distribuciju

Pogledajmo pobliže distribuciju sati po tjednu

# Histogram with kernel density curve
library(ggplot2)
ggplot(continuous, aes(x = hours.per.week)) +
    geom_density(alpha = .2, fill = "#FF6666")

Izlaz:

Provjerite kontinuirane varijable

Varijabla ima puno outliera i nije dobro definiranu distribuciju. Ovaj problem možete djelomično riješiti brisanjem gornjih 0.01 posto sati tjedno.

Osnovna sintaksa kvantila:

quantile(variable, percentile)
arguments:
-variable:  Select the variable in the data frame to compute the percentile
-percentile:  Can be a single value between 0 and 1 or multiple value. If multiple, use this format:  `c(A,B,C, ...)
- `A`,`B`,`C` and `...` are all integer from 0 to 1.

Izračunavamo 99-ti percentil tjednog radnog vremena.

top_one_percent <- quantile(data_adult$hours.per.week, .99)
top_one_percent

Code Objašnjenje

  • kvantil(data_adult$hours.per.week, .99): Izračunaj 99. percentil tjednog radnog vremena

Izlaz:

## 99% 
##  80

99 posto stanovništva radi manje od 80 sati tjedno.

Možete ispustiti opažanja iznad ovog praga. Koristite filtar iz dplyr knjižnica.

data_adult_drop <-data_adult %>%
filter(hours.per.week<top_one_percent)
dim(data_adult_drop)

Izlaz:

## [1] 45537    10
  1. Standardizirajte kontinuirane varijable

Možete standardizirati svaki stupac kako biste poboljšali izvedbu jer vaši podaci nemaju istu ljestvicu. Možete koristiti funkciju mutate_if iz biblioteke dplyr. Osnovna sintaksa je:

mutate_if(df, condition, funs(function))
arguments:
-`df`: Data frame used to compute the function
- `condition`: Statement used. Do not use parenthesis
- funs(function):  Return the function to apply. Do not use parenthesis for the function

Brojčane stupce možete standardizirati na sljedeći način:

data_adult_rescale <- data_adult_drop %>%
	mutate_if(is.numeric, funs(as.numeric(scale(.))))
head(data_adult_rescale)

Code Objašnjenje

  • mutate_if(is.numeric, funs(scale)): uvjet je samo numerički stupac, a funkcija je scale

Izlaz:

##           X         age        workclass    education educational.num
## 1 -1.732680 -1.02325949          Private         11th     -1.22106443
## 2 -1.732605 -0.03969284          Private      HS-grad     -0.43998868
## 3 -1.732530 -0.79628257        Local-gov   Assoc-acdm      0.73162494
## 4 -1.732455  0.41426100          Private Some-college     -0.04945081
## 5 -1.732379 -0.34232873          Private         10th     -1.61160231
## 6 -1.732304  1.85178149 Self-emp-not-inc  Prof-school      1.90323857
##       marital.status  race gender hours.per.week income
## 1      Never-married Black   Male    -0.03995944  <=50K
## 2 Married-civ-spouse White   Male     0.86863037  <=50K
## 3 Married-civ-spouse White   Male    -0.03995944   >50K
## 4 Married-civ-spouse Black   Male    -0.03995944   >50K
## 5      Never-married White   Male    -0.94854924  <=50K
## 6 Married-civ-spouse White   Male    -0.76683128   >50K

Korak 2) Provjerite faktorske varijable

Ovaj korak ima dva cilja:

  • Provjerite razinu u svakom stupcu kategorije
  • Definirajte nove razine

Ovaj korak ćemo podijeliti u tri dijela:

  • Odaberite kategoričke stupce
  • Pohranite trakasti grafikon svakog stupca na popis
  • Ispišite grafikone

Stupce faktora možemo odabrati pomoću donjeg koda:

# Select categorical column
factor <- data.frame(select_if(data_adult_rescale, is.factor))
	ncol(factor)

Code Objašnjenje

  • data.frame(select_if(data_adult, is.factor)): Stupce faktora pohranjujemo u faktor u tipu okvira podataka. Biblioteka ggplot2 zahtijeva objekt okvira podataka.

Izlaz:

## [1] 6

Skup podataka sadrži 6 kategoričkih varijabli

Drugi korak je zahtjevniji. Želite nacrtati stupčasti grafikon za svaki stupac u faktoru okvira podataka. Praktičnije je automatizirati proces, posebno u situacijama kada postoji mnogo stupaca.

library(ggplot2)
# Create graph for each column
graph <- lapply(names(factor),
    function(x) 
	ggplot(factor, aes(get(x))) +
		geom_bar() +
		theme(axis.text.x = element_text(angle = 90)))

Code Objašnjenje

  • lapply(): Koristite funkciju lapply() za prosljeđivanje funkcije u svim stupcima skupa podataka. Izlaz pohranjujete na popis
  • funkcija(x): funkcija će biti obrađena za svaki x. Ovdje je x stupac
  • ggplot(faktor, aes(get(x))) + geom_bar()+ theme(axis.text.x = element_text(angle = 90)): Napravite trakasti dijagram za svaki x element. Napomena, da vratite x kao stupac, morate ga uključiti unutar get()

Posljednji korak je relativno lak. Želite ispisati 6 grafikona.

# Print the graph
graph

Izlaz:

## [[1]]

Provjerite varijable faktora

## ## [[2]]

Provjerite varijable faktora

## ## [[3]]

Provjerite varijable faktora

## ## [[4]]

Provjerite varijable faktora

## ## [[5]]

Provjerite varijable faktora

## ## [[6]]

Provjerite varijable faktora

Napomena: Koristite sljedeći gumb za navigaciju do sljedećeg grafikona

Provjerite varijable faktora

Korak 3) Inženjering značajki

Dvije kategoričke varijable nose više razina nego što je modelu potrebno. Pregrupirat ćete ih u šire, bolje naseljene kategorije.

Preinačiti obrazovanje

Iz gornjeg grafikona možete vidjeti da varijabla obrazovanje ima 16 razina. To je značajno, a neke razine imaju relativno mali broj opažanja. Ako želite poboljšati količinu informacija koju možete dobiti iz ove varijable, možete je preinačiti na višu razinu. Naime, stvarate veće grupe sa sličnim stupnjem obrazovanja. Na primjer, niska razina obrazovanja pretvorit će se u napuštanje škole. Više razine obrazovanja bit će promijenjene u master.

Evo detalja:

Stara razina Nova razina
Predškolski maloljetnik koji se ispisao iz škole
10th maloljetnik koji se ispisao iz škole
11th maloljetnik koji se ispisao iz škole
12th maloljetnik koji se ispisao iz škole
1.-4 maloljetnik koji se ispisao iz škole
5th-6th maloljetnik koji se ispisao iz škole
7th-8th maloljetnik koji se ispisao iz škole
9th maloljetnik koji se ispisao iz škole
HS-Grad HighGrad
Neki fakulteti Zajednica
izv.-acdm Zajednica
izv. voc Zajednica
Celibat Celibat
Masters Masters
Prof-škola Masters
Doktorat Dr.
recast_data <- data_adult_rescale %>%
	select(-X) %>%
	mutate(education = factor(ifelse(education == "Preschool" | education == "10th" | education == "11th" | education == "12th" | education == "1st-4th" | education == "5th-6th" | education == "7th-8th" | education == "9th", "dropout", ifelse(education == "HS-grad", "HighGrad", ifelse(education == "Some-college" | education == "Assoc-acdm" | education == "Assoc-voc", "Community",
    ifelse(education == "Bachelors", "Bachelors",
        ifelse(education == "Masters" | education == "Prof-school", "Master", "PhD")))))))

Code Objašnjenje

  • Koristimo glagol mutirati iz biblioteke dplyr. Izjavom ifelse mijenjamo vrijednosti obrazovanja

U donjoj tablici kreirate sažetak statistike da vidite, u prosjeku, koliko je godina obrazovanja (z-vrijednost) potrebno da se postigne diploma, magisterij ili doktorat.

recast_data %>%
	group_by(education) %>%
	summarize(average_educ_year = mean(educational.num),
		count = n()) %>%
	arrange(average_educ_year)

Izlaz:

## # A tibble: 6 x 3
## education average_educ_year count			
##      <fctr>             <dbl> <int>
## 1   dropout       -1.76147258  5712
## 2  HighGrad       -0.43998868 14803
## 3 Community        0.09561361 13407
## 4 Bachelors        1.12216282  7720
## 5    Master        1.60337381  3338
## 6       PhD        2.29377644   557

Preoblikovati Marital-status

Također je moguće stvoriti niže razine za bračni status. U sljedećem kodu mijenjate razinu na sljedeći način:

Stara razina Nova razina
Nikad oženjen Neoženjen
Oženjen-supružnik-odsutan Neoženjen
Oženjen-AF-bračni drug Oženjen
Oženjen-građanka-supružnik
Odvojen Odvojen
Rastavljen
udovice Udovica
# Change level marry
recast_data <- recast_data %>%
	mutate(marital.status = factor(ifelse(marital.status == "Never-married" | marital.status == "Married-spouse-absent", "Not_married", ifelse(marital.status == "Married-AF-spouse" | marital.status == "Married-civ-spouse", "Married", ifelse(marital.status == "Separated" | marital.status == "Divorced", "Separated", "Widow")))))

Možete provjeriti broj pojedinaca unutar svake grupe.

table(recast_data$marital.status)

Izlaz:

## ##     Married Not_married   Separated       Widow
##       21165       15359        7727        1286

Korak 4) Sažeta statistika

Vrijeme je da provjerimo neke statistike o našim ciljnim varijablama. Na donjem grafikonu brojite postotak pojedinaca koji zarađuju više od 50 tisuća s obzirom na njihov spol.

# Plot gender income
ggplot(recast_data, aes(x = gender, fill = income)) +
    geom_bar(position = "fill") +
    theme_classic()

Izlaz:

Sumarna statistika

Zatim provjerite utječe li porijeklo pojedinca na njihovu zaradu.

# Plot origin income
ggplot(recast_data, aes(x = race, fill = income)) +
    geom_bar(position = "fill") +
    theme_classic() +
    theme(axis.text.x = element_text(angle = 90))

Izlaz:

Sumarna statistika

Broj sati rada prema spolu.

# box plot gender working time
ggplot(recast_data, aes(x = gender, y = hours.per.week)) +
    geom_boxplot() +
    stat_summary(fun.y = mean,
        geom = "point",
        size = 3,
        color = "steelblue") +
    theme_classic()

Izlaz:

Sumarna statistika

Okvirni dijagram potvrđuje da raspodjela radnog vremena odgovara različitim skupinama. U okvirnom dijagramu, oba spola nemaju homogena opažanja.

Možete provjeriti gustoću tjednog radnog vremena prema vrsti obrazovanja. Raspodjela ima mnogo različitih odabira. To se vjerojatno može objasniti vrstom obrazovanjatract u SAD-u.

# Plot distribution working time by education
ggplot(recast_data, aes(x = hours.per.week)) +
    geom_density(aes(color = education), alpha = 0.5) +
    theme_classic()

Code Objašnjenje

  • ggplot(recast_data, aes( x= hours.per.week)): Dijagram gustoće zahtijeva samo jednu varijablu
  • geom_density(aes(color = education), alpha =0.5): Geometrijski objekt za kontrolu gustoće

Izlaz:

Sumarna statistika

Kako biste potvrdili svoje misli, možete izvesti jednosmjerni ANOVA test:

anova <- aov(hours.per.week~education, recast_data)
summary(anova)

Izlaz:

##                Df Sum Sq Mean Sq F value Pr(>F)    
## education       5   1552  310.31   321.2 <2e-16 ***
## Residuals   45531  43984    0.97                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

ANOVA test potvrđuje razliku u prosjeku između skupina.

Nelinearnost

Prije nego što pokrenete model, možete vidjeti je li broj radnih sati povezan s dobi.

library(ggplot2)
ggplot(recast_data, aes(x = age, y = hours.per.week)) +
    geom_point(aes(color = income),
        size = 0.5) +
    stat_smooth(method = 'lm',
        formula = y~poly(x, 2),
        se = TRUE,
        aes(color = income)) +
    theme_classic()

Code Objašnjenje

  • ggplot(recast_data, aes(x = age, y = sati.po.tjednu)): Postavite estetiku grafikona
  • geom_point(aes(color= prihod), veličina =0.5): Konstruirajte točkasti dijagram
  • stat_smooth(): Dodajte liniju trenda sa sljedećim argumentima:
    • method='lm': iscrtajte prilagođenu vrijednost ako je Linearna regresija
    • formula = y~poly(x,2): Uklopi polinomsku regresiju
    • se = TRUE: Dodajte standardnu ​​pogrešku
    • aes(boja= prihod): Razdvojite model prema prihodu

Izlaz:

Nelinearnost

Ukratko, možete testirati uvjete interakcije u modelu kako biste uočili učinak nelinearnosti između tjednog radnog vremena i drugih značajki. Važno je otkriti pod kojim se uvjetima radno vrijeme razlikuje.

Korelacija

Sljedeća provjera je vizualizacija korelacije između varijabli. Vrstu razine faktora pretvarate u numeričku tako da možete iscrtati toplinsku kartu koja sadrži koeficijent korelacije izračunat Spearmanovom metodom.

library(GGally)
# Convert data to numeric
corr <- data.frame(lapply(recast_data, as.integer))
# Plot the graphggcorr(corr,
    method = c("pairwise", "spearman"),
    nbreaks = 6,
    hjust = 0.8,
    label = TRUE,
    label_size = 3,
    color = "grey50")

Code Objašnjenje

  • data.frame(lapply(recast_data,as.integer)): Pretvori podatke u numeričke
  • ggcorr() crta toplinsku kartu sa sljedećim argumentima:
    • metoda: Metoda za izračunavanje korelacije
    • nbreaks = 6: Broj prekida
    • hjust = 0.8: Kontrolni položaj naziva varijable u dijagramu
    • label = TRUE: Dodajte oznake u središte prozora
    • label_size = 3: Oznake veličine
    • boja = “siva50”): Boja naljepnice

Izlaz:

Korelacija

Korak 5) Skup za obuku/testiranje

Svaki pod nadzorom stroj za učenje Zadatak zahtijeva da podijelite podatke između skupa vlakova i skupa testova. Možete koristiti "funkciju" koju ste stvorili u drugim tutorijalima za nadzirano učenje za stvaranje skupa vlakova/testova.

set.seed(1234)
create_train_test <- function(data, size = 0.8, train = TRUE) {
    n_row = nrow(data)
    total_row = size * n_row
    train_sample <- 1: total_row
    if (train == TRUE) {
        return (data[train_sample, ])
    } else {
        return (data[-train_sample, ])
    }
}
data_train <- create_train_test(recast_data, 0.8, train = TRUE)
data_test <- create_train_test(recast_data, 0.8, train = FALSE)
dim(data_train)

Izlaz:

## [1] 36429     9
dim(data_test)

Izlaz:

## [1] 9108    9

Korak 6) Izgradite model

Da biste vidjeli kako algoritam radi, koristite funkciju glm() iz paketa stats. Generalizirani linearni model je kolekcija modela. Osnovna sintaksa je:

glm(formula, data=data, family=linkfunction()
Argument:
- formula:  Equation used to fit the model- data: dataset used
- Family:     - binomial: (link = "logit")			
- gaussian: (link = "identity")			
- Gamma:    (link = "inverse")			
- inverse.gaussian: (link = "1/mu^2")			
- poisson:  (link = "log")			
- quasi:    (link = "identity", variance = "constant")			
- quasibinomial:    (link = "logit")			
- quasipoisson: (link = "log")	

Spremni ste procijeniti logistički model kako biste podijelili razinu prihoda između skupa značajki.

formula <- income~.
logit <- glm(formula, data = data_train, family = 'binomial')
summary(logit)

Code Objašnjenje

  • formula <- prihod ~ .: Stvorite model koji odgovara
  • logit <- glm(formula, data = data_train, family = 'binomial'): Uklopi logistički model (family = 'binomial') s podacima data_train.
  • summary(logit): Ispis sažetka modela

Izlaz:

## 
## Call:
## glm(formula = formula, family = "binomial", data = data_train)
## ## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -2.6456  -0.5858  -0.2609  -0.0651   3.1982  
## 
## Coefficients:
##                           Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                0.07882    0.21726   0.363  0.71675    
## age                        0.41119    0.01857  22.146  < 2e-16 ***
## workclassLocal-gov        -0.64018    0.09396  -6.813 9.54e-12 ***
## workclassPrivate          -0.53542    0.07886  -6.789 1.13e-11 ***
## workclassSelf-emp-inc     -0.07733    0.10350  -0.747  0.45499    
## workclassSelf-emp-not-inc -1.09052    0.09140 -11.931  < 2e-16 ***
## workclassState-gov        -0.80562    0.10617  -7.588 3.25e-14 ***
## workclassWithout-pay      -1.09765    0.86787  -1.265  0.20596    
## educationCommunity        -0.44436    0.08267  -5.375 7.66e-08 ***
## educationHighGrad         -0.67613    0.11827  -5.717 1.08e-08 ***
## educationMaster            0.35651    0.06780   5.258 1.46e-07 ***
## educationPhD               0.46995    0.15772   2.980  0.00289 ** 
## educationdropout          -1.04974    0.21280  -4.933 8.10e-07 ***
## educational.num            0.56908    0.07063   8.057 7.84e-16 ***
## marital.statusNot_married -2.50346    0.05113 -48.966  < 2e-16 ***
## marital.statusSeparated   -2.16177    0.05425 -39.846  < 2e-16 ***
## marital.statusWidow       -2.22707    0.12522 -17.785  < 2e-16 ***
## raceAsian-Pac-Islander     0.08359    0.20344   0.411  0.68117    
## raceBlack                  0.07188    0.19330   0.372  0.71001    
## raceOther                  0.01370    0.27695   0.049  0.96054    
## raceWhite                  0.34830    0.18441   1.889  0.05894 .  
## genderMale                 0.08596    0.04289   2.004  0.04506 *  
## hours.per.week             0.41942    0.01748  23.998  < 2e-16 ***
## ---## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## ## (Dispersion parameter for binomial family taken to be 1)
## ##     Null deviance: 40601  on 36428  degrees of freedom
## Residual deviance: 27041  on 36406  degrees of freedom
## AIC: 27087
## 
## Number of Fisher Scoring iterations: 6

Sažetak našeg modela otkriva zanimljive podatke. Učinkovitost logističke regresije procjenjuje se pomoću specifičnih ključnih metrika.

  • AIC (Akaike informacijski kriteriji): Ovo je ekvivalent R2 u logističkoj regresiji. Mjeri prikladnost kada se kazna primijeni na broj parametara. Manji AIC vrijednosti pokazuju da je model bliži istini.
  • Nulta devijacija: odgovara modelu samo s presjekom. Stupanj slobode je n-1. Možemo je protumačiti kao vrijednost hi-kvadrat (prilagođena vrijednost koja se razlikuje od testiranja hipoteze stvarne vrijednosti).
  • Rezidualna devijacija: Model sa svim varijablama. Također se tumači kao testiranje hi-kvadrat hipoteze.
  • Broj ponavljanja Fisherova bodovanja: Broj ponavljanja prije konvergiranja.

Izlaz funkcije glm() pohranjuje se na popis. Kod u nastavku prikazuje sve stavke dostupne u logit varijabli koju smo konstruirali za procjenu logističke regresije.

# Popis je jako dug, ispišite samo prva tri elementa

lapply(logit, class)[1:3]

Izlaz:

## $coefficients
## [1] "numeric"
## 
## $residuals
## [1] "numeric"
## 
## $fitted.values
## [1] "numeric"

Svaka vrijednost može biti npr.tracoznačeno znakom $ nakon kojeg slijedi naziv metrike. Na primjer, model ste pohranili kao logit. Na primjertracPrema AIC kriterijima, koristite:

logit$aic

Izlaz:

## [1] 27086.65

Korak 7) Procijenite izvedbu modela

Matrica zabune

The matrica zabune je bolji izbor za procjenu izvedbe klasifikacije u usporedbi s različitim mjernim podacima koje ste vidjeli prije. Opća ideja je brojati koliko su puta True instance klasificirane kao False.

Matrica zabune

Da biste izračunali matricu zabune, prvo morate imati skup predviđanja kako bi se mogla usporediti sa stvarnim ciljevima.

predict <- predict(logit, data_test, type = 'response')
# confusion matrix
table_mat <- table(data_test$income, predict > 0.5)
table_mat

Code Objašnjenje

  • predict(logit,data_test, type = 'response'): Izračunajte predviđanje na skupu testova. Postavite type = 'response' za izračunavanje vjerojatnosti odgovora.
  • table(data_test$income, predict > 0.5): Izračunajte matricu zabune. predict > 0.5 znači da vraća 1 ako su predviđene vjerojatnosti iznad 0.5, inače 0.

Izlaz:

##        
##         FALSE TRUE
##   <=50K  6310  495
##   >50K   1074 1229	

Svaki redak u matrici konfuzije predstavlja stvarni cilj, dok svaki stupac predstavlja predviđeni cilj. Prvi redak ove matrice uzima u obzir prihod niži od 50 tisuća dolara (negativna klasa): 6,310 opažanja ispravno je klasificirano kao pojedinci s prihodom nižim od 50 tisuća dolara (Istinski negativan), dok je 495 pogrešno klasificirano kao iznad 50 tisuća (Lažno pozitivno). Drugi redak uzima u obzir prihod iznad 50 tisuća: 1,229 je ispravno identificirano (Prava pozitiva), dok je 1,074 propušteno (Lažno negativan).

Možete izračunati model točnost zbrajanjem stvarnog pozitivnog + istinskog negativnog ukupnog promatranja

Matrica zabune

accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)
accuracy_Test

Code Objašnjenje

  • sum(diag(table_mat)): Zbroj dijagonale
  • sum(table_mat): Zbroj matrice.

Izlaz:

## [1] 0.8277339

Čini se da model pati od jednog problema: proizvodi previše lažno negativnih rezultata. To se naziva paradoks testa točnostiNaveli smo da je točnost omjer točnih predviđanja i ukupnog broja slučajeva. Možemo imati relativno visoku točnost, ali beskoristan model. To se događa kada postoji dominantna klasa. Ako pogledate matricu zbunjenosti, možete vidjeti da je većina slučajeva klasificirana kao istinski negativna. Zamislite sada da je model klasificirao svako opažanje kao negativno (tj. ispod 50 tisuća). I dalje biste dobili točnost od oko 75 posto (6,805 / 9,108). Vaš model radi bolje, ali se muči razlikovati istinski pozitivno od istinski negativnog.

U takvoj situaciji poželjno je imati sažetiju metriku. Možemo pogledati:

  • Preciznost=TP/(TP+FP)
  • Opoziv=TP/(TP+FN)

Preciznost protiv prisjećanja

Preciznost gleda na točnost pozitivnog predviđanja. Podsjetiti je omjer pozitivnih instanci koje je klasifikator ispravno otkrio;

Možete konstruirati dvije funkcije za izračunavanje ove dvije metrike

  1. Konstruirajte preciznost
precision <- function(matrix) {
	# True positive
    tp <- matrix[2, 2]
	# false positive
    fp <- matrix[1, 2]
    return (tp / (tp + fp))
}

Code Objašnjenje

  • mat[1,1]: vraća prvu ćeliju prvog stupca podatkovnog okvira, tj. pravi pozitivan
  • prostirka[1,2]; Vrati prvu ćeliju drugog stupca podatkovnog okvira, tj. lažno pozitivno
recall <- function(matrix) {
# true positive
    tp <- matrix[2, 2]# false positive
    fn <- matrix[2, 1]
    return (tp / (tp + fn))
}

Code Objašnjenje

  • mat[1,1]: vraća prvu ćeliju prvog stupca podatkovnog okvira, tj. pravi pozitivan
  • prostirka[2,1]; Vrati drugu ćeliju prvog stupca podatkovnog okvira, tj. lažno negativno

Možete testirati svoje funkcije

prec <- precision(table_mat)
prec
rec <- recall(table_mat)
rec

Izlaz:

## [1] 0.712877
## [2] 0.5336518

Pažljivo pročitajte ova dva broja. Preciznost je 0.71, pa kada model kaže da pojedinac zarađuje više od 50 tisuća, to je točno u 71 posto slučajeva. Podsjetnik je 0.53, pa model detektira samo 53 posto pojedinaca koji stvarno zarađuju više od 50 tisuća.

Možete stvoriti Preciznost protiv prisjećanja rezultat na temelju preciznosti i prisjećanja. The Preciznost protiv prisjećanja je harmonijska sredina ove dvije metrike, što znači da daje veću težinu nižim vrijednostima.

Preciznost protiv prisjećanja

f1 <- 2 * ((prec * rec) / (prec + rec))
f1

Izlaz:

## [1] 0.6103799

Kompromis preciznosti u odnosu na opoziv

Nemoguće je imati i visoku preciznost i visoko pamćenje.

Ako povećamo preciznost, točna će se osoba bolje predvidjeti, ali bismo propustili puno njih (slabije pamćenje). U nekim situacijama više volimo veću preciznost od opoziva. Postoji konkavan odnos između preciznosti i prisjećanja.

  • Zamislite, morate predvidjeti ima li pacijent bolest. Želite biti što precizniji.
  • Ako trebate otkriti potencijalne prevarante na ulici putem prepoznavanja lica, bilo bi bolje uhvatiti mnogo ljudi označenih kao prevaranti iako je preciznost niska. Policija će moći pustiti osobu koja nije prijevaru.

ROC krivulja

The Prijamnik Operating Karakterističan krivulja je još jedan uobičajeni alat koji se koristi s binarnom klasifikacijom. Vrlo je slična krivulji preciznost/prisjećanje, ali umjesto iscrtavanja preciznosti u odnosu na prisjećanje, ROC krivulja pokazuje pravu pozitivnu stopu (tj. prisjećanje) naspram lažno pozitivne stope. Lažno pozitivna stopa je omjer negativnih slučajeva koji su netočno klasificirani kao pozitivni. Jednaka je jedan minus prava negativna stopa. Prava negativna stopa također se naziva specifičnost. Stoga je prikazana ROC krivulja osjetljivost (prisjećanje) u odnosu na 1-specifičnost

Za crtanje ROC krivulje, potrebno je instalirati paket pod nazivom ROCR. Možemo ga pronaći u conda knjižnica. Možete upisati kod:

conda install -c r r-rocr --yes

Možemo iscrtati ROC s funkcijama prediction() i performance().

library(ROCR)
ROCRpred <- prediction(predict, data_test$income)
ROCRperf <- performance(ROCRpred, 'tpr', 'fpr')
plot(ROCRperf, colorize = TRUE, text.adj = c(-0.2, 1.7))

Code Objašnjenje

  • predviđanje(predviđanje, data_test$income): ROCR biblioteka treba stvoriti objekt predviđanja za transformaciju ulaznih podataka
  • performance(ROCRpred, 'tpr','fpr'): Vrati dvije kombinacije za izradu na grafikonu. Ovdje su konstruirani tpr i fpr. Za precizno iscrtavanje i opoziv zajedno koristite "prec", "rec".

Izlaz:

ROC krivulja

Korak 8) Poboljšajte model

Možete pokušati dodati nelinearnost modelu s interakcijom između

  • dob i sati.po.tjednu
  • spol i sati.po.tjednu.

Zatim uspoređujete F1 rezultat oba modela.

formula_2 <- income~age: hours.per.week + gender: hours.per.week + .
logit_2 <- glm(formula_2, data = data_train, family = 'binomial')
predict_2 <- predict(logit_2, data_test, type = 'response')
table_mat_2 <- table(data_test$income, predict_2 > 0.5)
precision_2 <- precision(table_mat_2)
recall_2 <- recall(table_mat_2)
f1_2 <- 2 * ((precision_2 * recall_2) / (precision_2 + recall_2))
f1_2

Izlaz:

## [1] 0.6109181

Rezultat F1 je nešto viši od prethodnog. Možete nastaviti raditi na podacima i pokušati nadmašiti rezultat.

Kako interpretirati GLM koeficijente i omjere šansi u R-u

Sažeta tablica ispisana u koraku 6 prikazuje koeficijente na logaritamske vjerojatnosti skala, što je teško objasniti netehničkoj publici. Pretvaranjem u omjere šansi model je puno lakši za komunikaciju.

Slijedite ova četiri koraka.

  1. Potenciraj koeficijente. Primijenite exp() na svaku procjenu tako da logaritamske vjerojatnosti postanu multiplikativni omjeri vjerojatnosti.
  2. Dodajte interval pouzdanosti. Omotajte confint() u exp() kako biste dobili interval od 95 posto na istoj skali vjerojatnosti.
  3. Usporedite svaku vrijednost s 1. Omjer šansi iznad 1 povećava vjerojatnost pozitivne klase, vrijednost ispod 1 je smanjuje, a vrijednost blizu 1 znači da prediktor malo dodaje.
  4. Provjerite statističku značajnost. Interpretirajte samo prediktore čija je p-vrijednost u sažetku ispod odabranog praga, obično 0.05.
# Convert log-odds coefficients into odds ratios
odds_ratio <- exp(coef(logit))
round(odds_ratio, 3)

# Odds ratios with 95% confidence intervals
exp(cbind(OddsRatio = coef(logit), confint(logit)))

Čitanje izlaza. Koeficijent za sate tjedno u našem modelu iznosi 0.41942. Njegovo potenciranje daje exp(0.41942) = 1.52, što znači da povećanje tjednog radnog vremena za jednu standardnu ​​devijaciju množi vjerojatnost zarade iznad 50 tisuća dolara s otprilike 1.5, držeći svaku drugu varijablu konstantnom.

Negativni koeficijenti funkcioniraju na isti način. marital.statusNot_married je -2.50346, pa je exp(-2.50346) = 0.08: neoženjene osobe imaju oko 8 posto vjerojatnosti za oženjenu osobu. Budući da su kontinuirani prediktori standardizirani u 1. koraku, opišite promjene u jedinicama standardne devijacije, a ne u sirovim satima.

Napomena za ostale obitelji: Eksponencijalni koeficijenti su omjeri šansi samo pod binomnom obitelji s logit vezom. S obitelji = "poisson" i log vezom, iste vrijednosti exp() čitaju se kao omjeri stopa.

GLM u R-u: Kratki pregled funkcija

Držite ovu tablicu pokraj sebe dok pišete kod. U njoj je navedena svaka funkcija korištena u gornjih osam koraka, zajedno s paketom koji je pruža i argumentima koje očekuje.

Paket Cilj funkcija Argument
- Stvorite skup podataka o vlaku/testiranju create_train_set() podaci, veličina, vlak
glm Uvježbajte generalizirani linearni model glm() formula, podaci, obitelj*
glm Sažmite model Sažetak() ugrađeni model
baza Napravite predviđanje predvidjeti() prilagođeni model, skup podataka, tip = 'odgovor'
baza Napravite matricu zabune stol() y, predvidi()
baza Stvorite ocjenu točnosti zbroj(dijag(tablica())/zbroj(tablica()
ROCR Stvorite ROC: Korak 1 Stvorite predviđanje predviđanje() predvidjeti(), y
ROCR Stvorite ROC: 2. korak Stvorite izvedbu izvođenje() predviđanje(), 'tpr', 'fpr'
ROCR Stvorite ROC: korak 3 Iscrtajte grafikon zemljište() izvođenje()

Drugi GLM obitelji dostupne putem obiteljskog argumenta su:

  • binom: (link = “logit”)
  • gaussova: (veza = “identitet”)
  • Gama: (link = “inverzno”)
  • inverzna.gaussova: (link = “1/mu^2”)
  • poisson: (link = “log”)
  • kvazi: (veza = „identitet“, varijanca = „konstanta“)
  • kvazibinom: (link = “logit”)
  • kvazipoisson: (link = “log”)

Pitanja i odgovori

Argument obitelji deklarira raspodjelu vjerojatnosti odgovora i njegovu zadanu funkciju povezivanja. Koristite binomnu raspodjelu za binarne ishode, Poissonovu za brojeve, Gama za pozitivne asimetrične vrijednosti i Gaussovu za reprodukciju obične linearne regresije.

Prekomjerna disperzija se javlja kada rezidualna devijacija daleko premašuje stupnjeve slobode. Prebacite familiju na kvazibinomnu ili kvazipoissonovu, što mijenja skalu standardnih pogrešaka, ili prilagodite negativni binomni model s glm.nb() iz MASS paket.

Granična vrijednost od 0.5 je samo konvencija. Odaberite prag iz ROC krivulje ili krivulje preciznosti i prisjećanja koji odgovara vašem trošku pogrešaka. Snizite ga kako biste uhvatili više pozitivnih rezultata, a povisite ga kada je lažno pozitivan skup.

AI cjevovodi i dalje se oslanjaju na GLM-ove kao brze, transparentne osnove za kreditno bodovanje, odljev klijenata i modele rizika. Regulirane industrije ih preferiraju jer se svaki koeficijent može revidirati, za razliku od neprozirnih težina duboke neuronske mreže.

Da. AI asistenti mogu skicirati glm() pozive, objasniti izlaz odstupanja i označiti uobičajene pogreške poput nekonvergiranih modela ili kolinearnih prediktora. Uvijek provjerite generirani kod u odnosu na vlastite podatke prije nego što povjerujete rezultatima.

Sažmite ovu objavu uz: