Logistisk regression – en komplett handledning med exempel i R

Logistisk regression är en algoritm för prediktiv modellering som används när Y-variabeln är binär kategorisk. Det vill säga att den bara kan anta två värden som 1 eller 0. Målet är att fastställa en matematisk ekvation som kan användas för att förutsäga sannolikheten för händelse 1. När ekvationen väl är fastställd kan den användas för att förutsäga Y när endast X�s är kända.

Logistisk regression – en komplett handledning med exempel i R Innehåll1. Introduktion till logistisk regression
2. Några verkliga exempel på binära klassificeringsproblem
3. Varför inte linjär regression?
4. Den logistiska ekvationen
5. Hur man bygger en logistisk regressionsmodell i R?
6. Hur man hanterar obalans mellan klasser?
7. Hur man hanterar obalans mellan klasser med Upsample och Downsample?
8. Byggandet av den logistiska regressionsmodellen
9. Hur man förutspår på testdatasetet
10. Varför är det viktigt att hantera obalans mellan klasser?
11. Slutsats

1. Introduktion till logistisk regression

Förut såg du vad linjär regression är och hur man använder den för att förutsäga kontinuerliga Y-variabler.

I linjär regression är Y-variabeln alltid en kontinuerlig variabel. Om vi antar att Y-variabeln är kategorisk kan du inte använda linjär regression för att modellera den.

Vad gör du då när Y är en kategorisk variabel med två klasser?

Logistisk regression kan användas för att modellera och lösa sådana problem, även kallade binära klassificeringsproblem.

En viktig punkt att notera här är att Y endast kan ha två klasser och inte fler än så. Om Y har fler än 2 klasser blir det en klassificering med flera klasser och du kan inte längre använda logistisk regression för detta.

Då är logistisk regression en klassisk teknik för prediktiv modellering och förblir fortfarande ett populärt val för modellering av binära kategoriska variabler.

En annan fördel med logistisk regression är att den beräknar en sannolikhetspoäng för förutsägelse av en händelse. Mer om det när du faktiskt börjar bygga modellerna.

Några verkliga exempel på binära klassificeringsproblem

Du kanske undrar vilken typ av problem du kan använda logistisk regression för.

Här är några exempel på binära klassificeringsproblem:

  • Spamdetektering : Förutsägelse av om ett e-postmeddelande är skräppost eller inte
  • Kreditkortsbedrägeri : Förutsägelse av om en viss kreditkortstransaktion är bedrägeri eller inte
  • Hälsa : Förutsägelse om en viss vävnadsmassa är godartad eller elakartad
  • Marknadsföring : Förutsägelse om en viss användare kommer att köpa en försäkringsprodukt eller inte
  • Bankverksamhet : Förutsägelse om en kund inte kommer att betala ett lån.

Varför inte linjär regression?

När svarsvariabeln endast har två möjliga värden är det önskvärt att ha en modell som förutspår värdet antingen som 0 eller 1 eller som en sannolikhetspoäng som ligger mellan 0 och 1.

Den linjära regressionen har inte denna möjlighet. Eftersom, Om du använder linjär regression för att modellera en binär svarsvariabel kan den resulterande modellen inte begränsa de förutspådda Y-värdena inom 0 och 1.

Linjär vs logistisk regression

Det är här som logistisk regression kommer in i bilden. I logistisk regression får du ett sannolikhetsvärde som återspeglar sannolikheten för att händelsen ska inträffa.

En händelse i det här fallet är varje rad i träningsdatasetet. Det kan vara något som att klassificera om ett visst e-postmeddelande är skräppost eller om en cellmassa är elakartad eller om en användare kommer att köpa en produkt och så vidare.

Den logistiska ekvationen

Logistisk regression uppnår detta genom att ta logaritmiska oddsen för händelsen ln(P/1?P), där P är sannolikheten för händelsen. Så P ligger alltid mellan 0 och 1.

Tar man exponenten på båda sidor av ekvationen får man:

Du kan implementera den här ekvationen med hjälp av glm()-funktionen genom att ställa in family-argumentet till "binomial".

En viktig varning är också att se till att du ställer in type="response" när du använder predict-funktionen på en logistisk regressionsmodell. Annars kommer den att förutsäga log odds för P, det vill säga Z-värdet, istället för själva sannolikheten.

Hur bygger man en logistisk regressionsmodell i R?

Nu ska vi se hur man implementerar logistisk regression med hjälp av BreastCancer-dataset i mlbench-paketet. Du måste installera mlbench-paketet för detta.

Målet här är att modellera och förutsäga om ett givet prov (rad i datasetet) är benign eller malignant, baserat på 9 andra cellfunktioner. Så låt oss ladda in data och bara behålla de fullständiga fallen.

Bröstcancerdataset

Dataset har 699 observationer och 11 kolumner. Kolumnen Class är svarsvariabeln (den beroende variabeln) och den talar om huruvida en viss vävnad är malign eller benign.

Vi kan kontrollera strukturen på detta dataset.

Med undantag för Id är alla andra kolumner faktorer. Detta är ett problem när du modellerar den här typen av data.

För att när du bygger en logistisk modell med faktorvariabler som funktioner omvandlas varje nivå i faktorn till en binär dummyvariabel med 1:or och 0:or.

Till exempel är Cell shape en faktor med 10 nivåer. När du använder glm för att modellera Class som en funktion av cellform kommer cellformen att delas upp i 9 olika binära kategoriska variabler innan du bygger modellen.

Om du ska bygga en logistisk modell utan att göra några förberedande steg kan du göra följande. Men vi kommer inte att följa detta eftersom det finns vissa saker att ta hand om innan man bygger logitmodellen.

Syntaxen för att bygga en logitmodell är mycket lik lm-funktionen som du såg i linjär regression. Du behöver bara ställa in family='binomial' för glm för att bygga en logistisk regressionsmodell.

glm står för generaliserade linjära modeller och kan bygga många typer av regressionsmodeller förutom linjär och logistisk regression.

Låt oss se hur koden för att bygga en logistisk modell kan se ut. Jag kommer att återkomma till detta steg senare eftersom det finns några förbehandlingssteg som måste göras innan modellen byggs.

I ovanstående modell modelleras Class som en funktion av enbart Cell.shape.

Men observera att Cell.Shape har delats upp i 9 olika variabler i utmatningen. Detta beror på att eftersom Cell.Shape lagras som en faktorvariabel skapar glm 1 binär variabel (a.k.a. dummyvariabel) för var och en av de 10 kategoriska nivåerna av Cell.Shape.

Det framgår tydligt av innebörden av Cell.Shape att det tycks finnas någon form av ordningsföljd inom de kategoriska nivåerna av Cell.Shape. Det vill säga, ett cellformsvärde på 2 är större än cellform 1 och så vidare.

Detta gäller även för andra variabler i datasetet. Därför är det bättre att omvandla dem till numeriska variabler och ta bort id-kolumnen.

Hade det varit en ren kategorisk variabel utan intern ordning, som till exempel patientens kön, kan man låta den variabeln vara en faktor i sig själv.

# 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

Klasserna “godartad” och “elakartad” är uppdelade ungefär i ett 1:2-förhållande.

Det är uppenbart att det finns en obalans mellan klasserna. Så innan man bygger logitmodellen måste man bygga upp stickproven så att både 1:orna och 0:orna är i ungefär lika stora proportioner.

Detta problem hanteras normalt med ett par tekniker som kallas:

  • Down Sampling
  • Up Sampling
  • Hybrid Sampling med hjälp av SMOTE och ROSE.

Vad är Down Sampling och Up Sampling?

7. Hur man hanterar obalans mellan klasser med Upsampling och Downsampling

I Down Sampling tas ett slumpmässigt Down Sampling av majoritetsklassen för att den ska vara lika stor som den mindre klassen. Det innebär att när utbildningsdatasetet skapas kommer raderna med den godartade klassen att plockas färre gånger under den slumpmässiga provtagningen.

På samma sätt, i UpSampling, provtas rader från minoritetsklassen, det vill säga malignant, upprepade gånger om och om igen tills den uppnår samma storlek som majoritetsklassen (benign).

Men i fallet Hybrid sampling genereras artificiella datapunkter som systematiskt läggs till runt minoritetsklassen. Detta kan implementeras med hjälp av paketen SMOTE och ROSE.

Hur som helst för det här exemplet kommer jag att visa hur man gör uppåt- och nedåtriktad sampling.

Så låt mig skapa Tränings- och testdata med hjälp av caret-paketet.

I ovanstående utdrag har jag laddat caret-paketet och använt createDataPartition-funktionen för att generera radnumren för träningsdatasetet. Genom att ställa in p=.70 har jag valt att 70 % av raderna ska gå in i trainData och resterande 30 % ska gå till testData.

table(trainData$Class)

Det finns ungefär 2 gånger fler godartade prover. Så låt oss minska urvalet med hjälp av downSample-funktionen från caret-paketet.

För att göra detta behöver du bara ange X- och Y-variablerna som argument.

Benignt och malignt är nu i samma förhållande.

Funktionen %ni% är negationen av funktionen %in% och jag har använt den här för att välja alla kolumner utom kolumnen Class.

Funktionen downSample kräver “y” som en faktorvariabel, det är anledningen till att jag hade konverterat klassen till en faktor i de ursprungliga uppgifterna.

Snyggt! Låt mig nu göra upsampling med hjälp av upSample-funktionen. Den följer en liknande syntax som downSample.

Som väntat är benign och malign nu i samma förhållande.

Jag kommer att använda den nedprovade versionen av datasetet för att bygga logitmodellen i nästa steg.

Byggandet av den logistiska regressionsmodellen

Hur man förutspår på testdataset

Det logitmod är nu byggt. Du kan nu använda den för att förutsäga svaret på testData.

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

Nu innehåller pred sannolikheten för att observationen är malign för varje observation.

Notera att när du använder logistisk regression måste du ställa in type='response' för att beräkna förutsägelsesannolikheterna. Detta argument behövs inte vid linjär regression.

Det är vanligt att ta sannolikhetsgränsen som 0,5. Om sannolikheten för Y är > 0,5 kan det klassificeras som en händelse (malign).

Så om pred är större än 0,5 är det malignt annars är det benignt.

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

Låt oss beräkna noggrannheten, som inte är något annat än andelen y_pred som stämmer med y_act.

mean(y_pred == y_act) 

Där har du en noggrannhet på 94 %.

Varför är det viktigt att hantera obalans mellan klasser?

Okej, jag lovade att jag ska berätta varför du måste ta hand om obalans mellan klasser tidigare. För att förstå det kan vi anta att du har ett dataset där 95 % av Y-värdena tillhör den godartade klassen och 5 % tillhör den elakartade klassen.

Om jag bara blint hade förutspått att alla datapunkter var godartade skulle jag uppnå en noggrannhetsprocent på 95 %. Vilket låter ganska högt. Men det är uppenbart att det är bristfälligt. Det viktiga är hur väl du förutsäger de maligna klasserna.

Så det kräver att de godartade och maligna klasserna är balanserade OCH dessutom behöver jag mer förfinade noggrannhetsmått och modellutvärderingsmått för att förbättra min förutsägelsemodell.

Full kod

Slutsats

I det här inlägget såg du när och hur du kan använda logistisk regression för att klassificera binära svarsvariabler i R.

Du såg detta med ett exempel som baserades på datasetetet BreastCancer där målet var att avgöra om en viss vävnadsmassa är malign eller godartad.

Byggandet av modellen och klassificeringen av Y är bara halva arbetet gjort. Egentligen inte ens hälften. Eftersom omfattningen av utvärderingsmått för att bedöma modellens effektivitet är stor och kräver noggrann bedömning för att välja rätt modell. I nästa del kommer jag att diskutera olika utvärderingsmått som hjälper till att förstå hur väl klassificeringsmodellen fungerar ur olika perspektiv.

Lämna ett svar

Din e-postadress kommer inte publiceras.