អ៊ីមែលគឺជាឧបករណ៍ដ៏សំខាន់សម្រាប់ការទំនាក់ទំនងនៅក្នុងពិភពលោកបច្ចុប្បន្ន។ ទោះយ៉ាងណាក៏ដោយ អ៊ីមែល spam បានលេចចេញជាបញ្ហាប្រឈមដ៏សំខាន់មួយ។ សារដែលមិនមានការស្នើសុំទាំងនេះពីប្រភពមិនស្គាល់ច្រើនតែបំពេញប្រអប់ទទួល ដែលរំខានដល់ការទំនាក់ទំនង និងផលិតភាព។ ឯកសារនេះស៊ើបអង្កេតការប្រើប្រាស់បច្ចេកទេសរៀនម៉ាស៊ីនផ្សេងៗដើម្បីចាត់ថ្នាក់អ៊ីមែលជា "សារឥតបានការ" ឬ "ហាំ" (មិនមែនសារឥតបានការ)។
គំរូចំណាត់ថ្នាក់ដូចជា K-Nearest Neighbors (KNN), Logistic Regression, Support Vector Machines (SVM) និង Naïve Bayes ត្រូវបានវាយតម្លៃដោយប្រៀបធៀបប្រសិទ្ធភាពរបស់ពួកគេក្នុងការចាត់ថ្នាក់អ៊ីមែល។ ដំណើរការនៃម៉ូដែលនីមួយៗត្រូវបានវាយតម្លៃដោយផ្អែកលើរង្វាស់ដូចជាភាពត្រឹមត្រូវ ភាពជាក់លាក់ ការរំលឹកឡើងវិញ និងពិន្ទុ F1 ដើម្បីកំណត់វិធីសាស្រ្តណាមួយដែលសមស្របបំផុតសម្រាប់កិច្ចការនេះ។
នៅឆ្នាំ 2023 មានអ៊ីម៉ែលចំនួន 347.3 ពាន់លានដែលត្រូវបានផ្ញើជារៀងរាល់ថ្ងៃ ដែលក្នុងនោះ អ៊ីម៉ែល spam បង្កើតបាន 45% នៃចរាចរអ៊ីម៉ែលទាំងអស់។ សារឥតបានការអ៊ីម៉ែលទាំងនេះធ្វើឱ្យអាជីវកម្មចំណាយអស់ 20.5 ពាន់លានដុល្លារជារៀងរាល់ឆ្នាំ។ អាស្រ័យហេតុនេះ វានឹងតែងតែមានតម្រូវការដើម្បីធានាថាសារឥតបានការត្រូវបានចាត់ថ្នាក់យ៉ាងត្រឹមត្រូវ និងមិនជ្រៀតជ្រែកជាមួយចរាចរណ៍អ៊ីមែលស្របច្បាប់។ នេះគឺជាវិធីដ៏មានប្រយោជន៍មួយដើម្បីយល់ពីសក្តានុពល និងការអនុវត្តនៃការរៀនម៉ាស៊ីន។
ក្នុងករណីនៃការរកឃើញសារឥតបានការ អ្នកប្រើប្រាស់ដែលស្គាល់អ៊ីមែលអាចកំណត់បានយ៉ាងងាយស្រួលនូវសារឥតបានការស្ទើរតែភ្លាមៗនៅពេលមើលវា។ ជាលទ្ធផល ខ្ញុំជឿថា ការងារនេះបញ្ជាក់ថា ការកំណត់អត្តសញ្ញាណសារឥតបានការ គឺជាកម្មវិធីដ៏មានសារៈប្រយោជន៍សម្រាប់អ្នកចាត់ថ្នាក់រៀនម៉ាស៊ីន។ ដើម្បីចាត់ថ្នាក់អ៊ីមែលជាសារឥតបានការ ឬ ham មានជំហានដំណើរការមុនជាច្រើនដែលពាក់ព័ន្ធ - រៀបចំទិន្នន័យដើម្បីអាចទទួលយកបានចំពោះអ្នកចាត់ថ្នាក់លីនេអ៊ែរ បន្ទាប់មកកំណត់សញ្ញាសម្ងាត់ និងកំណត់បន្ទាត់នីមួយៗដើម្បីបំប្លែងទៅជាតារាង TF-IDF (Term Frequency – Inverse Document Frequency)។
KNN ជាមួយ K=3 ត្រូវបានជ្រើសរើសជាគំរូមូលដ្ឋាន។ ការតំរែតំរង់ផ្នែកឡូជីស្ទិកជាមួយនឹងការធ្វើឱ្យទៀងទាត់ L1 ម៉ូដែល Naïve Bayes និងម៉ូដែល SVM ក៏ត្រូវបានសាកល្បងផងដែរមុនពេលសម្រេចចិត្តម៉ូដែលល្អបំផុត។ សម្រាប់គោលបំណងនៃគម្រោងនេះ សំណុំទិន្នន័យពី Kaggle ត្រូវបានប្រើប្រាស់ ដែលមានឯកសារអ៊ីមែល "ham" ចំនួន 2551 និងឯកសារអ៊ីម៉ែលសារឥតបានការចំនួន 501 ហើយការធ្វើគំរូត្រូវបានធ្វើឡើងដោយប្រើភាសាសរសេរកម្មវិធី R ។
គំនូសតាងខាងក្រោមនឹងជួយឱ្យយល់អំពីលំហូរនៃជំហានផ្សេងៗដែលបានធ្វើតាម -
ជំហានដំណើរការមុន។
ដោយសារទិន្នន័យអត្ថបទជាច្រើនកំពុងត្រូវបានប្រើប្រាស់ ចាំបាច់ត្រូវដំណើរការទិន្នន័យជាមុន ដើម្បីសម្អាតវា ហើយយកវាទៅជាទម្រង់ដែលអាចប្រើបានដោយគំរូចំណាត់ថ្នាក់។ ខាងក្រោមនេះនឹងពន្យល់ពីដំណើរការមួយជំហានម្តង ៗ ដែលត្រូវបានអនុវត្តជាផ្នែកនៃដំណើរការទិន្នន័យជាមុន -
ទិន្នន័យអត្ថបទត្រូវតែអាចទទួលយកបានចំពោះអ្នកចាត់ថ្នាក់លីនេអ៊ែរ។ នេះមានន័យថាសំណុំទិន្នន័យត្រូវតែត្រូវបានបំប្លែងដោយប្រើវិធីសាស្ត្រទាញយកមុខងារអត្ថបទទៅជាលក្ខណៈលេខ។
ជាដំបូង បន្ទាត់នីមួយៗនៃអត្ថបទត្រូវបានសម្គាល់ និងកំណត់ទៅជាទម្រង់ខាងក្រោម។ ដំណើរការ stemming ធ្វើឱ្យខ្លីពាក្យដោយយកចុងបញ្ចប់ដែលមិនប៉ះពាល់។ ឧទាហរណ៍ កម្មករក្លាយជាកម្មករក្នុងឧទាហរណ៍ខាងក្រោម។
បន្ទាប់មក ទិន្នន័យដែលបានកំណត់អត្តសញ្ញាណត្រូវបានបំប្លែងទៅជាតារាង TF-IDF (ប្រេកង់ពាក្យ - ប្រេកង់ឯកសារបញ្ច្រាស)។ TF-IDF គឺជាវិធីសាស្រ្តមួយសម្រាប់ការវិភាគអត្ថបទដែលចែងអំពី n-gram នីមួយៗនៅក្នុងឯកសារមួយទាក់ទងនឹងប្រេកង់ឯកសារ-inverse frequency របស់វា។ ប្រេកង់ពាក្យគឺគ្រាន់តែជាប្រេកង់នៃពាក្យដែលបានផ្តល់ឱ្យនៅក្នុងឯកសារ (ក្នុងករណីនេះ អ៊ីមែល) ។ ប្រេកង់ឯកសារបញ្ច្រាសត្រូវបានបញ្ជាក់ជាទូទៅដូចជា៖
កំណត់ហេតុ ((ចំនួនសរុបនៃឯកសារ/ចំនួនឯកសារដែលមានរយៈពេល)
វាបម្រើដើម្បីថ្លឹងថ្លែងពាក្យសំខាន់ៗច្រើនជាងពាក្យញឹកញាប់ ហើយដូច្នេះលក្ខខណ្ឌមិនសូវសំខាន់។
នេះផ្តល់លទ្ធផលសរុបចំនួន 1,130 ពាក្យនៅក្នុងសំណុំទិន្នន័យបណ្តុះបណ្តាល។
វាជាការសំខាន់ក្នុងការកត់សម្គាល់ថាយុទ្ធសាស្រ្តសម្រាប់ការប្រើប្រាស់ TF-IDF ជាមួយនឹងសំណុំសាកល្បងនឹងអនុវត្តតែការបណ្តុះបណ្តាលគំរូនៅលើការបណ្តុះបណ្តាល TF-IDF ហើយបន្ទាប់មកដើម្បីគណនាឡើងវិញនូវ TF-IDF ជាមួយនឹងទិន្នន័យពេញលេញសម្រាប់ភាពត្រឹមត្រូវនៃការធ្វើតេស្ត។ វាត្រូវបានទាមទារ ពីព្រោះ TF-IDF ពឹងផ្អែកលើប្រេកង់នៅក្នុងសំណុំទិន្នន័យ ទាំងមូល នៃពាក្យជាក់លាក់មួយ ហើយក៏មិនរួមបញ្ចូលទិន្នន័យសាកល្បងក្នុងអំឡុងពេលបណ្តុះបណ្តាលផងដែរ។
ជាចុងក្រោយ មានតែលក្ខខណ្ឌកំពូល 1000 ដោយប្រេកង់ពាក្យទាំងមូលប៉ុណ្ណោះដែលត្រូវបានជ្រើសរើសនៅក្នុងសំណុំបណ្តុះបណ្តាល។
កូដសម្រាប់ជំហានដំណើរការមុន -
#tokenize word_tokens <- complete_tbl %>% unnest_tokens(word,content) #stemming word_tokens<-word_tokens %>% mutate(word_stem=SnowballC::wordStem(word)) #remove any words with numbers word_tokens <- word_tokens[-grep('^\\d+$', word_tokens$word_stem),] #remove any words with . word_tokens <- word_tokens[-grep('[.]', word_tokens$word_stem),] #remove any single character words word_tokens <- word_tokens[-grep('.\\b[az]\\b.', word_tokens$word_stem),] #remove tokens which match stop words word_tokens <- word_tokens %>% filter(!word %in% stopWords) word_tokens <- word_tokens %>% filter(!word_stem %in% stopWords) #split into training and test word_tokens_train <- word_tokens %>% filter(document %in% ind) #create tfidf for training and then a complete tfidf for testing tfidf_train<-word_tokens_train %>% count(document,word_stem,sort=TRUE) %>% bind_tf_idf(word_stem,document,n) tfidf_complete<-word_tokens %>% count(document,word_stem,sort=TRUE) %>% bind_tf_idf(word_stem,document,n)
ម៉ូដែលដែលបានប្រើ
ម៉ូដែលនេះសម្រេចបាននូវភាពជាក់លាក់ដែលសមហេតុផល ប៉ុន្តែមានភាពរសើបខ្លាំង ដែលមានន័យថា hams ជាច្រើនត្រូវបានព្យាករណ៍ថាជាសារឥតបានការ។ ចំណាំថានៅក្នុងលទ្ធផលនីមួយៗខាងក្រោម ថ្នាក់វិជ្ជមានគឺ "ham" ។ នេះគឺជាលទ្ធផលដ៏អាក្រក់បំផុតសម្រាប់អ្នកប្រើដែលពួកគេនឹងខកខានអ៊ីមែលពិតជាច្រើនដែលត្រូវបានចាត់ថ្នាក់ជាសារឥតបានការ។
លេខកូដសម្រាប់ម៉ូដែល KNN -
##train a model library(e1071) library(caret) library(class) library(LiblineaR) ##remove document number since this is indicative of spam or ham wide_feat_train<-subset(wide_feat_train, select=-c(document)) wide_feat_test<-subset(wide_feat_test,select=-c(document)) #Base model is a knn attempt knn_pred<-knn(train=wide_feat_train,test=wide_feat_test,cl=labels_train$label,k=3) knn_results<-confusionMatrix(knn_pred,labels_test$label) knn_results knn_results$byClass["F1"] knn_results$byClass["Precision"] knn_results$byClass["Recall"]
បន្ទាប់ពីទទួលបានលទ្ធផលមិនល្អពីគំរូ KNN Logistic Regression គឺជាគំរូបន្ទាប់ដែលត្រូវបានប្រើប្រាស់។
សម្រាប់គោលបំណងនៃសេណារីយ៉ូនេះ,
ការតំរែតំរង់ផ្នែកឡូជីស្ទិកត្រូវបានអនុវត្តជាមួយប៉ារ៉ាម៉ែត្រខ្ពស់ខាងក្រោម -
គំរូនេះផ្តល់នូវលទ្ធផលដូចខាងក្រោមនៅលើសំណុំទិន្នន័យសាកល្បង ដែលជាការកែលម្អយ៉ាងសំខាន់លើគំរូ KNN រួចហើយ។ ភាពត្រឹមត្រូវសរុបគឺខ្ពស់ណាស់ ប៉ុន្តែភាពជាក់លាក់បង្ហាញថា វានៅតែមានកន្លែងខ្លះសម្រាប់កែលម្អ។ អ្នកប្រើប្រាស់នៃគំរូនេះនឹងរកឃើញ Hams មួយចំនួនដែលត្រូវបានព្យាករណ៍ថាជា Spams ។
កូដសម្រាប់គំរូតំរែតំរង់ផ្នែកដឹកជញ្ជូន -
#Next is a logistic regression usin the below hyperparameters grid_logit <- expand.grid(loss="L1",cost=2,epsilon=0.1) lr <- train(x=wide_feat_train,y=labels_train$label,method="regLogistic",tuneGrid=grid_logit) lr_results<-confusionMatrix(as.factor(predict(lr,wide_feat_test)),labels_test$label) lr_results p_lr = predict(lr,wide_feat_test) prednum_lr<-ifelse(p_lr=="spam",0,1) roc_lr<-roc(labels_test$label,prednum_lr) plot(roc_lr) roc_lr$auc p1_lr<- prediction(as.numeric(p_lr),as.numeric(labels_test$label)) pr_lr <- performance(p1_lr, "prec", "rec") plot(pr_lr) lr_results$byClass["F1"] lr_results$byClass["Precision"] lr_results$byClass["Recall"]
ម៉ូដែលបន្ទាប់ដែលបានសាកល្បងគឺម៉ូដែល Naïve Bayes ។ សម្រាប់គំរូនេះ ការផ្ទៀងផ្ទាត់ឆ្លងកាត់ត្រូវបានធ្វើឡើងដើម្បីស្វែងរកប៉ារ៉ាម៉ែត្រខ្ពស់ដែលល្អបំផុតជាមួយនឹងវិធីសាស្រ្តប្រាំដង។ លទ្ធផលនេះនៅក្នុងប៉ារ៉ាម៉ែត្រខាងក្រោមសម្រាប់ Naive-Bayes -
ម៉ូដែលនេះក៏សម្រេចបានលទ្ធផលល្អទាំងភាពជាក់លាក់ និងភាពប្រែប្រួលផងដែរ។
លេខកូដសម្រាប់ម៉ូដែល Naive Bayes -
##naive bayes main model nb_cv <- train( x=wide_feat_train, y=labels_train$label, method = "naive_bayes", trControl = train_control, tuneGrid = grid ) nb <- naiveBayes(wide_feat_train,labels_train$label,adjust=1,laplace=0,usekernel=FALSE) nb_results<-confusionMatrix(as.factor(predict(nb,wide_feat_test)),labels_test$label) nb_results p = predict(nb,wide_feat_test) prednum<-ifelse(p=="spam",0,1) roc_nb<-roc(labels_test$label,prednum) plot(roc_nb) roc_nb$auc p1<- prediction(as.numeric(p),as.numeric(labels_test$label)) pr <- performance(p1, "prec", "rec") plot(pr) nb_results$byClass["F1"] nb_results$byClass["Precision"] nb_results$byClass["Recall"]
4. គាំទ្រម៉ាស៊ីនវ៉ិចទ័រ (SVM)
គំរូចុងក្រោយគឺ SVM ឆ្លងកាត់សុពលភាពជាមួយខឺណែលលីនេអ៊ែរ។ គាំទ្រម៉ាស៊ីនវ៉ិចទ័រ ព្យាយាមស្វែងរកយន្តហោះខ្ពស់ដែលបំបែកជាអតិបរមា ដើម្បីបំបែកទិន្នន័យរវាងថ្នាក់ពីរ។
នៅទីនេះ CV 5 ដងត្រូវបានអនុវត្តដោយប្រើ R Library caret ដើម្បីកំណត់អត្តសញ្ញាណ hyperparameters ល្អបំផុត។ ប៉ារ៉ាម៉ែត្រខ្ពស់ទាំងនេះត្រូវបានបង្ហាញខាងក្រោម -
លទ្ធផលនៃគំរូនេះនៅពេលអនុវត្តទៅសំណុំទិន្នន័យសាកល្បងដែលទុកចោលត្រូវបានបង្ហាញខាងក្រោម -
កូដសម្រាប់ SVM -
#svm train_control <- trainControl( method = "cv", number = 5 ) svm <- train(x=wide_feat_train,y=labels_train$label,method="svmLinearWeights2",trControl=train_control) svm$bestTune svm_results<-confusionMatrix(as.factor(predict(svm,wide_feat_test)),labels_test$label) svm_results p_svm = predict(svm,wide_feat_test) prednum_svm<-ifelse(p_svm=="spam",0,1) roc_svm<-roc(labels_test$label,prednum_svm) plot(roc_svm,colorize=T,lwd=3, main=" ROC curve for SVM model") roc_svm$auc p1_svm<- prediction(as.numeric(p_svm),as.numeric(labels_test$label)) pr <- performance(p1_svm, "prec", "rec") plot(pr) svm_results$byClass["F1"] svm_results$byClass["Precision"] svm_results$byClass["Recall"]
តារាងខាងក្រោមសង្ខេបអំពីវិធានការដែលត្រូវបានពិចារណាសម្រាប់ការជ្រើសរើសគំរូល្អបំផុត-
គំរូ | ភាពត្រឹមត្រូវ | ពិន្ទុ F1 | ភាពជាក់លាក់ | រំលឹកឡើងវិញ |
---|---|---|---|---|
ខេ.អិន | ០.២៥២ | ០.២២៩៣ | ០.៨៩៤៧ | 0.1315 |
តំរែតំរង់ផ្នែកដឹកជញ្ជូន | ០.៩៦២៤ | ០.៩៧៨១ | ០.៩៥៩១ | ០.៩៩៨ |
Naive Bayes | ០.៩៧២២ | ០.៩៨៣៤ | ០.៩៨៨២ | ០.៩៧៨៧ |
SVM | ០.៩៨៨៥ | 0.9932 | ០.៩៨៨៦ | ១ |
ពីតារាងខាងលើវាអាចត្រូវបានគេមើលឃើញថា SVM ដំណើរការបានល្អបំផុតបើប្រៀបធៀបទៅនឹងម៉ូដែលផ្សេងទៀត។
ដើម្បីបញ្ជាក់បន្ថែម ខ្សែកោង ROC ត្រូវបានគ្រោងទុក ហើយតម្លៃ AUC ត្រូវបានគណនា។
គំរូ | ខេ.អិន | តំរែតំរង់ផ្នែកដឹកជញ្ជូន | Naïve Bayes | SVM |
---|---|---|---|---|
AUC | .៥២៣២ | .៨៨២ | .៩៥៧៤ | .៩៦២៨ |
រូប៖ តម្លៃ AUC សម្រាប់ម៉ូដែលទាំង ៤
ពីការវាស់វែងខាងលើ វាអាចត្រូវបានសន្និដ្ឋានថា SVM ដែលមានសុពលភាពឆ្លង 5 ដងដំណើរការល្អបំផុតលើសំណុំទិន្នន័យក្នុងការចាត់ថ្នាក់អ៊ីមែលជា Ham និង spam ។
ការត្រងសារឥតបានការនឹងតែងតែជាវាលមួយដែលមានការវិវត្តជាបន្តបន្ទាប់ ខណៈដែលអ្នកផ្ញើសារឥតបានការកំពុងស្វែងរកវិធីសាស្រ្តថ្មីៗ និងប្រកបដោយភាពច្នៃប្រឌិតជានិច្ចដើម្បីផ្ញើសារឥតបានការ។ គ្មានដំណោះស្រាយប្រឆាំងសារឥតបានការតែមួយអាចត្រឹមត្រូវទេ។ នៅក្នុងគម្រោងនេះ ឧបករណ៍រៀនម៉ាស៊ីនមួយចំនួនត្រូវបានប្រើប្រាស់ដើម្បីមើលពីរបៀបដែលពួកគេធ្វើជាអ្នកចាត់ថ្នាក់សម្រាប់អ៊ីមែល Ham និង Spam ។ ការពិពណ៌នាអំពីការគណនាត្រូវបានបង្ហាញ ក៏ដូចជាការប្រៀបធៀបនៃការអនុវត្តរបស់ពួកគេ។
ក្នុងចំណោមម៉ូដែលរៀនម៉ាស៊ីនទាំងបួនដែលត្រូវបានសាកល្បង SVM ត្រូវបានរកឃើញថាល្អបំផុតទាក់ទងនឹងដំណើរការ។ ម៉ូដែល Logistic Regression និង Naïve Bayes ក៏បង្ហាញលទ្ធផលល្អផងដែរ។