SNA Hackathon 2019

Τον Φεβρουάριο-Μάρτιο 2019 πραγματοποιήθηκε διαγωνισμός για την κατάταξη της ροής του κοινωνικού δικτύου SNA Hackathon 2019, στην οποία η ομάδα μας κατέλαβε την πρώτη θέση. Στο άρθρο θα μιλήσω για την οργάνωση του διαγωνισμού, τις μεθόδους που δοκιμάσαμε και τις ρυθμίσεις catboost για προπόνηση σε μεγάλα δεδομένα.

SNA Hackathon 2019

SNA Hackathon

Είναι η τρίτη φορά που διοργανώνεται hackathon με αυτό το όνομα. Οργανώνεται από το κοινωνικό δίκτυο ok.ru, αντίστοιχα, η εργασία και τα δεδομένα σχετίζονται άμεσα με αυτό το κοινωνικό δίκτυο.
Το SNA (ανάλυση κοινωνικών δικτύων) σε αυτή την περίπτωση κατανοείται πιο σωστά όχι ως ανάλυση ενός κοινωνικού γραφήματος, αλλά μάλλον ως ανάλυση ενός κοινωνικού δικτύου.

  • Το 2014, το καθήκον ήταν να προβλέψουμε τον αριθμό των likes που θα λάμβανε μια ανάρτηση.
  • Το 2016 - η εργασία VVZ (ίσως είστε εξοικειωμένοι), πιο κοντά στην ανάλυση του κοινωνικού γραφήματος.
  • Το 2019, η κατάταξη της ροής του χρήστη με βάση την πιθανότητα να αρέσει στον χρήστη η ανάρτηση.

Δεν μπορώ να πω για το 2014, αλλά το 2016 και το 2019, εκτός από τις ικανότητες ανάλυσης δεδομένων, απαιτήθηκαν και δεξιότητες εργασίας με μεγάλα δεδομένα. Νομίζω ότι ήταν ο συνδυασμός της μηχανικής μάθησης και των προβλημάτων επεξεργασίας μεγάλων δεδομένων που με προσέλκυσε σε αυτούς τους διαγωνισμούς και η εμπειρία μου σε αυτούς τους τομείς με βοήθησε να κερδίσω.

mlbootcamp

Το 2019, ο διαγωνισμός διοργανώθηκε στην πλατφόρμα https://mlbootcamp.ru.

Ο διαγωνισμός ξεκίνησε διαδικτυακά στις 7 Φεβρουαρίου και αποτελούνταν από 3 εργασίες. Οποιοσδήποτε θα μπορούσε να εγγραφεί στον ιστότοπο, να πραγματοποιήσει λήψη αρχική και φορτώστε το αυτοκίνητό σας για μερικές ώρες. Στο τέλος της διαδικτυακής σκηνής στις 15 Μαρτίου, οι 15 κορυφαίοι κάθε εκδήλωσης άλματος επίδειξης προσκλήθηκαν στο γραφείο του Mail.ru για το στάδιο εκτός σύνδεσης, το οποίο έλαβε χώρα από τις 30 Μαρτίου έως την 1η Απριλίου.

Έργο

Τα δεδομένα προέλευσης παρέχουν αναγνωριστικά χρήστη (userId) και αναγνωριστικά ανάρτησης (objectId). Εάν εμφανίστηκε στον χρήστη μια ανάρτηση, τότε τα δεδομένα περιέχουν μια γραμμή που περιέχει userId, objectId, αντιδράσεις χρήστη σε αυτήν την ανάρτηση (feedback) και ένα σύνολο από διάφορες λειτουργίες ή συνδέσμους προς εικόνες και κείμενα.

ταυτότητα χρήστη αντικείμενο ID ID ιδιοκτήτη ανατροφοδότηση εικόνες
3555 22 5677 [μου άρεσε, έκανε κλικ] [hash1]
12842 55 32144 [Αντιπαθής] [hash2,hash3]
13145 35 5677 [κλικ, κοινοποιήθηκε] [hash2]

Το σύνολο δεδομένων δοκιμής περιέχει παρόμοια δομή, αλλά το πεδίο ανάδρασης λείπει. Το καθήκον είναι να προβλέψουμε την παρουσία της αντίδρασης «αρέσει» στο πεδίο ανατροφοδότησης.
Το αρχείο υποβολής έχει την εξής δομή:

ταυτότητα χρήστη SortedList[objectId]
123 78,13,54,22
128 35,61,55
131 35,68,129,11

Η μέτρηση είναι η μέση AUC ROC για τους χρήστες.

Μια πιο λεπτομερής περιγραφή των δεδομένων μπορείτε να βρείτε στη διεύθυνση ιστοσελίδα του συμβουλίου. Μπορείτε επίσης να κάνετε λήψη δεδομένων από εκεί, συμπεριλαμβανομένων δοκιμών και εικόνων.

Διαδικτυακό στάδιο

Στο διαδικτυακό στάδιο, η εργασία χωρίστηκε σε 3 μέρη

  • Συνεργατικό σύστημα — περιλαμβάνει όλα τα χαρακτηριστικά εκτός από εικόνες και κείμενα.
  • Изображения — περιλαμβάνει μόνο πληροφορίες για εικόνες.
  • Κείμενα — περιλαμβάνει πληροφορίες μόνο για κείμενα.

Στάδιο εκτός σύνδεσης

Στο στάδιο εκτός σύνδεσης, τα δεδομένα περιελάμβαναν όλα τα χαρακτηριστικά, ενώ τα κείμενα και οι εικόνες ήταν αραιά. Υπήρχαν 1,5 φορές περισσότερες σειρές στο σύνολο δεδομένων, από τις οποίες υπήρχαν ήδη πολλές.

Η λύση του προβλήματος

Δεδομένου ότι κάνω βιογραφικό στη δουλειά, ξεκίνησα το ταξίδι μου σε αυτόν τον διαγωνισμό με την εργασία «Εικόνες». Τα δεδομένα που δόθηκαν ήταν userId, objectId, ownerId (η ομάδα στην οποία δημοσιεύτηκε η ανάρτηση), χρονικές σημάνσεις για τη δημιουργία και την εμφάνιση της ανάρτησης και, φυσικά, η εικόνα για αυτήν την ανάρτηση.
Μετά τη δημιουργία πολλών χαρακτηριστικών που βασίζονται σε χρονικές σημάνσεις, η επόμενη ιδέα ήταν να πάρουμε το προτελευταίο στρώμα του νευρώνα προεκπαιδευμένο στο imagenet και να στείλουμε αυτές τις ενσωματώσεις για ενίσχυση.

SNA Hackathon 2019

Τα αποτελέσματα δεν ήταν εντυπωσιακά. Οι ενσωματώσεις από τον νευρώνα του imagenet είναι άσχετες, σκέφτηκα, πρέπει να φτιάξω τον δικό μου αυτόματο κωδικοποιητή.

SNA Hackathon 2019

Χρειάστηκε πολύς χρόνος και το αποτέλεσμα δεν βελτιώθηκε.

Δημιουργία χαρακτηριστικών

Η εργασία με εικόνες απαιτεί πολύ χρόνο, οπότε αποφάσισα να κάνω κάτι πιο απλό.
Όπως μπορείτε να δείτε αμέσως, υπάρχουν αρκετά κατηγορηματικά χαρακτηριστικά στο σύνολο δεδομένων και για να μην ενοχλώ πολύ, απλώς πήρα το catboost. Η λύση ήταν εξαιρετική, χωρίς καμία ρύθμιση έφτασα αμέσως στην πρώτη γραμμή του βαθμολογικού πίνακα.

Υπάρχουν αρκετά δεδομένα και είναι διατεταγμένα σε μορφή παρκέ, οπότε χωρίς να το σκεφτώ δύο φορές, πήρα τη σκάλα και άρχισα να γράφω τα πάντα με σπινθήρα.

Τα πιο απλά χαρακτηριστικά που έδωσαν μεγαλύτερη ανάπτυξη από τις ενσωματώσεις εικόνων:

  • πόσες φορές το objectId, το userId και το ownerId εμφανίστηκαν στα δεδομένα (θα πρέπει να συσχετίζονται με τη δημοτικότητα).
  • πόσες αναρτήσεις έχει δει το userId από το ownerId (θα πρέπει να συσχετίζονται με το ενδιαφέρον του χρήστη για την ομάδα).
  • πόσα μοναδικά userIds είδαν αναρτήσεις από το ownerId (αντανακλά το μέγεθος του κοινού της ομάδας).

Από τις χρονικές σημάνσεις ήταν δυνατό να ληφθεί η ώρα της ημέρας κατά την οποία ο χρήστης παρακολούθησε τη ροή (πρωί/απόγευμα/βράδυ/βράδυ). Συνδυάζοντας αυτές τις κατηγορίες, μπορείτε να συνεχίσετε να δημιουργείτε χαρακτηριστικά:

  • πόσες φορές το userId συνδέθηκε το βράδυ.
  • ποια ώρα εμφανίζεται πιο συχνά αυτή η ανάρτηση (objectId) και ούτω καθεξής.

Όλα αυτά βελτίωσαν σταδιακά τις μετρήσεις. Αλλά το μέγεθος του συνόλου δεδομένων εκπαίδευσης είναι περίπου 20 εκατομμύρια εγγραφές, επομένως η προσθήκη χαρακτηριστικών επιβράδυνε σημαντικά την εκπαίδευση.

Έχω ξανασκεφτεί την προσέγγισή μου στη χρήση δεδομένων. Αν και τα δεδομένα εξαρτώνται από το χρόνο, δεν είδα καμία προφανή διαρροή πληροφοριών "στο μέλλον", ωστόσο, για κάθε ενδεχόμενο, τα ανέλυσα ως εξής:

SNA Hackathon 2019

Το σετ εκπαίδευσης που μας παρασχέθηκε (Φεβρουάριος και 2 εβδομάδες Μαρτίου) χωρίστηκε σε 2 μέρη.
Το μοντέλο εκπαιδεύτηκε σε δεδομένα από τις τελευταίες Ν ημέρες. Οι συναθροίσεις που περιγράφονται παραπάνω βασίστηκαν σε όλα τα δεδομένα, συμπεριλαμβανομένης της δοκιμής. Ταυτόχρονα, εμφανίστηκαν δεδομένα στα οποία είναι δυνατή η δημιουργία διαφόρων κωδικοποιήσεων της μεταβλητής στόχου. Η απλούστερη προσέγγιση είναι να επαναχρησιμοποιήσετε κώδικα που ήδη δημιουργεί νέες δυνατότητες και απλώς να τροφοδοτήσετε δεδομένα στα οποία δεν θα εκπαιδευτεί και να στοχεύσετε = 1.

Έτσι, έχουμε παρόμοια χαρακτηριστικά:

  • Πόσες φορές έχει δει το userId μια ανάρτηση στο ownerId της ομάδας;
  • Πόσες φορές άρεσε στο userId η ανάρτηση στο group ownerId;
  • Το ποσοστό των αναρτήσεων που άρεσε στο userId από το ownerId.

Δηλαδή αποδείχθηκε μέση κωδικοποίηση στόχου σε μέρος του συνόλου δεδομένων για διάφορους συνδυασμούς κατηγορικών χαρακτηριστικών. Κατ' αρχήν, το catboost δημιουργεί επίσης κωδικοποίηση στόχου και από αυτή την άποψη δεν υπάρχει κανένα όφελος, αλλά, για παράδειγμα, κατέστη δυνατό να μετρηθεί ο αριθμός των μοναδικών χρηστών που τους άρεσαν οι αναρτήσεις σε αυτήν την ομάδα. Ταυτόχρονα, ο κύριος στόχος επιτεύχθηκε - το σύνολο δεδομένων μου μειώθηκε αρκετές φορές και ήταν δυνατή η συνέχιση της δημιουργίας χαρακτηριστικών.

Ενώ το catboost μπορεί να δημιουργήσει κωδικοποίηση μόνο με βάση την αντίδραση που σας αρέσει, η ανατροφοδότηση έχει άλλες αντιδράσεις: αναδημοσίευση, αντιπαθητικό, μη άρεσε, κλικ, παράβλεψη, κωδικοποιήσεις για τις οποίες μπορούν να γίνουν χειροκίνητα. Υπολογίστηκα εκ νέου όλα τα είδη συγκεντρωτικών στοιχείων και εξάλειψα χαρακτηριστικά χαμηλής σημασίας για να μην διογκωθεί το σύνολο δεδομένων.

Μέχρι εκείνη τη στιγμή ήμουν στην πρώτη θέση με μεγάλη διαφορά. Το μόνο που προκαλούσε σύγχυση ήταν ότι οι ενσωματώσεις εικόνων δεν παρουσίαζαν σχεδόν καθόλου ανάπτυξη. Η ιδέα ήρθε να δώσει τα πάντα στο catboost. Συγκεντρώνουμε εικόνες Kmeans και λαμβάνουμε ένα νέο κατηγορηματικό χαρακτηριστικό imageCat.

Ακολουθούν ορισμένες τάξεις μετά από χειροκίνητο φιλτράρισμα και συγχώνευση συμπλεγμάτων που λαμβάνονται από το KMeans.

SNA Hackathon 2019

Με βάση το imageCat δημιουργούμε:

  • Νέα κατηγορικά χαρακτηριστικά:
    • Ποιο imageCat προβλήθηκε συχνότερα από το userId;
    • Ποιο imageCat εμφανίζει πιο συχνά το ownerId.
    • Ποιο imageCat άρεσε πιο συχνά από το userId;
  • Διάφοροι μετρητές:
    • Πόσα μοναδικά imageCat εξέτασε το userId;
    • Περίπου 15 παρόμοια χαρακτηριστικά και κωδικοποίηση στόχου όπως περιγράφεται παραπάνω.

Κείμενα

Τα αποτελέσματα στον διαγωνισμό εικόνας μου ταίριαξαν και αποφάσισα να δοκιμάσω τις δυνάμεις μου σε κείμενα. Δεν έχω ξαναδουλέψει πολύ με κείμενα και, ανόητα, σκότωσα την ημέρα σε tf-idf και svd. Μετά είδα τη γραμμή βάσης με το doc2vec, το οποίο κάνει ακριβώς αυτό που χρειάζομαι. Έχοντας προσαρμόσει ελαφρώς τις παραμέτρους doc2vec, έλαβα ενσωματώσεις κειμένου.

Και μετά απλώς ξαναχρησιμοποίησα τον κώδικα για τις εικόνες, στον οποίο αντικατέστησα τις ενσωματώσεις εικόνων με ενσωματώσεις κειμένου. Ως αποτέλεσμα, πήρα τη 2η θέση στο διαγωνισμό κειμένου.

Συνεργατικό σύστημα

Είχε απομείνει ένας διαγωνισμός που δεν είχα «χτυπήσει» ακόμη με ένα ραβδί, και αν κρίνω από το AUC στον πίνακα κατάταξης, τα αποτελέσματα αυτού του συγκεκριμένου διαγωνισμού θα έπρεπε να είχαν τον μεγαλύτερο αντίκτυπο στο offline στάδιο.
Πήρα όλα τα χαρακτηριστικά που υπήρχαν στα δεδομένα πηγής, επέλεξα κατηγορίες και υπολόγισα τα ίδια συγκεντρωτικά στοιχεία όπως για τις εικόνες, εκτός από τα χαρακτηριστικά που βασίζονται στις ίδιες τις εικόνες. Απλώς βάζοντας αυτό στο catboost με έφερε στη 2η θέση.

Τα πρώτα βήματα βελτιστοποίησης catboost

Μία πρώτη και δύο δεύτερες θέσεις με ικανοποίησαν, αλλά υπήρχε η κατανόηση ότι δεν είχα κάνει κάτι ιδιαίτερο, πράγμα που σημαίνει ότι θα μπορούσα να περιμένω απώλεια θέσεων.

Το καθήκον του διαγωνισμού είναι να ταξινομεί τις αναρτήσεις εντός του χρήστη και όλο αυτό το διάστημα έλυνα το πρόβλημα ταξινόμησης, δηλαδή βελτιστοποιούσα τη λάθος μέτρηση.

Θα δώσω ένα απλό παράδειγμα:

ταυτότητα χρήστη αντικείμενο ID πρόβλεψη επίγεια αλήθεια
1 10 0.9 1
1 11 0.8 1
1 12 0.7 1
1 13 0.6 1
1 14 0.5 0
2 15 0.4 0
2 16 0.3 1

Ας κάνουμε μια μικρή αναδιάταξη

ταυτότητα χρήστη αντικείμενο ID πρόβλεψη επίγεια αλήθεια
1 10 0.9 1
1 11 0.8 1
1 12 0.7 1
1 13 0.6 0
2 16 0.5 1
2 15 0.4 0
1 14 0.3 1

Παίρνουμε τα ακόλουθα αποτελέσματα:

Μοντέλο AUC Χρήστης 1 AUC Χρήστης 2 AUC μέση AUC
Επιλογή 1 0,8 1,0 0,0 0,5
Επιλογή 2 0,7 0,75 1,0 0,875

Όπως μπορείτε να δείτε, η βελτίωση της συνολικής μέτρησης AUC δεν σημαίνει βελτίωση της μέσης μέτρησης AUC εντός ενός χρήστη.

Catboost ξέρει πώς να βελτιστοποιεί τις μετρήσεις κατάταξης από το κουτί. Διάβασα για μετρήσεις κατάταξης, ιστορίες επιτυχίας όταν χρησιμοποιείτε το catboost και ρυθμίστε το YetiRankPairwise να προπονείται όλη τη νύχτα. Το αποτέλεσμα δεν ήταν εντυπωσιακό. Αποφασίζοντας ότι ήμουν υποεκπαιδευμένος, άλλαξα τη συνάρτηση σφάλματος σε QueryRMSE, η οποία, κρίνοντας από την τεκμηρίωση του catboost, συγκλίνει πιο γρήγορα. Στο τέλος, πήρα τα ίδια αποτελέσματα με την προπόνηση για κατάταξη, αλλά τα σύνολα αυτών των δύο μοντέλων έδωσαν μια καλή άνοδο, που με έφερε στην πρώτη θέση και στους τρεις διαγωνισμούς.

5 λεπτά πριν από το κλείσιμο της διαδικτυακής σκηνής του διαγωνισμού «Συνεργατικά Συστήματα», ο Sergey Shalnov με έφερε στη δεύτερη θέση. Περπατήσαμε μαζί το περαιτέρω μονοπάτι.

Προετοιμασία για το στάδιο εκτός σύνδεσης

Είχαμε εγγυημένη νίκη στο διαδικτυακό στάδιο με μια κάρτα βίντεο RTX 2080 TI, αλλά το κύριο έπαθλο των 300 ρούβλια και, πιθανότατα, ακόμη και η τελική πρώτη θέση, μας ανάγκασαν να δουλέψουμε για αυτές τις 000 εβδομάδες.

Όπως αποδείχθηκε, ο Σεργκέι χρησιμοποίησε επίσης catboost. Ανταλλάξαμε ιδέες και χαρακτηριστικά και το έμαθα έκθεση της Anna Veronica Dorogush που περιείχε απαντήσεις σε πολλές από τις ερωτήσεις μου, ακόμα και σε αυτές που δεν είχα ακόμη μέχρι τότε.

Η προβολή της αναφοράς με οδήγησε στην ιδέα ότι πρέπει να επαναφέρουμε όλες τις παραμέτρους στην προεπιλεγμένη τιμή και να κάνουμε τις ρυθμίσεις πολύ προσεκτικά και μόνο αφού διορθώσουμε ένα σύνολο λειτουργιών. Τώρα μια προπόνηση χρειάστηκε περίπου 15 ώρες, αλλά ένα μοντέλο κατάφερε να αποκτήσει ταχύτητα καλύτερη από αυτή που είχε στο σύνολο με την κατάταξη.

Δημιουργία χαρακτηριστικών

Στον διαγωνισμό Collaborative Systems, ένας μεγάλος αριθμός χαρακτηριστικών αξιολογούνται ως σημαντικά για το μοντέλο. Για παράδειγμα, auditweights_spark_svd - το πιο σημαντικό σημάδι, αλλά δεν υπάρχουν πληροφορίες για το τι σημαίνει. Σκέφτηκα ότι θα άξιζε τον κόπο να μετρήσω τα διάφορα συγκεντρωτικά στοιχεία με βάση σημαντικά χαρακτηριστικά. Για παράδειγμα, ο μέσος όρος auditweights_spark_svd ανά χρήστη, ανά ομάδα, ανά αντικείμενο. Το ίδιο μπορεί να υπολογιστεί χρησιμοποιώντας δεδομένα στα οποία δεν πραγματοποιείται εκπαίδευση και στόχος = 1, δηλαδή μέσος όρος auditweights_spark_svd ανά χρήστη ανά αντικείμενα που του άρεσαν. Σημαντικά σημάδια εξάλλου auditweights_spark_svd, ήταν αρκετοί. Εδώ είναι μερικά από αυτά:

  • βάρη ελέγχουCtrΦύλο
  • βάρη ελέγχουCtrΥψηλό
  • userOwnerCounterCreate Likes

Για παράδειγμα, ο μέσος όρος βάρη ελέγχουCtrΦύλο σύμφωνα με το userId αποδείχθηκε ότι ήταν ένα σημαντικό χαρακτηριστικό, όπως και η μέση τιμή userOwnerCounterCreate Likes από userId+ownerId. Αυτό θα πρέπει ήδη να σας κάνει να πιστεύετε ότι πρέπει να κατανοήσετε τη σημασία των πεδίων.

Επίσης σημαντικά χαρακτηριστικά ήταν βαρη λογιστικων συμπαθειων и βάρη ελέγχουΕμφανίσειςΑριθμός. Διαιρώντας το ένα με το άλλο, αποκτήθηκε ένα ακόμη πιο σημαντικό χαρακτηριστικό.

Διαρροές δεδομένων

Ο ανταγωνισμός και η μοντελοποίηση παραγωγής είναι πολύ διαφορετικά καθήκοντα. Κατά την προετοιμασία των δεδομένων, είναι πολύ δύσκολο να ληφθούν υπόψη όλες οι λεπτομέρειες και να μην μεταφερθούν κάποιες μη ασήμαντες πληροφορίες σχετικά με τη μεταβλητή στόχο στο τεστ. Εάν δημιουργούμε μια λύση παραγωγής, θα προσπαθήσουμε να αποφύγουμε τη χρήση διαρροών δεδομένων κατά την εκπαίδευση του μοντέλου. Αλλά αν θέλουμε να κερδίσουμε τον ανταγωνισμό, τότε οι διαρροές δεδομένων είναι τα καλύτερα χαρακτηριστικά.

Έχοντας μελετήσει τα δεδομένα, μπορείτε να το δείτε σύμφωνα με τις τιμές του objectId βαρη λογιστικων συμπαθειων и βάρη ελέγχουΕμφανίσειςΑριθμός αλλαγή, πράγμα που σημαίνει ότι η αναλογία των μέγιστων τιμών αυτών των χαρακτηριστικών θα αντικατοπτρίζει τη μετατροπή μετατροπής πολύ καλύτερα από την αναλογία τη στιγμή της εμφάνισης.

Η πρώτη διαρροή που βρήκαμε είναι βαρη λογιστικων βαρη λογαριασμωνΜέγ.
Τι γίνεται όμως αν δούμε τα δεδομένα πιο προσεκτικά; Ας ταξινομήσουμε κατά ημερομηνία προβολής και ας λάβουμε:

αντικείμενο ID ταυτότητα χρήστη βάρη ελέγχουΕμφανίσειςΑριθμός βαρη λογιστικων συμπαθειων στόχος (είναι αρεστός)
1 1 12 3 πιθανώς όχι
1 2 15 3 ίσως ναι
1 3 16 4

Ήταν έκπληξη όταν βρήκα το πρώτο τέτοιο παράδειγμα και αποδείχθηκε ότι η πρόβλεψή μου δεν έγινε πραγματικότητα. Όμως, λαμβάνοντας υπόψη το γεγονός ότι οι μέγιστες τιμές αυτών των χαρακτηριστικών εντός του αντικειμένου έδωσαν αύξηση, δεν ήμασταν τεμπέληδες και αποφασίσαμε να βρούμε βάρη ελέγχουΕμφανίζειΕπόμενο и auditweightsLikesCountΕπόμενο, δηλαδή τις τιμές την επόμενη χρονική στιγμή. Με την προσθήκη μιας δυνατότητας
(auditweightsShowsCountNext-auditweightsShowsCount)/(auditweightsLikesCount-auditweightsLikesCountNext) κάναμε ένα απότομο άλμα γρήγορα.
Παρόμοιες διαρροές θα μπορούσαν να χρησιμοποιηθούν με την εύρεση των παρακάτω τιμών για userOwnerCounterCreate Likes εντός userId+ownerId και, για παράδειγμα, βάρη ελέγχουCtrΦύλο εντός objectId+userGender. Βρήκαμε 6 παρόμοια πεδία με διαρροές και αντλήσαμε όσο το δυνατόν περισσότερες πληροφορίες από αυτά.

Μέχρι εκείνη τη στιγμή, είχαμε αποσπάσει όσο το δυνατόν περισσότερες πληροφορίες από συνεργατικές λειτουργίες, αλλά δεν επιστρέψαμε σε διαγωνισμούς εικόνας και κειμένου. Είχα μια υπέροχη ιδέα να ελέγξω: πόσο δίνουν χαρακτηριστικά που βασίζονται απευθείας σε εικόνες ή κείμενα σε σχετικούς διαγωνισμούς;

Δεν υπήρχαν διαρροές στους διαγωνισμούς εικόνας και κειμένου, αλλά μέχρι τότε είχα επιστρέψει τις προεπιλεγμένες παραμέτρους catboost, είχα καθαρίσει τον κώδικα και είχα προσθέσει μερικές λειτουργίες. Το σύνολο ήταν:

Λύση σύντομα
Μέγιστο με εικόνες 0.6411
Μέγιστη χωρίς εικόνες 0.6297
Αποτέλεσμα δεύτερης θέσης 0.6295

Λύση σύντομα
Μέγιστο με κείμενα 0.666
Μέγιστο χωρίς κείμενα 0.660
Αποτέλεσμα δεύτερης θέσης 0.656

Λύση σύντομα
Μέγιστη σε συνεργασία 0.745
Αποτέλεσμα δεύτερης θέσης 0.723

Έγινε προφανές ότι ήταν απίθανο να μπορέσουμε να αποσπάσουμε πολλά από κείμενα και εικόνες, και αφού δοκιμάσαμε μερικές από τις πιο ενδιαφέρουσες ιδέες, σταματήσαμε να δουλεύουμε μαζί τους.

Περαιτέρω δημιουργία χαρακτηριστικών σε συνεργατικά συστήματα δεν έδωσε αύξηση και ξεκινήσαμε την κατάταξη. Στο διαδικτυακό στάδιο, το σύνολο κατάταξης και κατάταξης μου έδωσε μια μικρή αύξηση, όπως αποδείχτηκε επειδή υποεκπαίδευσα την κατάταξη. Καμία από τις συναρτήσεις σφάλματος, συμπεριλαμβανομένου του YetiRanlPairwise, δεν παρήγαγε σχεδόν το αποτέλεσμα που έκανε το LogLoss (0,745 έναντι 0,725). Υπήρχε ακόμα ελπίδα για το QueryCrossEntropy, το οποίο δεν μπορούσε να κυκλοφορήσει.

Στάδιο εκτός σύνδεσης

Στο στάδιο εκτός σύνδεσης, η δομή δεδομένων παρέμεινε η ίδια, αλλά υπήρξαν μικρές αλλαγές:

  • Τα αναγνωριστικά userId, objectId, ownerId επανατυχαιοποιήθηκαν.
  • Αρκετές πινακίδες αφαιρέθηκαν και αρκετές μετονομάστηκαν.
  • τα δεδομένα έχουν αυξηθεί περίπου 1,5 φορές.

Εκτός από τις αναφερόμενες δυσκολίες, υπήρχε ένα μεγάλο πλεονέκτημα: η ομάδα έλαβε έναν μεγάλο διακομιστή με RTX 2080TI. Απολαμβάνω το htop εδώ και πολύ καιρό.
SNA Hackathon 2019

Υπήρχε μόνο μια ιδέα - να αναπαραχθεί απλώς αυτό που ήδη υπάρχει. Αφού ξοδέψαμε μερικές ώρες ρυθμίζοντας το περιβάλλον στον διακομιστή, αρχίσαμε σταδιακά να επαληθεύουμε ότι τα αποτελέσματα ήταν αναπαραγώγιμα. Το βασικό πρόβλημα που αντιμετωπίζουμε είναι η αύξηση του όγκου των δεδομένων. Αποφασίσαμε να μειώσουμε λίγο το φορτίο και να ορίσουμε την παράμετρο catboost ctr_complexity=1. Αυτό μειώνει λίγο την ταχύτητα, αλλά το μοντέλο μου άρχισε να λειτουργεί, το αποτέλεσμα ήταν καλό - 0,733. Ο Σεργκέι, σε αντίθεση με εμένα, δεν χώρισε τα δεδομένα σε 2 μέρη και εκπαιδεύτηκε σε όλα τα δεδομένα, αν και αυτό έδωσε τα καλύτερα αποτελέσματα στο διαδικτυακό στάδιο, στο στάδιο εκτός σύνδεσης υπήρχαν πολλές δυσκολίες. Εάν παίρναμε όλα τα χαρακτηριστικά που δημιουργήσαμε και προσπαθήσαμε να τα βάλουμε στο catboost, τότε τίποτα δεν θα λειτουργούσε στο διαδικτυακό στάδιο. Ο Sergey έκανε βελτιστοποίηση τύπων, για παράδειγμα, μετατρέποντας τους τύπους float64 σε float32. Σε αυτό το άρθρο, Μπορείτε να βρείτε πληροφορίες για τη βελτιστοποίηση μνήμης στα πάντα. Ως αποτέλεσμα, ο Sergey εκπαιδεύτηκε στη CPU χρησιμοποιώντας όλα τα δεδομένα και πήρε περίπου 0,735.

Αυτά τα αποτελέσματα ήταν αρκετά για να κερδίσουμε, αλλά κρύψαμε την πραγματική μας ταχύτητα και δεν μπορούσαμε να είμαστε σίγουροι ότι άλλες ομάδες δεν έκαναν το ίδιο.

Πολεμήστε μέχρι το τέλος

Συντονισμός Catboost

Η λύση μας αναπαράχθηκε πλήρως, προσθέσαμε τις δυνατότητες δεδομένων κειμένου και εικόνων, οπότε το μόνο που έμεινε ήταν να συντονίσουμε τις παραμέτρους catboost. Ο Sergey εκπαιδεύτηκε στην CPU με μικρό αριθμό επαναλήψεων, και εγώ εκπαιδεύτηκα σε αυτήν με ctr_complexity=1. Έμενε μια μέρα και αν προσθέσατε απλώς επαναλήψεις ή αυξήσετε την ctr_complexity, τότε μέχρι το πρωί θα μπορούσατε να έχετε ακόμα καλύτερη ταχύτητα και να περπατάτε όλη την ημέρα.

Στο στάδιο εκτός σύνδεσης, οι ταχύτητες θα μπορούσαν πολύ εύκολα να κρυφτούν επιλέγοντας απλώς την όχι την καλύτερη λύση στον ιστότοπο. Περιμέναμε δραστικές αλλαγές στο leaderboard τα τελευταία λεπτά πριν κλείσουν οι υποβολές και αποφασίσαμε να μην σταματήσουμε.

Από το βίντεο της Άννας, έμαθα ότι για να βελτιώσετε την ποιότητα του μοντέλου, είναι καλύτερο να επιλέξετε τις ακόλουθες παραμέτρους:

  • βαθμός μάθησης — Η προεπιλεγμένη τιμή υπολογίζεται με βάση το μέγεθος του συνόλου δεδομένων. Η αύξηση του ρυθμού_μάθησης απαιτεί αύξηση του αριθμού των επαναλήψεων.
  • l2_leaf_reg — Συντελεστής τακτοποίησης, προεπιλεγμένη τιμή 3, επιλέξτε κατά προτίμηση από 2 έως 30. Η μείωση της τιμής οδηγεί σε αύξηση της υπερπροσαρμογής.
  • bagging_temperature — προσθέτει τυχαιοποίηση στα βάρη των αντικειμένων στο δείγμα. Η προεπιλεγμένη τιμή είναι 1, όπου τα βάρη λαμβάνονται από μια εκθετική κατανομή. Η μείωση της τιμής οδηγεί σε αύξηση της υπερπροσάρτησης.
  • τυχαία_δύναμη — Επηρεάζει την επιλογή των διαχωρισμών σε μια συγκεκριμένη επανάληψη. Όσο μεγαλύτερη είναι η τυχαία_δύναμη, τόσο μεγαλύτερη είναι η πιθανότητα επιλογής ενός διαχωρισμού χαμηλής σημασίας. Σε κάθε επόμενη επανάληψη, η τυχαιότητα μειώνεται. Η μείωση της τιμής οδηγεί σε αύξηση της υπερπροσάρτησης.

Άλλες παράμετροι έχουν πολύ μικρότερη επίδραση στο τελικό αποτέλεσμα, οπότε δεν προσπάθησα να τις επιλέξω. Μια επανάληψη εκπαίδευσης στο σύνολο δεδομένων GPU με ctr_complexity=1 διήρκεσε 20 λεπτά και οι επιλεγμένες παράμετροι στο μειωμένο σύνολο δεδομένων ήταν ελαφρώς διαφορετικές από τις βέλτιστες στο πλήρες σύνολο δεδομένων. Στο τέλος, έκανα περίπου 30 επαναλήψεις στο 10% των δεδομένων και μετά περίπου 10 ακόμη επαναλήψεις σε όλα τα δεδομένα. Αποδείχθηκε κάτι σαν αυτό:

  • βαθμός μάθησης Αύξησα κατά 40% από την προεπιλογή.
  • l2_leaf_reg το άφησε το ίδιο?
  • bagging_temperature и τυχαία_δύναμη μειώθηκε στο 0,8.

Μπορούμε να συμπεράνουμε ότι το μοντέλο ήταν υποεκπαιδευμένο με τις προεπιλεγμένες παραμέτρους.

Έμεινα πολύ έκπληκτος όταν είδα το αποτέλεσμα στον πίνακα κατάταξης:

Μοντέλο μοντέλο 1 μοντέλο 2 μοντέλο 3 σύνολο
Χωρίς συντονισμό 0.7403 0.7404 0.7404 0.7407
Με συντονισμό 0.7406 0.7405 0.7406 0.7408

Κατέληξα στο συμπέρασμα ότι εάν δεν απαιτείται γρήγορη εφαρμογή του μοντέλου, τότε είναι καλύτερο να αντικαταστήσετε την επιλογή των παραμέτρων με ένα σύνολο πολλών μοντέλων χρησιμοποιώντας μη βελτιστοποιημένες παραμέτρους.

Ο Sergey βελτιστοποιούσε το μέγεθος του συνόλου δεδομένων για να το τρέξει στη GPU. Η απλούστερη επιλογή είναι να αποκόψετε μέρος των δεδομένων, αλλά αυτό μπορεί να γίνει με διάφορους τρόπους:

  • αφαιρέστε σταδιακά τα παλαιότερα δεδομένα (αρχές Φεβρουαρίου) έως ότου το σύνολο δεδομένων αρχίσει να χωράει στη μνήμη.
  • αφαιρέστε χαρακτηριστικά με τη μικρότερη σημασία.
  • καταργήστε τα userIds για τα οποία υπάρχει μόνο μία καταχώρηση.
  • αφήστε μόνο τα userIds που βρίσκονται στη δοκιμή.

Και τελικά, φτιάξτε ένα σύνολο από όλες τις επιλογές.

Το τελευταίο σύνολο

Μέχρι αργά το βράδυ της τελευταίας ημέρας, είχαμε παρουσιάσει ένα σύνολο από τα μοντέλα μας που απέδιδε 0,742. Κατά τη διάρκεια της νύχτας εκτόξευσα το μοντέλο μου με ctr_complexity=2 και αντί για 30 λεπτά προπονήθηκε για 5 ώρες. Μόνο στις 4 τα ξημερώματα μετρήθηκε, και έφτιαξα το τελευταίο σύνολο, που έδωσε 0,7433 στο δημόσιο leaderboard.

Λόγω διαφορετικών προσεγγίσεων για την επίλυση του προβλήματος, οι προβλέψεις μας δεν συσχετίστηκαν έντονα, γεγονός που έδωσε μια καλή αύξηση στο σύνολο. Για να αποκτήσετε ένα καλό σύνολο, είναι καλύτερο να χρησιμοποιήσετε το ακατέργαστο μοντέλο προβλέψεων predict(prediction_type='RawFormulaVal') και να ορίσετε scale_pos_weight=neg_count/pos_count.

SNA Hackathon 2019

Στην ιστοσελίδα μπορείτε να δείτε τελικά αποτελέσματα στον ιδιωτικό πίνακα κατάταξης.

Άλλες λύσεις

Πολλές ομάδες ακολούθησαν τους κανόνες των αλγορίθμων συστημάτων συστάσεων. Εγώ, που δεν είμαι ειδικός σε αυτόν τον τομέα, δεν μπορώ να τα αξιολογήσω, αλλά θυμάμαι 2 ενδιαφέρουσες λύσεις.

  • Η λύση του Nikolay Anokhin. Ο Νικολάι, ως υπάλληλος του Mail.ru, δεν υπέβαλε αίτηση για βραβεία, επομένως ο στόχος του δεν ήταν να επιτύχει τη μέγιστη ταχύτητα, αλλά να αποκτήσει μια εύκολα επεκτάσιμη λύση.
  • Η απόφαση της ομάδας που κέρδισε το βραβείο της κριτικής επιτροπής με βάση αυτό το άρθρο από το facebook, επέτρεψε πολύ καλή ομαδοποίηση εικόνων χωρίς χειρωνακτική εργασία.

Συμπέρασμα

Αυτό που μου έχει μείνει περισσότερο στη μνήμη:

  • Εάν υπάρχουν κατηγορικές δυνατότητες στα δεδομένα και γνωρίζετε πώς να κάνετε σωστά την κωδικοποίηση στόχων, είναι καλύτερο να δοκιμάσετε το catboost.
  • Εάν συμμετέχετε σε έναν διαγωνισμό, δεν πρέπει να χάνετε χρόνο επιλέγοντας παραμέτρους εκτός από το learning_rate και τις επαναλήψεις. Μια πιο γρήγορη λύση είναι να φτιάξετε ένα σύνολο από πολλά μοντέλα.
  • Οι ενισχύσεις μπορούν να μάθουν στη GPU. Το Catboost μπορεί να μάθει πολύ γρήγορα στη GPU, αλλά καταναλώνει πολλή μνήμη.
  • Κατά την ανάπτυξη και τη δοκιμή ιδεών, είναι καλύτερο να ορίσετε ένα μικρό rsm~=0.2 (μόνο CPU) και ctr_complexity=1.
  • Σε αντίθεση με άλλες ομάδες, το σύνολο των μοντέλων μας έδωσε μεγάλη άνοδο. Ανταλλάξαμε μόνο ιδέες και γράψαμε σε διάφορες γλώσσες. Είχαμε μια διαφορετική προσέγγιση για τον διαχωρισμό των δεδομένων και, νομίζω, το καθένα είχε τα δικά του σφάλματα.
  • Δεν είναι σαφές γιατί η βελτιστοποίηση κατάταξης απέδωσε χειρότερα από τη βελτιστοποίηση ταξινόμησης.
  • Απέκτησα κάποια εμπειρία δουλεύοντας με κείμενα και κατανοώ πώς κατασκευάζονται τα συστήματα συστάσεων.

SNA Hackathon 2019

Ευχαριστούμε τους διοργανωτές για τις συγκινήσεις, τις γνώσεις και τα βραβεία που έλαβαν.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο