Αυτό θα είναι ένα ακόμη τεχνικό post για το πώς υλοποίησα έναν απλό αλγόριθμο κατάταξης για το project News. Ωστόσο, θα προσπαθήσω να το κρατήσω απλό και κατανοητό για άτομα που δεν έχουν τεχνικές γνώσεις.
Το χαρακτηριστικό που χρειαζόταν ήταν μια λίστα με καυτές ειδήσεις που θα εμφανιζόταν στην αρχική σελίδα. Ο ορισμός του τι είναι δεν ήταν ξεκάθαρος εκείνη τη στιγμή, αλλά ήξερα ότι έπρεπε να χρησιμοποιήσω δεδομένα από τα μέσα κοινωνικής δικτύωσης για τον υπολογισμό του. Θα εξηγήσω πώς το έκανα.
Μερικά πράγματα που ήξερα ήταν ότι ένα άρθρο δεν έπρεπε να είναι παλαιότερο από τρεις ημέρες και ότι έπρεπε να υπολογίσω μια βαθμολογία που θα έπρεπε να φθίνει με την πάροδο του χρόνου.
Για αυτό, οι προτιμήσεις των χρηστών και άλλοι παράγοντες δεν λαμβάνονται υπόψη και θεωρούνται εκτός πεδίου εφαρμογής. Αυτά είναι πιο πολύπλοκα και θα τα αντιμετωπίσω στο μέλλον.
Συγκέντρωση δεδομένων μέσω των δικτύων κοινωνικών μέσων ενημέρωσης
Αποφάσισα να αξιοποιήσω τη δύναμη των δικτύων κοινωνικής δικτύωσης όπως το Reddit και το Hacker News για να καταλάβω τι συνιστά ένα "καυτό" άρθρο. Μέσω της σχολαστικής συλλογής δεδομένων από αυτές τις πλατφόρμες, άρχισα να λαμβάνω σαφέστερες πληροφορίες. Κάθε δίκτυο έχει ένα score
για την ανάρτηση και θα το αποθηκεύσω στη βάση δεδομένων.
Αλλά πρώτα απ' όλα: έπρεπε να πάρω τα δεδομένα από αυτές τις πλατφόρμες. Τα άρθρα ειδήσεων είναι ουσιαστικά σύνδεσμοι προς τις αρχικές πηγές ειδήσεων, οπότε έπρεπε να βρω ποια άρθρα από τη βάση δεδομένων έχουν κοινοποιηθεί στα κοινωνικά δίκτυα. Ένα απλό πράγμα που μπορούσα να κάνω ήταν να χρησιμοποιήσω τη λειτουργία αναζήτησης κάθε πλατφόρμας. Φυσικά, χρησιμοποίησα μια ουρά αναμονής για να μην εκραγεί ο διακομιστής φιλοξενίας.
Για το Hacker News η διεύθυνση URL είναι
https://hn.algolia.com/api/v1/search?tags=story&query=
Αυτό θα επιστρέψει ένα αντικείμενο json με έναν πίνακα hits
. Αν ο πίνακας είναι άδειος, τότε το άρθρο δεν κοινοποιήθηκε στο Hacker News. Αν ο πίνακας δεν είναι άδειος, τότε θα αποθηκεύσω το πεδίο points
στη βάση δεδομένων μας.
Σημειώστε ότι θα αποθηκεύσει κάθε κοινοποίηση του συνδέσμου, οπότε αν το άρθρο κοινοποιήθηκε πολλές φορές, θα έχει πολλαπλές καταχωρήσεις στη βάση δεδομένων μας. Αυτό δεν αποτελεί πρόβλημα, απλά θα υπολογίσω το μέσο όρο των πόντων για κάθε άρθρο.
Για το Reddit, η διεύθυνση URL είναι
https://www.reddit.com/search.json?q=
Θα επιστρέψει ένα αντικείμενο json με έναν πίνακα data.children
. Αν ο πίνακας είναι άδειος, τότε το άρθρο δεν κοινοποιήθηκε στο reddit. Αν ο πίνακας δεν είναι άδειος, τότε θα αποθηκεύσω το πεδίο data.children.data.data.score
στη βάση δεδομένων μας.
Με αυτά τα δεδομένα, θα έχουμε έναν πίνακα σαν αυτόν και μπορούμε να αρχίσουμε να δουλεύουμε τον αλγόριθμο.
article_id | type | score |
---|---|---|
1 | hackernews | 10 |
1 | 20 | |
2 | hackernews | 5 |
2 | 10 | |
3 | hackernews | 17 |
Βρείτε έναν αλγόριθμο κατάταξης στην άγρια φύση
Ας προσπαθήσουμε να μην ανακαλύψουμε ξανά τον τροχό και να βρούμε έναν αλγόριθμο που ήδη λειτουργεί. Μετά από κάποια έρευνα, βρήκα ότι το reddit έχει έναν καυτό αλγόριθμο. Ένα μικρό πρόβλημα είναι ότι είναι γραμμένος σε pyrex και χρησιμοποιώ NestJS και Typescript.
Θα μπορούσα να τον μεταφράσω με το χέρι, αλλά αυτό θα ήταν τόσο 2021 🤡. Έτσι θα χρησιμοποιήσω το Copilot. Έχει μια λειτουργία προεπισκόπησης και τα εργαστήρια που μπορούν να μεταφράσουν γλώσσες κώδικα. Το προτίμησα όντως από το ChatGPT, καθώς είναι ειδικά εκπαιδευμένο για κώδικα και τείνει να είναι πιο ακριβές.
Όπως συνήθιζε να μου λέει ο πατέρας μου: Χρησιμοποιήστε το σωστό εργαλείο για τη δουλειά. Αν δεν το έχετε, χακάρετέ το. (Τα ελληνικά χρησιμοποιούν τη λέξη patent/πατέντα ως just-in-time invention)
Το μέρος από τον κώδικα του Reddit pyrex από το archived repository που μας ενδιαφέρει είναι:
cpdef double _hot(long ups, long downs, double date):
"""The hot formula. Θα πρέπει να ταιριάζει με την αντίστοιχη συνάρτηση στο postgres."""
s = score(ups, downs)
order = log10(max(abs(s), 1))
if s > 0:
sign = 1
elif s < 0:
sign = -1
else:
sign = 0
seconds = date - 1134028003
return round(sign * order + seconds / 45000, 7)
Μεταφράζω σε typescript και πήρα ένα καλό σημείο εκκίνησης. Το επόμενο βήμα είναι να το αναθεωρήσω και να το διορθώσω όπως πρέπει πάντα να κάνουμε όταν παράγουμε κώδικα με LLMs. Για να εξηγήσετε πώς λειτουργεί, το ChatGPT μπορεί να είναι πολύ χρήσιμο. Για παράδειγμα, χρειάστηκε να κάνω μια συζήτηση για το τι είναι ο αριθμός "45000" και πώς λειτουργεί.
Τελικά κατέληξα στον ακόλουθο κώδικα:
calcScore(article: Article) {
// Ορίζω κάποια βαρύτητα για να περιορίσω τον αντίκτυπο κάθε κοινωνικού δικτύου
// Ξέρω ότι το hackernews έχει περισσότερες τεχνικές ειδήσεις
const weights = { reddit: 1, hackernews: .7 }
// Υπολογίζω το μέσο όρο της βαθμολογίας κάθε κοινωνικού δικτύου
const average = article.socials.reduce((acc, social) => {
return acc + (social.score * weights[social.name])
}, 0) / article.socials.length
// Αυτός είναι ο κύριος αλγόριθμος.
// Υπολογίζω την τάξη μεγέθους του μέσου όρου χρησιμοποιώντας log10
const order = Math.log10(Math.max(Math.abs(average),1))
// Υπολογίζω τα δευτερόλεπτα από την εποχή.
// Χρησιμοποιώ το 2023 ως εποχή επειδή θέλω να έχω θετικό αριθμό
// και οι τρεις τελευταίες ημέρες μας είναι το 2023.
const epoch = new Date(2023, 1, 1)
// Το 45000 είναι ένας μαγικός αριθμός που χρησιμοποιεί το reddit.
// Τον χρησιμοποιώ και εγώ ως έχει. Αν το μειώσω, το σκορ θα είναι υψηλότερο.
// και αν το αυξήσω, η βαθμολογία θα είναι χαμηλότερη.
// Αυτό θα αλλάξει τον τρόπο με τον οποίο ευνοώ την ηλικία του άρθρου.
const magic = 45000
const seconds =
differenceInSeconds(article.publishedAt, epoch) / magic
// Υπολογίζω το σκορ και κρατάω μόνο 7 ψηφία
const score = Math.round((order + seconds) * 100000)
return { average, order, seconds, score}
}
Τα αποτελέσματα
Πριν το χρησιμοποιήσω στην αρχική σελίδα πρέπει να δω αν λειτουργεί. Δημιούργησα ένα debug api που θα μας δείξει τη βαθμολογία κάθε άρθρου καθώς και τις άλλες τιμές. Επίσης, συμπεριλαμβάνω και άλλα του άρθρου για να έχουμε καλύτερη κατανόηση της βαθμολογίας.
Σε αυτή την τελική κατάσταση δεν υπάρχει ντετερμινιστικός τρόπος να γνωρίζουμε αν η βαθμολογία είναι καλή ή όχι. Μπορώ μόνο να χρησιμοποιήσω τη διαίσθησή μας και την προτίμησή μας κοιτάζοντας τα αποτελέσματα. Μπορώ επίσης να τροποποιήσω τον αλγόριθμο για να ταιριάζει καλύτερα στις ανάγκες μας.
Το τελικό σημείο εντοπισμού σφαλμάτων δεν αναφέρεται πουθενά στον ιστότοπο, καθώς το χρησιμοποιώ μόνο για δοκιμαστικούς σκοπούς. Αλλά αν φτάσατε μέχρι εδώ, μπορείτε να το βρείτε στη διεύθυνση /debug/hot.
Ένα παράδειγμα απάντησης των αποτελεσμάτων είναι το εξής:
[
{
"id": "7c59e519-16c6-42fa-b265-67569c4c2fef",
"title": "Έγγραφα της Microsoft διαρρέουν νέα παιχνίδια της Bethesda, συμπεριλαμβανομένου ενός remaster του Oblivion",
"publishedAt": "2023-09-19T07:10:06.749Z",
"calc": {
"average": 463.175,
"order": 2.66574511018601,
"seconds": 442.1734666666667,
"score": 44483921
}
},
{
"id": "6ff8ed99-fe81-4839-a4f1-d356e23bdb66",
"title": "Google αύξησε αθόρυβα τις τιμές των διαφημίσεων για να ενισχύσει τα έσοδα από την αναζήτηση, λέει στέλεχος",
"publishedAt": "2023-09-19T14:01:01.631Z",
"calc": {
"average": 79.1,
"order": 1.8981764834976764,
"seconds": 442.72135555555553,
"score": 44461953
}
},
{
"id": "0efd703d-1399-431d-85bc-ff116ca30060",
"title": "Αυτός είναι ο νέος σχεδιασμός Xbox Series X χωρίς δίσκο της Microsoft με νέο χειριστήριο",
"publishedAt": "2023-09-19T05:45:05.849Z",
"calc": {
"average": 276.4230769230769,
"order": 2.4415742968859298,
"seconds": 442.0601111111111,
"score": 44450169
}
},
...
Όταν ήμουν έτοιμος, ήταν ένα απλό θέμα χρήσης του αλγορίθμου στην αρχική σελίδα. Χρησιμοποίησα τη βαθμολογία για να ταξινομήσω τα άρθρα και να περιορίσω τα αποτελέσματα σε 7 άρθρα.
Το αποτέλεσμα όπως είναι στην home είναι:
Συμπερασματικά
Η δημιουργία ενός αλγορίθμου κατάταξης μπορεί να ακούγεται τρομακτική, ειδικά αν δεν είστε πολύ εξοικειωμένοι με την τεχνολογία. Αλλά με καλή κατανόηση των στόχων σας, τα σωστά δεδομένα, έναν κατάλληλο αλγόριθμο και εργαλεία που βοηθούν στην κατανόηση και τη μετάφραση, γίνεται πολύ πιο απλό.
Είτε είστε ένας επίδοξος προγραμματιστής, ένας λάτρης της τεχνολογίας ή απλώς κάποιος που ενδιαφέρεται για το πώς λειτουργούν τα πράγματα στο παρασκήνιο, ελπίζω αυτό το ιστολόγιο να σας απομυθοποίησε τους αλγόριθμους κατάταξης.
Αν έχετε οποιεσδήποτε ερωτήσεις ή σχόλια σχετικά με αυτή τη δημοσίευση, μη διστάσετε να επικοινωνήσετε μαζί μου. Επίσης, χρειάζομαι έναν αλγόριθμο κατάταξης για το έργο σας, θα χαρώ να σας βοηθήσω.
Το παρόν άρθρο δημιουργήθηκε με τη βοήθεια της ΤΝ και βελτιώθηκε με τη χρήση εργαλείων διόρθωσης. Αν και χρησιμοποιήθηκαν τεχνολογίες ΤΝ, το περιεχόμενο και οι ιδέες που εκφράζονται σε αυτό το άρθρο είναι αποτέλεσμα ανθρώπινης επιμέλειας και συγγραφής.
Μπορείτε να διαβάσετε περισσότερα σχετικά με το θέμα στο: Η σημασία είναι το μόνο που χρειάζεστε