- Stefanescu Mihai a postat in Paginare in PHP
- johhny a postat in Paginare in PHP
- Stefanescu Mihai a postat in Cum pot afisa eroarea cand utilizatorul a scris un username gresit sau o parola gresita?
- madalin a postat in Cum pot afisa eroarea cand utilizatorul a scris un username gresit sau o parola gresita?
- Stefanescu Mihai a postat in Featureuri site
Cum am facut un sistem de detectat spam-ul folosind libraria PHP-ML
La scurt timp dupa ce am facut site-ul asta mi-am dat seama ca am o problema, ca apar multe comentarii SPAM, atat de multe incat este destul de greu sa le administrezi manual.
Usor usor am inceput sa fac diversi pasi pentru a scapa de tot acest spam, am pus honeybot pe formular, am creat semnaturi (fingerprints) pentru userii care posteaza frecvent comentarii si asa mai departe, desi acesti pasi au scazut numarul de comentarii spam, tot nu m-a scapat de management-ul manual.
Apoi am descoperit libraria php-ml si mi-am dat seama ca as putea folosi aceasta librarie pentru a imi creea un model care sa imi spuna daca un comentariu este spam sau nu si sa il aprobe sau sa il marcheze ca spam pentru mine.
Am bagat rapid libraria in proiect-ul mei scris in laravel:
composer require php-ai/php-ml
Am generat o comanda noua cu
php artisan make:command ClassifySpamCommentCommand
Deja aveam o baza de cateva sute de comentarii, atat spam cat si comentarii bune, le-am luat la mana sa ma asigur ca sunt marcate ca si spam in mod corect.
Apoi am inceput sa scriu codul pentru a antrena modelul pe comentariile mele si am ajuns sa am aceste 2 functii:
private function trainModel(): { // imi definesc calea unui model, pentru ca nu vreau sa antrenez modelul in fiecare zi $phpMLmodelPath = storage_path('/predictions/spam_comments_model.phpml'); $modelManager = new ModelManager(); if (file_exists($modelPath)) { // daca am deja un model existent am sa il incarca pe ala $classifier = $modelManager->restoreFromFile($modelPath); } else { // nu am un model deja antrenat, asa ca il antrenez si il salvez intr-un fisier $classifier = $this->train(); $modelManager->saveToFile($classifier, $modelPath); } return $classifier; } private function train(): { // pentru ca rulez aceasta comanda o data pe zi am sa iau doar comentariile din mai vechi de 24h $twentyFourHoursAgo = Carbon::now()->subHours(24); $comments = Comment::where('created_at', '<', $twentyFourHoursAgo)->get(); $samples = []; $labels = []; foreach ($comments as $comment) { // imi pregatesc datele de test $sample = [$comment->name, $comment->email, $comment->website, $comment->content]; $samples[] = $sample; $labels[] = $comment->status == 0 ? 'spam' : 'not_spam'; } $vectorizer = new TokenCountVectorizer(new WhitespaceTokenizer()); $dataset = new ArrayDataset($samples, $labels); $classifier = new SVC(); // iar in cele din urma pregatesc modelul cu datele pe care le am $classifier->train($dataset->getSamples(), $dataset->getTargets()); return $classifier; }
In momentul asta am un model deja antrenat, pot incepe sa scriu functia handle care imi va marca comentariile noi din comanda mea:
public function handle(): { // imi iau modelul, fie el pregatit acum fie din fisier $classifier = $this->trainModel(); // iau comenatriile din ultimele 24h $twentyFourHoursAgo = Carbon::now()->subHours(24); $comments = Comment::where('created_at', '>', $twentyFourHoursAgo)->get(); foreach ($comments as $comment) { // imi pregatesc datele de test $testData = [$comment->name, $comment->email, $comment->website, $comment->content]; // cer o predictie pentru datele pregatite $predictedLabel = $classifier->predict([$testData]); $comment->status = Comment::STATUS_NOT_SPAM; if ($predictedLabel === 'spam') { $comment->status = Comment::STATUS_SPAM; } $comment->save(); } }
Gata, asta este tot, acum avem un model antrenat in PHP ce poate detecta spam-ul, dar la fel de simplu acest tip de model poate fi antrenat si pentru cazul tau specific, trebuie doar sa ii schimbi datele de antrenare si test.
Comentarii
Inca nu au fost postate comentarii, fii primul care posteaza un comentariu!