Logistisk regression – en komplet vejledning med eksempler i R

Logistisk regression er en algoritme til prædiktiv modellering, der anvendes, når Y-variablen er binær kategorisk. Det vil sige, at den kun kan antage to værdier som 1 eller 0. Målet er at bestemme en matematisk ligning, der kan bruges til at forudsige sandsynligheden for hændelse 1. Når ligningen er fastlagt, kan den bruges til at forudsige Y, når kun X�erne er kendt.

Logistisk regression – en komplet vejledning med eksempler i R Indholdsfortegnelse1. Introduktion til logistisk regression
2. Nogle eksempler fra den virkelige verden på binære klassifikationsproblemer
3. Hvorfor ikke lineær regression?
4. Den logistiske ligning
5. Hvordan opbygger man logistisk regressionsmodel i R?
6. Hvordan håndterer man klasseubalance?
7. Hvordan håndterer man klasseubalance med Upsample og Downsample?
8. Opbygning af den logistiske regressionsmodel
9. Hvordan man forudsiger på Test Dataset
10. Hvorfor håndtering med klasseubalance er vigtig?
11. Konklusion

1. Introduktion til logistisk regression

Førhen så du, hvad lineær regression er, og hvordan du kan bruge den til at forudsige kontinuerlige Y-variabler.

I lineær regression er Y-variablen altid en kontinuerlig variabel. Hvis vi antager, at Y-variablen var kategorisk, kan du ikke bruge lineær regression til at modellere den.

Så hvad gør du, når Y er en kategorisk variabel med 2 klasser?

Logistisk regression kan bruges til at modellere og løse sådanne problemer, også kaldet binære klassifikationsproblemer.

Et vigtigt punkt at bemærke her er, at Y kun kan have 2 klasser og ikke flere end det. Hvis Y har mere end 2 klasser, vil det blive en klassifikation med flere klasser, og du kan ikke længere bruge vanilla logistisk regression til det.

Den logistiske regression er dog en klassisk prædiktiv modelleringsteknik og er stadig et populært valg til modellering af binære kategoriske variabler.

En anden fordel ved logistisk regression er, at den beregner en sandsynlighedsscore for forudsigelse af en begivenhed. Mere om det, når du rent faktisk begynder at opbygge modellerne.

Nogle eksempler fra den virkelige verden på binære klassifikationsproblemer

Du undrer dig måske over, hvilke typer problemer du kan bruge logistisk regression til.

Her er nogle eksempler på binære klassifikationsproblemer:

  • Spam-detektion : Forudsigelse af, om en e-mail er spam eller ej
  • Kreditkortsvindel : Forudsigelse af, om en given kreditkorttransaktion er svindel eller ej
  • Sundhed : Forudsigelse af, om en given vævsmasse er godartet eller ondartet
  • Markedsføring : Forudsigelse af, om en given bruger vil købe et forsikringsprodukt eller ej
  • Bankvæsen : Forudsigelse af, om en kunde vil misligholde et lån.

Hvorfor ikke lineær regression?

Når responsvariablen kun har 2 mulige værdier, er det ønskeligt at have en model, der forudsiger værdien enten som 0 eller 1 eller som en sandsynlighedsscore, der ligger mellem 0 og 1.

Linær regression har ikke denne mulighed. Fordi, Hvis du bruger lineær regression til at modellere en binær responsvariabel, kan den resulterende model muligvis ikke begrænse de forudsagte Y-værdier inden for 0 og 1.

Linear vs. logistisk regression

Det er her, at logistisk regression kommer ind i billedet. I logistisk regression får man en sandsynlighedsscore, der afspejler sandsynligheden for, at hændelsen forekommer.

En hændelse er i dette tilfælde hver række i træningsdatasættet. Det kunne være noget som at klassificere, om en given e-mail er spam, eller en cellemasse er ondartet, eller en bruger vil købe et produkt osv.

Den logistiske ligning

Logistisk regression opnår dette ved at tage log odds for begivenheden ln(P/1?P), hvor P er sandsynligheden for begivenheden. P ligger altså altid mellem 0 og 1.

Tager man eksponent på begge sider af ligningen, giver det:

Du kan implementere denne ligning ved hjælp af glm()-funktionen ved at indstille family-argumentet til "binomial".

Et vigtigt forbehold er også, at du skal sørge for at indstille type="response", når du bruger predict-funktionen på en logistisk regressionsmodel. Ellers vil den forudsige log odds for P, dvs. Z-værdien, i stedet for selve sandsynligheden.

Hvordan opbygger man logistisk regressionsmodel i R?

Nu skal vi se, hvordan man implementerer logistisk regression ved hjælp af BreastCancer-datasættet i mlbench-pakken. Du skal installere mlbench-pakken for at kunne gøre dette.

Målet her er at modellere og forudsige, om et givet eksemplar (række i datasættet) er benign eller malignant, baseret på 9 andre celleegenskaber. Så lad os indlæse dataene og kun beholde de komplette tilfælde.

Brystkræftdatasæt

Datasættet har 699 observationer og 11 kolonner. Kolonnen Class er responsvariablen (afhængig), og den fortæller, om et givet væv er malignt eller benignt.

Lad os kontrollere strukturen af dette datasæt.

Bortset fra Id er alle de andre kolonner faktorer. Dette er et problem, når du modellerer denne type data.

For når du opbygger en logistisk model med faktorvariabler som funktioner, konverterer den hvert niveau i faktoren til en binær dummy-variabel med 1’er og 0’er.

For eksempel er celleform en faktor med 10 niveauer. Når du bruger glm til at modellere klasse som en funktion af celleform, vil celleformen blive opdelt i 9 forskellige binære kategoriske variabler, før du opbygger modellen.

Hvis du skal opbygge en logistisk model uden at foretage nogen forberedende trin, så er det følgende, hvad du kan gøre. Men vi vil ikke følge dette, da der er visse ting, man skal tage sig af, før man bygger logitmodellen.

Syntaksen for at bygge en logitmodel ligner meget den lm-funktion, som du så i lineær regression. Du skal blot indstille family='binomial' til glm for at opbygge en logistisk regressionsmodel.

glm står for generaliserede lineære modeller, og den er i stand til at opbygge mange typer regressionsmodeller ud over lineær og logistisk regression.

Lad os se, hvordan koden til at opbygge en logistisk model kan se ud. Jeg vil komme til dette trin igen senere, da der er nogle forbehandlingstrin, der skal udføres, før modellen bygges.

I ovenstående model er Class modelleret som en funktion af Cell.shape alene.

Men bemærk ud fra output, at Cell.Shape blev opdelt i 9 forskellige variabler. Dette skyldes, at da Cell.Shape er gemt som en faktorvariabel, skaber glm 1 binær variabel (a.k.a. dummy-variabel) for hvert af de 10 kategoriske niveauer af Cell.Shape.

Det fremgår tydeligt af betydningen af Cell.Shape, at der synes at være en eller anden form for ordening inden for de kategoriske niveauer af Cell.Shape. Det vil sige, at en celleformværdi på 2 er større end celleform 1 osv.

Det er også tilfældet med andre variabler i datasættet. Så det er at foretrække at konvertere dem til numeriske variabler og fjerne id-kolonnen.

Hvis det havde været en ren kategorisk variabel uden intern ordening, som f.eks. patientens køn, kan man lade denne variabel være en faktor i sig selv.

# remove id columnbc <- bc# convert factors to numericfor(i in 1:9) { bc <- as.numeric(as.character(bc))}

Another important point to note. When converting a factor to a numeric variable, you should always convert it to character and then to numeric, else, the values can get screwed up.

Now all the columns are numeric.

Also I’d like to encode the response variable into a factor variable of 1’s and 0’s. Though, this is only an optional step.

So whenever the Class is malignant, it will be 1 else it will be 0. Then, I am converting it into a factor.

bc$Class <- ifelse(bc$Class == "malignant", 1, 0)bc$Class <- factor(bc$Class, levels = c(0, 1))

The response variable Class is now a factor variable and all other columns are numeric.

Alright, the classes of all the columns are set. Let’s proceed to the next step.

How to deal with Class Imbalance?

Before building the logistic regressor, you need to randomly split the data into training and test samples.

Since the response variable is a binary categorical variable, you need to make sure the training data has approximately equal proportion of classes.

table(bc$Class)#> benign malignant #> 444 239

Klasserne “benign” og “malign” er delt omtrent i forholdet 1:2.

Der er tydeligvis en klasseubalance. Så før logitmodellen opbygges, skal man opbygge stikprøverne således, at både 1’erne og 0’erne er i omtrent lige store proportioner.

Dette problem håndteres normalt med et par teknikker kaldet:

  • Down Sampling
  • Up Sampling
  • Hybrid Sampling ved hjælp af SMOTE og ROSE.

Så, hvad er Down Sampling og Up Sampling?

7. Hvordan håndteres klasseubalance med Upsampling og Downsampling

I Down sampling nedtages flertallet af klassen tilfældigt, så den er af samme størrelse som den mindre klasse. Det betyder, at når træningsdatasættet oprettes, vil rækkerne med den godartede klasse blive plukket færre gange under den tilfældige prøveudtagning.

Sådan er det også i UpSampling, at rækker fra minoritetsklassen, dvs. malignant, gentagne gange samples igen og igen, indtil den når samme størrelse som majoritetsklassen (benign).

Men i tilfælde af Hybrid sampling genereres kunstige datapunkter, der systematisk tilføjes omkring minoritetsklassen. Dette kan implementeres ved hjælp af pakkerne SMOTE og ROSE.

Men i dette eksempel vil jeg vise, hvordan man laver op- og nedadgående prøvetagning.

Så lad mig oprette trænings- og testdataene ved hjælp af caret-pakken.

I ovenstående uddrag har jeg indlæst caret-pakken og brugt funktionen createDataPartition til at generere rækketal for træningsdatasættet. Ved at indstille p=.70 har jeg valgt, at 70 % af rækkerne skal gå inden for trainData og de resterende 30 % skal gå til testData.

table(trainData$Class)

Der er ca. 2 gange flere godartede prøver. Så lad os downsample det ved hjælp af downSample-funktionen fra caret-pakken.

For at gøre dette skal du blot angive X- og Y-variablerne som argumenter.

Benign og malign er nu i samme forhold.

Den %ni% er negationen af %in%-funktionen, og jeg har brugt den her til at vælge alle kolonnerne undtagen Class-kolonnen.

Den downSample-funktion kræver ‘y’ som en faktorvariabel, det er grunden til, at jeg havde konverteret klassen til en faktor i de oprindelige data.

Glimrende! Lad mig nu foretage upsampling ved hjælp af upSample-funktionen. Den følger en lignende syntaks som downSample.

Som forventet er benign og malign nu i samme forhold.

Jeg vil bruge den downSamplede version af datasættet til at bygge logit-modellen i næste trin.

Bygning af den logistiske regressionsmodel

Sådan forudsiger jeg på testdatasættet

Den logitmod er nu bygget. Du kan nu bruge den til at forudsige svaret på testData.

pred <- predict(logitmod, newdata = testData, type = "response")

Nu indeholder pred sandsynligheden for, at observationen er malign for hver observation.

Bemærk, at når du bruger logistisk regression, skal du indstille type='response' for at kunne beregne forudsigelsessandsynlighederne. Dette argument er ikke nødvendigt i tilfælde af lineær regression.

Den almindelige praksis er at tage sandsynlighedsgrænseværdien som 0,5. Hvis sandsynligheden for Y er > 0,5, kan den klassificeres som en hændelse (malign).

Så hvis pred er større end 0,5, er den malign, ellers er den godartet.

y_pred_num <- ifelse(pred > 0.5, 1, 0)y_pred <- factor(y_pred_num, levels=c(0, 1))y_act <- testData$Class

Lad os beregne nøjagtigheden, som ikke er andet end andelen af y_pred, der passer med y_act.

mean(y_pred == y_act) 

Der har du en nøjagtighedsgrad på 94%.

Hvorfor håndtering med klasseubalance er vigtig?

Okay, jeg lovede, at jeg vil fortælle dig, hvorfor du skal tage dig af klasseubalance tidligere. For at forstå det lad os antage, at du har et datasæt, hvor 95% af Y-værdierne tilhører den godartede klasse og 5% tilhører den ondartede klasse.

Hvis jeg bare blindt havde forudsagt alle datapunkterne som godartede, ville jeg opnå en nøjagtighedsprocent på 95%. Hvilket lyder ret højt. Men det er naturligvis fejlbehæftet. Det afgørende er, hvor godt du forudsiger de ondartede klasser.

Så det kræver, at de godartede og ondartede klasser er afbalancerede OG oven i købet har jeg brug for mere raffinerede nøjagtighedsmålinger og model-evalueringsmetrikker for at forbedre min forudsigelsesmodel.

Fuld kode

Slutning

I dette indlæg så du, hvornår og hvordan du kan bruge logistisk regression til at klassificere binære responsvariabler i R.

Du så dette med et eksempel baseret på datasættet BreastCancer, hvor målet var at bestemme, om en given vævsmasse er malign eller benign.

Opbygning af modellen og klassificering af Y er kun halvt arbejde udført. Faktisk ikke engang halvdelen. For omfanget af evalueringsmetrikker til vurdering af modellens effektivitet er stort og kræver en omhyggelig vurdering for at vælge den rigtige model. I den næste del vil jeg diskutere forskellige evalueringsmetrikker, der kan hjælpe med at forstå, hvor godt klassifikationsmodellen klarer sig ud fra forskellige perspektiver.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.