Objasnienie Celu Projektu

Wczesna diagnoza czynników, zwiększających ryzyko chorób serca, umożliwia podjęcie odpowiednich środków ostrożności we właściwym czasie. Badania koncentrują się na przewidywaniu, które głównie z tych czynników, prowadzą do analizowanych chorób serca. Celem projektu było zbadanie jakie czynniki mają wpływ na choroby serca przy wykorzystaniu regresji oraz drzewa decyzyjnego.

Źródło: http://mlr.cs.umass.edu/ml/machine-learning-databases/statlog/heart

Opis zmiennych

V1 - age (integer)

V2 - sex (binary)

V3 - chest pain type (categorical with 4 levels)

V4 - resting blood pressure (continuous)

V5 - serum cholestoral in mg/dl (continuous)

V6 - fasting blood sugar > 120 mg/dl (binary)

V7 - resting electrocardiographic results (categorical with 3 levels)

V8 - maximum heart rate achieved (continuous)

V9 - exercise induced angina (binary)

V10 - oldpeak = ST depression induced by exercise relative to rest

V11 - the slope of the peak exercise ST segment (categorical with 3 levels)

V12 - number of major vessels colored by flourosopy (categorical with 4 levels)

V13 - thal: 3 = normal ; 6 = fixed defect; 7 = reversable defect (categorical with 3 levels)

V14 - absence (1) or presence (2) of heart disease

dane <- read.csv("http://mlr.cs.umass.edu/ml/machine-learning-databases/statlog/heart/heart.dat", header=FALSE, sep=" ")
head(dane,15)
##    V1 V2 V3  V4  V5 V6 V7  V8 V9 V10 V11 V12 V13 V14
## 1  70  1  4 130 322  0  2 109  0 2.4   2   3   3   2
## 2  67  0  3 115 564  0  2 160  0 1.6   2   0   7   1
## 3  57  1  2 124 261  0  0 141  0 0.3   1   0   7   2
## 4  64  1  4 128 263  0  0 105  1 0.2   2   1   7   1
## 5  74  0  2 120 269  0  2 121  1 0.2   1   1   3   1
## 6  65  1  4 120 177  0  0 140  0 0.4   1   0   7   1
## 7  56  1  3 130 256  1  2 142  1 0.6   2   1   6   2
## 8  59  1  4 110 239  0  2 142  1 1.2   2   1   7   2
## 9  60  1  4 140 293  0  2 170  0 1.2   2   2   7   2
## 10 63  0  4 150 407  0  2 154  0 4.0   2   3   7   2
## 11 59  1  4 135 234  0  0 161  0 0.5   2   0   7   1
## 12 53  1  4 142 226  0  2 111  1 0.0   1   0   7   1
## 13 44  1  3 140 235  0  2 180  0 0.0   1   0   3   1
## 14 61  1  1 134 234  0  0 145  0 2.6   2   2   3   2
## 15 57  0  4 128 303  0  2 159  0 0.0   1   1   3   1

Prezentacja rozkladu zmiennych objasniajacych

Healthy <- sum(dane$V14 == 1)
Sick <- sum(dane$V14 == 2)

se <-c(Healthy,Sick)

label <-c("Healthy patients","Sick pateints")

pct <- round(se/sum(se)*100)

label <- paste(label, pct) 
label <- paste(label,"%",sep="") 

pie(se, 
    labels=label, 
    col=c("darkolivegreen1","indianred1"), 
    main="All patients", 
    border = 'black')

# Wykres dla zmiennych: Age, RestBP, Chol, MaxHR, Oldpeak, AHD
data_df <- dane[, c(1, 4, 5, 8, 10, 14)]
str(data_df)
## 'data.frame':    270 obs. of  6 variables:
##  $ V1 : num  70 67 57 64 74 65 56 59 60 63 ...
##  $ V4 : num  130 115 124 128 120 120 130 110 140 150 ...
##  $ V5 : num  322 564 261 263 269 177 256 239 293 407 ...
##  $ V8 : num  109 160 141 105 121 140 142 142 170 154 ...
##  $ V10: num  2.4 1.6 0.3 0.2 0.2 0.4 0.6 1.2 1.2 4 ...
##  $ V14: int  2 1 2 1 1 1 2 2 2 2 ...
pairs(data_df)

dane$V14 <- factor(dane$V14)
levels(dane$V14) <- c("Healthy", "Sick")

hist(dane$V1, xlab="Age", ylab="Patients", main="Age of patients",
     xlim=c(20,80), breaks = 11, col = terrain.colors(11), border = 'black')

theme_set(theme_light()) 
fill <- "#4271AE"
line <- "#1F3552"
ggplot(dane, aes(x = V14, y = V4, fill=V14)) + 
  geom_boxplot(fill = fill, colour = line, alpha=0.7) + 
     scale_y_continuous(name = "Patients") +
        scale_x_discrete(name = "Healthy/Sick") +
  theme(legend.position = "none") + 
  labs(title = "Resting blood pressure")

theme_set(theme_light()) 
fill <- "#900C3F"
line <- "#270A04"
ggplot(dane, aes(x = V14, y = V8, fill=V14)) + 
  geom_boxplot(fill = fill, colour = line, alpha=0.7) + 
     scale_y_continuous(name = "Patients") +
        scale_x_discrete(name = "Healthy/Sick") +
  theme(legend.position = "none") + 
  labs(title = "Heart rate")

Interpretacja wykresów

Z danych wynika, że aż 44% badanych pacentów choruje na choroby serca. Próbka badanych pacentów wynosiła 270 osób, z czego przedział wiekowy badanych, wynosił od 29 lat do 77lat. Najliczniejszą grupą wiekową były osoby pomiędzy 50, a 60 rokiem życia.

Zauważyć należy, że zarówno osoby zdrowe jak i chore mają taką sama medianę spoczynkowego ciśnienia krwi, natomiast u osób chorych można dostrzec szerszy zakres wartości, natomiast jeżeli chodzi o tętno,wykres wyraźnie pokazuje, że osoby z chorobami serca mają zdecydowanie niższe tętno niż osoby zdrowe.

gestosc <-density(dane$V5)
plot(gestosc,main="Level of patients cholesterol",xlab="CHL in mg/dl",col="lightgreen")   
polygon(gestosc, col="lightblue", border="black")

quantile(dane$V5)
##   0%  25%  50%  75% 100% 
##  126  213  245  280  564
groups <-cut(dane$V5,breaks=c(0,213,245,565))
groups <- factor(groups)
levels(groups) <- c("normal", "admissible", "high")
plot(groups, main="Group of patients for CHL", col=blues9, ylim=c(0,180))

Kategoryzacja

Wykonano podział zmiennej wielkości poziomu cholesterolu u badanych pacjentów na 3 grupy:

0 - 213 - normal (oznacza, że poziom cholesterolu jest W normie)

213 - 245 - admissible (oznacza, że poziom cholesterolu jest na poziomie dopuszczalnym)

245 - 565 - high (oznacza, że poziom cholesterolu jest zbyt wysoki)

Analizując wykres, widać wyraźnie, iż najliczniejsza grupa znalazła się w przedziale high - zbyt wysoki.

matrix <-table(groups,dane$V14)
sum(matrix)
## [1] 270
plot(matrix, col=c("darkolivegreen1", "indianred1"), main="Level of CHL vs Diagnosis", xlab="Level of CHL", ylab="Diagnosis")

chisq.test(matrix)
## 
##  Pearson's Chi-squared test
## 
## data:  matrix
## X-squared = 10.529, df = 2, p-value = 0.005172

Zmienna nie jest istotna statystycznie, gdyż wartość p-value jest powyżej zakładanego (0,05).

Drzewo decyzyje

W poniższych krokach, zostanie stworzone drzewo decyzyjne dla zbioru treningowego oraz dla zbioru testowego, wyniki zostaną porównane za pomocą krzywej ROC.

Drzewo <- dane
V5 <-cut(Drzewo$V5,breaks=c(0,200,239,570))
V5 <- factor(V5)
levels(V5) <- c(0, 1, 2)
V9 <- factor(Drzewo$V9)
levels(V9) <- c(0, 1)

sample <- sample.int(nrow(Drzewo), floor(0.75*nrow(Drzewo)), replace=FALSE)
                     
Drzewo.train <- Drzewo[sample,]
Drzewo.test <- Drzewo[-sample,]

Drzewo.train.smote <- SMOTE(V14~ ., data = Drzewo.train, perc.over = 200, per.under = 150, k = 5)

summary(Drzewo.train.smote$V14)
## Healthy    Sick 
##     364     273
model1 <- rpart(V14 ~ V1+V2+V3+V4+V5+V6+V7+V8+
              V9+V10+V11+V12+V13, data =Drzewo.train.smote)

rpart.plot(model1, extra = 106, box.palette = "Oranges", border="black")

Drzewo.test.smote <- SMOTE(V14~ ., data = Drzewo.test, perc.over = 200, per.under = 150, k = 5)

summary(Drzewo.test.smote$V14)
## Healthy    Sick 
##     116      87
model2 <- rpart(V14 ~ V1+V2+V3+V4+V5+V6+V7+V8+
              V9+V10+V11+V12+V13, data =Drzewo.test.smote)

rpart.plot(model2, extra = 106, box.palette = "Blues" , border="black")

predict.model1 <- predict(model1, newdata= Drzewo.train.smote, type="vector")
roc.model1 <- roc(Drzewo.train.smote$V14, predict.model1)
## Setting levels: control = Healthy, case = Sick
## Setting direction: controls < cases
predict.model2 <- predict(model2, newdata= Drzewo.test.smote, type="vector")
roc.model2 <- roc(Drzewo.test.smote$V14, predict.model2)
## Setting levels: control = Healthy, case = Sick
## Setting direction: controls < cases
plot(roc.model1,col='orange')
lines(roc.model2, col='blue')

Podsumowanie

Podsumowując wszystkie analizy, należy przytoczyć najważniejsze informacje i wnioski:

Krzywa ROC wykazała, że lepsze drzewo decyzyjne wystąpiło na zbiorze treningowym.