Un esempio
Questo esempio mostrerà come il concetto di flusso di lavoro agile può creare un grande valore. Questo è un esempio molto semplice che ha lo scopo di visualizzare questo concetto. Gli esempi di vita reale saranno molto meno ovvi, ma l'idea che vedrai qui è altrettanto rilevante.
Diamo un'occhiata a questi dati bidimensionali che ho simulato da tre classi di uguali dimensioni.
num_samples_A = 500
num_samples_B = 500
num_samples_C = 500# Class A
mean_A = (3, 2)
cov_A = ((0.1, 0), (0, 0.1)) # Low variance
class_A = np.random.multivariate_normal(mean_A, cov_A, num_samples_A)
# Class B
mean_B = (0, 0)
cov_B = ((1, 0.5), (0.5, 1)) # Larger variance with some overlap with class C
class_B = np.random.multivariate_normal(mean_B, cov_B, num_samples_B)
# Class C
mean_C = (0, 1)
cov_C = ((2, 0.5), (0.5, 2)) # Larger variance with some overlap with class B
class_C = np.random.multivariate_normal(mean_C, cov_C, num_samples_C)
Ora proviamo ad adattare un classificatore di apprendimento automatico a questi dati, sembra che un classificatore SVM con un kernel gaussiano (“rbf”) potrebbe fare il trucco:
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC# Creating DataFrame
data = np.concatenate((class_A, class_B, class_C))
labels = np.concatenate((np.zeros(num_samples_A), np.ones(num_samples_B), np.ones(num_samples_C) * 2))
df = pd.DataFrame(data, columns=('x', 'y'))
df('label') = labels.astype(int)
# Splitting data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(df(('x', 'y')), df('label'), test_size=0.2, random_state=42)
# Training SVM model with RBF kernel
svm_rbf = SVC(kernel='rbf', probability= True)
svm_rbf.fit(X_train, y_train)
# Predict probabilities for each class
svm_rbf_probs = svm_rbf.predict_proba(X_test)
# Get predicted classes and corresponding confidences
svm_rbf_predictions = ((X_test.iloc(i)('x'), X_test.iloc(i)('y'), true_class, np.argmax(probs), np.max(probs)) for i, (true_class, probs) in enumerate(zip(y_test, svm_rbf_probs)))
svm_predictions_df = pd.DataFrame(svm_rbf_predictions).rename(columns={0:'x',1:'y' ,2: 'true_class', 3: 'predicted_class', 4: 'confidence'})
Come si comporta questo modello sui nostri dati?
accuracy = (svm_predictions_df('true_class') == svm_predictions_df('predicted_class')).mean()*100
print(f'Accuracy = {round(accuracy,2)}%')
Precisione = 75,33%
Una precisione del 75% è deludente, ma questo significa che questo modello è inutile?
Ora vogliamo esaminare le previsioni più attendibili e vedere come si comporta il modello su di esse. Come definiamo le previsioni più attendibili? Possiamo provare diverse soglie di confidenza (predict_proba) e vedere quale copertura e precisione otteniamo per ciascuna soglia e quindi decidere quale soglia soddisfa le nostre esigenze aziendali.
thresholds = (.5, .55, .6, .65, .7, .75, .8, .85, .9)
results = ()for threshold in thresholds:
svm_df_covered = svm_predictions_df.loc(svm_predictions_df('confidence') > threshold)
coverage = len(svm_df_covered) / len(svm_predictions_df) * 100
accuracy_covered = (svm_df_covered('true_class') == svm_df_covered('predicted_class')).mean() * 100
results.append({'Threshold': threshold, 'Coverage (%)': round(coverage,2), 'Accuracy on covered data (%)': round(accuracy_covered,2)})
results_df = pd.DataFrame(results)
print(results_df)
E otteniamo
Oppure, se desideriamo uno sguardo più dettagliato, possiamo creare un grafico della copertura e dell'accuratezza per soglia:
Ora possiamo selezionare la soglia che si adatta alla nostra logica aziendale. Ad esempio, se la politica della nostra azienda è garantire almeno il 90% di precisione, allora possiamo scegliere una soglia di 0,75 e ottenere una precisione del 90% per il 62% dei dati. Questo è un enorme miglioramento rispetto all'eliminazione del modello, soprattutto se non ne abbiamo alcuno in produzione!
Ora che il nostro modello funziona felicemente in produzione sul 60% dei dati, possiamo spostare la nostra attenzione sul resto dei dati. Possiamo raccogliere più dati, progettare più funzionalità, provare modelli più complessi o ottenere assistenza da un esperto di dominio.
Fonte: towardsdatascience.com