Quale algoritmo applicare per scegliere il punto giusto


9

L'immagine sotto mostra 7 punti intorno all'origine. Uno di questi è stato selezionato da un essere umano in base a regole ed esperienza ed è colorato in rosso (quello nel quadrante in basso a sinistra).

inserisci qui la descrizione dell'immagine

Ora abbiamo oltre 1000 di questi insiemi di punti e per ogni insieme un umano ha selezionato un singolo punto. Queste condizioni si applicano a tutti i set:

  • Ogni set ha circa 3 - 10 punti
  • Non ci sono valori anomali
  • I punti possono avere valori positivi e negativi
  • Non sono stati commessi errori durante la selezione di un punto

La mia domanda è: esiste un algoritmo di apprendimento automatico per imparare da questi insiemi e selezioni fatte dall'uomo in modo che possa decidere automaticamente quale punto selezionare quando viene assegnato un nuovo insieme di punti? Questo nuovo set soddisfa ovviamente le prime 3 condizioni dall'alto.

2 osservazioni finali:

  • L'esempio che ho fornito è solo un esempio costruito a caso da me per supportare l'idea dei punti in un piano attorno all'origine insieme a uno selezionato. Nella vita reale potrebbe esserci più struttura ma per ora sono curioso e vorrei sapere cosa è possibile per questo caso.
  • Le variazioni sarebbero possibili? Supponiamo che si tratti di circa 2 punti selezionati o di avere cerchi con un determinato raggio anziché punti.

2
Solo pensando ad alta voce, il trucco del kernel potrebbe essere d'aiuto? Il punto selezionato sembra piuttosto seduto molto vicino ad altri punti mentre è probabile che sia separabile in altro spazio (ad es. Dimensione superiore), quindi fai la classificazione! Direi che vale la pena pensare.
TwinPenguins

1
@MajidMortazavi Sembra buono. Ad essere sincero, l'apprendimento automatico è un nuovo campo per me. L'unica cosa che so è che è possibile, ma non ho idea di come e cosa. Proverà a leggere il tuo suggerimento sul kernel.
Elmex80

2
Se aggiungi funzionalità a ciascun punto, come la distanza dagli altri punti, il numero di altri punti ecc., Probabilmente potresti usare qualcosa di semplice come K-Nearby Neighbours per determinare su quali punti storici su cui ti sei allenato è più simile a i tuoi nuovi punti e usa quella classificazione. Gli alberi decisionali o le reti neurali potrebbero adattarsi meglio a questo tipo di confine non lineare.
Dan Carter,

1
Per abbandonare il commento di @ DanCarter, chiedere quale algoritmo ML usare è la domanda sbagliata. Pensa alle funzionalità che puoi progettare e lascia che determinino quali metodi usare (qui il plurale è essenziale; non dovresti mai provare un solo metodo, a meno che il problema non sia ben compreso). Alcune altre possibili funzionalità da provare: distanza dal centroide (sia assoluta che relativa alla distanza medio punto-centroide), distanza dall'origine, angolo che il vettore origine-punto fa con un asse.
Paul,

1
Due o più punti possono essere arbitrariamente vicini l'uno all'altro?
Imran,

Risposte:


6

Questo è un problema affascinante! Due cose lo rendono particolarmente impegnativo:

  • Come dovremmo confrontare due set di punti? I problemi classici nell'apprendimento automatico hanno un numero fisso di attributi e questi attributi non sono intercambiabili: ad esempio, potrei avere dati su diverse persone con attributi agee height(in centimetri). Ogni campione ha una voce per ciascuno, e ovviamente (age, height) = (22, 180)non è la stessa (age, height) = (180, 22). Né è vero nel tuo problema. Una serie di punti ha tra 3 e 10 punti e l'ordine in cui inseriamo i punti non dovrebbe fare la differenza quando si confrontano due serie di punti.
  • Come facciamo una previsione? Supponiamo di aver trovato un modo per selezionare i set di punti dal nostro set di allenamento simili al set di punti sopra riportato. Affrontiamo il problema che la nostra previsione deve essere uno dei 7 punti nella tua foto; ma nessuno di questi punti potrebbe essere contenuto in insiemi di punti simili.

Vorrei delineare un algoritmo che affronti entrambe le sfide. L'accuratezza della previsione non è molto buona; ma forse vedi un modo per migliorarlo. E almeno prevede qualcosa , giusto?

1. Simulazione di campioni

Per poter testare l'algoritmo, ho scritto funzioni che generano campioni ed etichette.

Generazione di campioni: ogni campione contiene tra 3 e 10 punti. Il numero di punti è casuale, tratto da una distribuzione uniforme. Ogni punto è della forma (x_coordinate, y_coordinate). Le coordinate sono di nuovo casuali, tratte da una distribuzione normale.

import numpy as np
from random import randint

def create_samples(number_samples, min_points, max_points):

    def create_single_sample(min_points, max_points):
        n = randint(min_points, max_points)
        return np.array([np.random.normal(size=2) for _ in range(n)]) 

    return np.array([create_single_sample(min_points, max_points) for _ in range(number_samples)])

Generazione di etichette: come esempio di un giocattolo, supponiamo che la regola per scegliere un punto sia: scegli sempre il punto più vicino a (0, 0), dove "più vicino" dovrebbe essere compreso in termini di norma euclidea.

def decision_function_minnorm(sample):
    norms = np.apply_along_axis(np.linalg.norm, axis=1, arr=sample)
    return sample[norms.argmin()]

def create_labels(samples, decision_function):
    return np.array([decision_function(sample) for sample in samples])

Ora possiamo creare i nostri set di treni e test:

n_train, n_test = 1000, 100
dec_fun = decision_function_minnorm

X_train = create_samples(number_samples=n_train, min_points=3, max_points=10)
X_test = create_samples(number_samples=n_test, min_points=3, max_points=10)
y_train = create_labels(X_train, dec_fun)
y_test = create_labels(X_test, dec_fun)

2. Confronto dei set di punti tramite la distanza di Hausdorff

Affrontiamo il primo problema: come dobbiamo confrontare diversi set di punti? Il numero di punti nelle serie di punti è diverso. Ricorda anche che l'ordine in cui annotiamo i punti non dovrebbe avere importanza: il confronto con il set di punti [(0,0), (1,1), (2,2)]dovrebbe produrre lo stesso risultato del confronto con il set di punti [(2,2), (0,0), (1,1)]. Il mio approccio è quello di confrontare i set di punti tramite la loro distanza Hausdorff :

def hausdorff(A, B):

    def dist_point_to_set(x, A):
        return min(np.linalg.norm(x - a) for a in A)

    def dist_set_to_set(A, B):
        return max(dist_point_set(a, B) for a in A)

    return max(dist_set_to_set(A, B), dist_set_to_set(B, A))

3. Previsione tramite k-vicini più vicini e media

Ora abbiamo una nozione di distanza tra set di punti. Ciò consente di utilizzare la classificazione k-vicini più vicini: dato un set di punti di test, troviamo i kset di punti nel nostro campione di addestramento che hanno la distanza più piccola di Hausdorff rispetto al set di punti di test e ottengono le loro etichette. Ora arriva il secondo problema: come trasformiamo queste ketichette in una previsione per il set di punti test? Ho adottato l'approccio più semplice: fare la media delle etichette e prevedere il punto nel set di punti di test più vicino alla media.

def predict(x, num_neighbors):
    # Find num_neighbors closest points in X_train.
    distances_to_train = np.array([hausdorff(x, x_train) for x_train in X_train])
    neighbors_idx = np.argpartition(distances_to_train, -num_neighbors)[-num_neighbors:]

    # Get labels of the neighbors and calculate the average.
    targets_neighbors = y_train[neighbors_idx]
    targets_mean = sum(targets_neighbors) / num_neighbors

    # Find point in x that is closest to targets_mean and use it as prediction.
    distances_to_mean = np.array([np.linalg.norm(p - targets_mean) for p in x])
    closest_point = x[distances_to_mean.argmin()]

    return closest_point

4. Test

Tutto è a posto per testare le prestazioni del nostro algoritmo.

num_neighbors = 70
successes = 0
for i, x in enumerate(X_test):
    print('%d/%d' % (i+1, n_test))
    prediction = predict(x, num_neighbors)
    successes += np.array_equal(prediction, y_test[i])

Per la data funzione decisionale e num_neighbors = 70otteniamo una precisione di previsione dell'84%. Questo non è terribilmente buono, ed è ovviamente specifico per la nostra funzione decisionale, che sembra abbastanza facile da prevedere.

Per vedere questo, definire una diversa funzione decisionale:

decision_function_maxaverage(sample):
    avgs = (sample[:, 0] + sample[:, 1]) / 2
    return sample[norms.argmin()]

L'uso di questa funzione dec_fun = decision_function_maxaverageriduce la precisione delle previsioni al 45%. Questo dimostra quanto sia importante pensare alle regole di decisione che generano le tue etichette. Se hai un'idea del perché le persone scelgono determinati punti, questo ti aiuterà a trovare l'algoritmo migliore.

Alcuni modi per migliorare questo algoritmo: (1) Usa una funzione di distanza diversa invece della distanza di Hausdorff, (2) usa qualcosa di più sofisticato dei vicini k-più vicini, (3) migliora il modo in cui le etichette di allenamento selezionate vengono trasformate in una previsione.


3

Ecco alcuni modi in cui potresti utilizzare le reti neurali per risolvere questo problema:

Con una semplice rete neurale Feedforward:

  • Ridimensiona i dati per adattarli al quadrato attorno all'origine da (-1, -1) a (1,1)
  • K
  • Aggiungi un terzo indicatore di input per ogni punto, indicando se quel punto è presente
  • Scegli il numero e la dimensione dei livelli nascosti
  • Utilizzare uno strato di softmax di dimensione 10 in uscita

KK

Con una rete neurale convoluzionale:

  • nnnnKKio,j010
  • n*n

La CNN potrebbe funzionare meglio poiché i tuoi dati sono intrinsecamente spaziali. Tuttavia devi decidere cosa fare se due o più punti si sovrappongono. La soluzione più semplice è sceglierne una a caso, che potrebbe essere OK a seconda dell'attività specifica.

Con una rete neurale ricorrente:

  • Inserisci sequenze di lunghezza variabile di punti in scala (x, y) e genera una stima del softmax di dimensione 10

Sì, è così semplice con gli RNN! Gestiscono bene input di lunghezza variabile, ma mancano ancora dei vantaggi delle CNN per la gestione dei dati spaziali.

Avvertenze:

Se si utilizza un FNN o un RNN, esiste anche la questione di come ordinare i dati di input. Se non esiste un ordine intrinseco nei dati reali, non vogliamo che la nostra rete faccia previsioni diverse per gli stessi dati codificati in ordini diversi. Un modo per gestirlo è con l'aumento dei dati : duplica ogni volta alcuni esempi di addestramento con diversi ordini di input, quindi spero che la tua rete possa apprendere le simmetrie appropriate.

Se hai solo il tempo di provare un approccio, sceglierei la CNN. Le CNN sono progettate per funzionare bene con i dati spaziali e non vi sono problemi con gli ordini di input.


1
Il problema è che la previsione dipende dall'ordine. Alimentare l'algoritmo di un set di punti (0,0), (1,1), (2,2)avrà un effetto diverso rispetto al fornire un set di punti (1,1), (2,2), (0,0).
Elias Strehle,

Buon punto Elias - Farò un suggerimento per mitigarlo.
Imran,

È bene che @EliasStrehle lo menzioni, l'ordine è irrilevante per questo problema. Abbiamo una serie di punti (tutti unici, nessun ordine).
Elmex80
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.