Considerazioni di architettura per abbinare frequentemente utenti simili

2

Ho cercato di progettare un'architettura backend in una SPA che soddisfi i seguenti requisiti:

  • l'utente risponde costantemente a sì / no domande (es: tinder swipe cards)
  • L'applicazione calcola la somiglianza di ciascun utente tra loro esclusivamente in base alle risposte
  • La somiglianza tra gli utenti dovrebbe essere aggiornata quando rispondono a più domande
  • L'applicazione richiede periodicamente a due utenti attivi con sufficiente somiglianza di accedere alla chat privata
  • L'applicazione avrà fino a 10 000 domande

Domanda:

Quale componente architettonico dovrebbe calcolare / archiviare / gestire la similarità degli utenti dato che ci sono molti utenti attivi simultaneamente che aggiornano costantemente il proprio set di risposte?

Possibili approcci che ho considerato:

  1. Crea tabelle K-many (db). Periodicamente, gli utenti sono raggruppati in cluster (K-medie) in esattamente una delle tabelle K. Tutti gli utenti all'interno di una determinata tabella hanno una somiglianza sufficiente. Il client richiede due utenti attivi da una determinata tabella. punti di incollaggio: dove / quando viene eseguito questo calcolo nell'architettura e può essere ri-clustered solo 1 utente in base ai relativi aggiornamenti?
  2. Calcola in movimento (thread client e / o server worker) + caching. Un processo in background del client richiede un elenco di utenti casuali e calcola la somiglianza dell'utente di this con ciascuno. Partite di Caches. punti di incollaggio: se un utente risponde ad alta frequenza, con quale frequenza viene eseguito questo calcolo? Inoltre scala?
  3. Rappresentazione di risposte bitfield / bit nel modello user (server / db): periodicamente il client richiede un utente corrispondente. Il server risponde con un utente effettuando una query in base al bitfield. punti di incollaggio: in che modo questa scala è in grado di rispondere a tutte le 10.000 domande (ad esempio: un database può archiviare e interrogare su una rappresentazione a bit così grande)?

Tecnologia attualmente in uso: Node / Express, PostgreSQL + ORM, Websockets.

Qualsiasi idea con schemi architettonici o progettazione di database o approcci migliori per questo scenario sarebbe molto apprezzata.

Ricerca / correlati:

posta vapurrmaid 06.01.2018 - 21:49
fonte

1 risposta

1

Ottima domanda. Sfortunatamente, non posso rispondere completamente, ma questo è un po 'troppo per un commento.

K-Means

L'approccio K-medie è probabilmente l'opzione più realistica nelle seguenti condizioni:

  • Sai - o puoi calcolare - un buon valore per k in qualsiasi momento vuoi confrontare gli utenti.

  • Stai bene confrontando gli utenti solo a determinati intervalli, non dopo ogni domanda.

  • Hai un'idea su come gestire gli utenti che non hanno risposto a tutte le domande.

    Se visualizzi le risposte di ciascun utente come un vettore di {Yes, No, NotAnswered} ^ 10k, gli utenti che non hanno risposto a molte domande potrebbero essere molto simili, indipendentemente da quanto concordino sulle risposte che hanno dato - specialmente se hai (k-1) cluster "reali".

Se si desidera modificare un solo utente, è possibile farlo in una certa misura: rimuovere l'utente dal relativo cluster e aggiungerlo al nuovo cluster più vicino. Naturalmente, col tempo i mezzi dei cluster non rifletteranno più la realtà, quindi è necessario aggiornarli (a quel punto, naturalmente, qualsiasi utente può essere nuovamente assegnato).

Nota: è possibile aggiornare i mezzi mentre si va, naturalmente, ma è comunque necessario ricomporre il cluster dopo un po ', altrimenti i cluster diventano sempre più inutili.

Aggiornamenti live

Il tuo secondo approccio potrebbe fornirti un'immagine più accurata in qualsiasi momento, ma non è fattibile per nessun numero non banale di utenti. Tuttavia, potrebbe funzionare anche per te in determinate condizioni.

Poiché inviti gli utenti a chattare, presumo che tu abbia davvero bisogno di confrontare la somiglianza tra gli utenti attualmente loggati, il che può essere o meno ragionevole.

Inoltre, la memorizzazione di valori di similarità tra ogni coppia di utenti probabilmente non sarà possibile, anche se ci si limita a utenti attivi. Tuttavia, hai indicato che potresti archiviare solo coppie corrispondenti. Se questo esclude la maggior parte delle coppie, potrebbe essere praticabile. Puoi provare a trovare un modo dinamico per calcolare la soglia di cut-off per assicurarti di filtrare la maggior parte delle coppie.

Avrai bisogno di un modo rapido per confrontare la somiglianza. È possibile utilizzare un vettore bit per rappresentare Sì / No e un altro per rappresentare Risposta / Non risposta. Puoi usare quelli direttamente per verificare l'uguaglianza, ma non per la somiglianza. In realtà devi contare bit uguali. Questa sarà un'operazione O (| Domande |).

Hash sensibile locale

Se potresti trovare una funzione di hash che mette i vettori di risposta ragionevolmente simili nello stesso bucket, puoi usarlo per la corrispondenza a grana grossa e quindi confrontare solo gli utenti nello stesso bucket.

Sfortunatamente, non vedo come potrebbe essere una tale funzione di hash.

    
risposta data 07.01.2018 - 15:10
fonte