Жишээ болгон дуу хоолойгоор хүйс таних гэсэн бодлого авч үзье. Энэ нь ангиллын асуудал тул ложистик регресс (logistic regression), шийдвэрийн мод (decision tree), санамсаргүй ой (random forest) зэрэг арга ашиглаж үүнийг шийдэх боломжтой.

Өгөгдөл

Ашиглах өгөгдлөө www.kaggle.com/primaryobjects/voicegender веб хуудаснаас татан авсан. Тус хуудсыг нээж өгөгдлийн талаарх дэлгэрэнгүй мэдээлэлтэй танилцах улмаар татан авах боломжтой. Татан авахдаа бүртгүүлсэн байхыг анхаарна уу. Татан авсан өгөгдлөө дараах байдлаар R програмд ачаалж оруулах боломжтой.

VG <- read.csv(file = "~/Downloads/voicegender.csv")

Энд файлыг хэрэглэгчийн хавтасны Downloads дэд хавтас дотор "voicegender.csv" хадгалсан гэж үзэв. Ихэнх веб хөтчийг интернэтээс татах файлыг тус хавтас дотор хадгалахаар тохируулсан байдаг билээ. Харин файлын нэрний хувьд северээс ирж буй нэрийг нь хэвээр нь үлдээсэн. Уг файл дотор хүний дуу хоолойн хэмжилтийн янз бүрийн статистикуудыг хүйсээр ялгаж хадгалсан байна.

Ашиглах багц суулгах

Шийдвэр мод алгоритмыг ажиллуулахад ашиглах боломжтой олон багц буюу package R програмд бий. Тэдгээрийн нэг болох tree багцыг ашиглая. Тус багцыг R програмд дараах байдлаар суулгана.

install.packages("tree")

Шийдвэрийн мод ургуулах буюу алгоритмыг ажиллуулах

tree багцын хувьд шийдвэрийн мод алгоритмыг ажиллуулах буюу шийдвэрийн мод ургуулахад tree() функцийг нь ашиглана.

VG.tree <- tree::tree(formula = label ~ ., data = VG)

Манай өгөгдөл дотор хүйс хувьсагчийг label гэж нэрлэсэн байсан. Бидний зорилго хүйсийг бусад хувьсагчдаар илэрхийлэх явдал тул загварын томьёоллыг label ~ . байдлаар өгөв. Энд . нь бусад хувьсагч гэсэн утга агуулгатай. Харин data аргументаар өгөгдлөө дамжуулна.

Шийдвэрийн модны тойм үзүүлэлтүүдийг харах болон модыг зурж дүрслэх

summary(VG.tree)
plot(VG.tree); text(VG.tree)
print(VG.tree)

Эндээс гарсан үр дүнг дор харуулав.

Classification tree:
tree::tree(formula = label ~ ., data = VG)
Variables actually used in tree construction:
[1] "meanfun" "IQR"    
Number of terminal nodes:  7 
Residual mean deviance:  0.1925 = 608.6 / 3161 
Misclassification error rate: 0.03472 = 110 / 3168

Дээрх үр дүнг харвал алдааны хэмээ багатай сайн мод ургасан мэт харагдах боловч тийм биш юм. Учир нь шийдвэрийг модыг ургуулахад "meanfun" болон "IQR" гэсэн хоёрхон хувьсагч ашигласан мөртөө салаа мөчрийнх нь төгсгөлийг тоолоод үзэхэд 7 ширхэг байгаа явдалд оршино.

Энгийнээр хэлбэл үр ашиггүй салаа мөчир их ургажээ. Үүнийг ерөнхийд нь машин сургалтын алгоритмыг хэт сургах (overfitting) гэж ярьдаг.

Шийдвэрийн модыг зохистой хэмжээнд ургуулах буюу алгоритмыг хэт сургахаас сэргийлэх

Үүний тулд өгөгдлөө сургалтын ба тестийн гэж хоёр хуваагаад сургалтын өгөгдөл дээрээ алгоритмаа сургаснаа тестийн өгөгдөл дээрээ шалгадаг. Мөн хэт сургалтаас сэргийлэхэд ашигладаг тодорхой аргачлалууд байдаг. Үүнээс cross validation аргачлалыг ашиглая.

Эхлээд өгөгдлөө хувааж, алгоритмаа сургах улмаар алгоритмаар гарган авсан загвараа тестийн өгөгдөл дээр ажиллуулж алдааг нь олж үзүүлье.

# өгөгдөл бэлдэх
set.seed(0)
training <- sample.int(n = nrow(VG), size = round(nrow(VG) * 0.8))
# алгоритмаа сургах
VG.tree <- tree::tree(formula = label ~ ., data = VG, subset = training)
# алгоритмаар гарган авсан загвар
summary(VG.tree)
plot(VG.tree); text(VG.tree)
print(VG.tree)
# загвараа тестийн өгөгдөл дээр ажилуулах
VG.pred <- predict(VG.tree, VG[-training,], type = "class")
# загварын алдаа
crosstab <- with(VG[-training,], table(VG.pred, label))
print(crosstab)
{sum(crosstab) - sum(diag(crosstab))} / sum(crosstab)

Гарган авсан загвар маань дээр олдсонтой төстэй үр ашиг муутай болсон. Тиймээс модны зургийг оруулсангүй. Харин ганц ялгаа нь "meanfun", "IQR", "minfun", "Q25", "maxdom" таван хувьсагч ашигласан явдал байлаа. Эцэст нь загварын алдаатай холбогдох үр дүнг харуулъя.

        label
VG.pred  female male
  female    326   18
  male        4  286

Үүнийг харсан хэн ч алдаа багатай сайн загвар гарсан гэх биз ээ. Үнэхээр алдааны хэмжээ 0.0347 буюу маш бага байна. Гэлээ ч шийдвэрийн модны алгоритм нь хэтрүүлж сургасан загвар гаргах боломжтой тул cross validation аргачлал ашиглая. Үүний тулд дараах хэлбэртэй код бичиж ажиллуулна.

VG.tree.cv <- tree::cv.tree(object = VG.tree, FUN = prune.misclass)
plot(VG.tree.cv)

Дээрх үр дүнгээс шийдвэрийн модны салаа мөчрийн төгсгөлийн нийт тоо ширхэг 3-тай тэнцүү байхад хангалттай гэсэн дүгнэлт гаргаж болно. Ингээд шийдвэрийн модныхоо хэрэгцээгүй салаа мөчрүүдийг тайрч хаяхын тулд дараах тушаал өгнө. Мөн шийдвэрийн модыг хэрэгцээгүй салаа мөчрөөс нь цэвэрлэсний дараа зурж харуулах тушаал нэмж бичлээ.

VG.tree.prune <- tree::prune.tree(tree = VG.tree, best = 3)
plot(VG.tree.prune); text(VG.tree.prune)

Шийдвэр мод өмнөхөөсөө илүү энгийн, ойлгомжтой болсоныг дараах зургаас харна уу.

Ингээд тайрч цэвэрлэсэн буюу зохистой байдлаар ургуулсан шийдвэрийн модоо тестийн өгөгдөл дээр ашиглаад улмаар алдааг нь тооцож үзье.

VG.pred.prune <- predict(VG.tree.prune, VG[-training,], type = "class")
crosstab.prune <- with(VG[-training,], table(VG.pred.prune, label))
print(crosstab.prune)
{sum(crosstab) - sum(diag(crosstab))} / sum(crosstab)

Эндээс гарсан үр дүнг дор харуулъя.

             label
VG.pred.prune female male
       female    321   18
       male        9  286

Алдааны хэмжээ 0.0347 гэж гарсан нь cross validation хийхээс өмнөхтэй адил байна. Гэсэн хэдий боловч cross validation хийснээр манай шийдвэрийн мод илүү энгийн, ойлгомжтой болсон. Ийнхүү хүний дуу хоолойгоор хүйс ялгаж танихад ашиглаж болох энгийн боловч үр ашигтай шийдвэрийн мод гарган авч чадлаа.