2016-05-06 6 views
0

Ich habe einen Gaussian Naive Bayes-Klassifikator in einem E-Mail (Spam/nicht Spam) -Datensatz erstellt und konnte ihn erfolgreich ausführen. Ich vektorisiert die Daten, unterteilt sie in Zug- und Testsätze und berechnet dann die Genauigkeit, alle Merkmale, die im Sklearn-Gaußschen Naive Bayes-Klassifikator vorhanden sind.Wie kann ich das Label einer E-Mail mit einem trainierten NB-Klassifikator in sklearn vorhersagen?

Jetzt möchte ich in der Lage sein, diesen Klassifikator zu verwenden, um "Etiketten" für neue E-Mails zu prognostizieren - ob sie durch Spam oder nicht sind. Zum Beispiel sagen, ich habe eine E-Mail. Ich möchte es meinem Klassifizierer zuführen und die Vorhersage erhalten, ob es ein Spam ist oder nicht. Wie kann ich das erreichen? Bitte Hilfe.

Code für die Klassifizierungsdatei.

#!/usr/bin/python 
 

 
import sys 
 
from time import time 
 
import logging 
 

 
# Display progress logs on stdout 
 
logging.basicConfig(level = logging.DEBUG, format = '%(asctime)s %(message)s') 
 

 
sys.path.append("../DatasetProcessing/") 
 
from vectorize_split_dataset import preprocess 
 

 
### features_train and features_test are the features 
 
for the training and testing datasets, respectively### labels_train and labels_test are the corresponding item labels 
 
features_train, features_test, labels_train, labels_test = preprocess() 
 

 
######################################################### 
 
from sklearn.naive_bayes import GaussianNB 
 
clf = GaussianNB() 
 
t0 = time() 
 
clf.fit(features_train, labels_train) 
 
pred = clf.predict(features_test) 
 
print("training time:", round(time() - t0, 3), "s") 
 
print(clf.score(features_test, labels_test)) 
 

 
## Printing Metrics 
 
for Training and Testing 
 
print("No. of Testing Features:" + str(len(features_test))) 
 
print("No. of Testing Features Label:" + str(len(labels_test))) 
 
print("No. of Training Features:" + str(len(features_train))) 
 
print("No. of Training Features Label:" + str(len(labels_train))) 
 
print("No. of Predicted Features:" + str(len(pred))) 
 

 
## Calculating Classifier Performance 
 
from sklearn.metrics import classification_report 
 
y_true = labels_test 
 
y_pred = pred 
 
labels = ['0', '1'] 
 
target_names = ['class 0', 'class 1'] 
 
print(classification_report(y_true, y_pred, target_names = target_names, labels = labels)) 
 

 
# How to predict label of a new text 
 
new_text = "You won a lottery at UK lottery commission. Reply to claim it"

-Code für Vektorisierung

#!/usr/bin/python 
 

 
import os 
 
import pickle 
 
import numpy 
 
numpy.random.seed(42) 
 

 
path = os.path.dirname(os.path.abspath(__file__)) 
 

 
### The words(features) and label_data(labels), already largely processed.###These files should have been created beforehand 
 
feature_data_file = path + "./createdDataset/dataSet.pkl" 
 
label_data_file = path + "./createdDataset/dataLabel.pkl" 
 

 
feature_data = pickle.load(open(feature_data_file, "rb")) 
 
label_data = pickle.load(open(label_data_file, "rb")) 
 

 
### test_size is the percentage of events assigned to the test set(the### remainder go into training)### feature matrices changed to dense representations 
 
for compatibility with### classifier functions in versions 0.15.2 and earlier 
 
from sklearn import cross_validation 
 
features_train, features_test, labels_train, labels_test = cross_validation.train_test_split(feature_data, label_data, test_size = 0.1, random_state = 42) 
 

 
from sklearn.feature_extraction.text import TfidfVectorizer 
 
vectorizer = TfidfVectorizer(sublinear_tf = True, max_df = 0.5, stop_words = 'english') 
 
features_train = vectorizer.fit_transform(features_train) 
 
features_test = vectorizer.transform(features_test)#.toarray() 
 

 
## feature selection to reduce dimensionality 
 
from sklearn.feature_selection import SelectPercentile, f_classif 
 
selector = SelectPercentile(f_classif, percentile = 5) 
 
selector.fit(features_train, labels_train) 
 
features_train_transformed_reduced = selector.transform(features_train).toarray() 
 
features_test_transformed_reduced = selector.transform(features_test).toarray() 
 

 
features_train = features_train_transformed_reduced 
 
features_test = features_test_transformed_reduced 
 

 
def preprocess(): 
 
    return features_train, features_test, labels_train, labels_test

-Code für Daten-Set Generation

#!/usr/bin/python 
 

 
import os 
 
import pickle 
 
import re 
 
import sys 
 

 
# sys.path.append("../tools/") 
 

 

 
"" 
 
" 
 
    Starter code to process the texts of accuate and inaccurate category to extract 
 
    the features and get the documents ready for classification. 
 

 
    The list of all the texts from accurate category are in the accurate_files list 
 
    likewise for texts of inaccurate category are in (inaccurate_files) 
 

 
    The data is stored in lists and packed away in pickle files at the end. 
 
" 
 
"" 
 

 

 
accurate_files = open("./rawDatasetLocation/accurateFiles.txt", "r") 
 
inaccurate_files = open("./rawDatasetLocation/inaccurateFiles.txt", "r") 
 

 
label_data = [] 
 
feature_data = [] 
 

 
### temp_counter is a way to speed up the development--there are### thousands of lines of accurate and inaccurate text, so running over all of them### can take a long time### temp_counter helps you only look at the first 200 lines in the list so you### can iterate your modifications quicker 
 
temp_counter = 0 
 

 

 
for name, from_text in [("accurate", accurate_files), ("inaccurate", inaccurate_files)]: 
 
    for path in from_text: ###only look at first 200 texts when developing### once everything is working, remove this line to run over full dataset 
 
temp_counter = 1 
 
if temp_counter < 200: 
 
    path = os.path.join('..', path[: -1]) 
 
print(path) 
 
text = open(path, "r") 
 
line = text.readline() 
 
while line: ###use a 
 
function parseOutText to extract the text from the opened text# stem_text = parseOutText(text) 
 
stem_text = text.readline().strip() 
 
print(stem_text)### use str.replace() to remove any instances of the words# stem_text = stem_text.replace("germani", "")### append the text to feature_data 
 
feature_data.append(stem_text)### append a 0 to label_data 
 
if text is from Sara, and 1 
 
if text is from Chris 
 
if (name == "accurate"): 
 
    label_data.append("0") 
 
elif(name == "inaccurate"): 
 
    label_data.append("1") 
 

 
line = text.readline() 
 

 
text.close() 
 

 
print("texts processed") 
 
accurate_files.close() 
 
inaccurate_files.close() 
 

 
pickle.dump(feature_data, open("./createdDataset/dataSet.pkl", "wb")) 
 
pickle.dump(label_data, open("./createdDataset/dataLabel.pkl", "wb"))

Auch möchte ich wissen, ob ich den Klassifizierer inkrementell trainieren kann, was bedeutet, dass ein erstelltes Modell mit neueren Daten zur Verfeinerung des Modells über die Zeit neu trainiert wird?

Ich wäre wirklich froh, wenn mir jemand dabei helfen könnte. Ich bin wirklich an diesem Punkt fest.

+0

Wie Sie bereits den train_test Split auf einem bereits markierten Satz durchgeführt haben und dann die Genauigkeit berechnen. Für die neuen Testdaten müssten Sie Ihren neuen Testdatensatz in die Variable features_test laden. Für die Vorhersage können Sie zwei Dinge tun, entweder fit_transform Ihr NB jedes Mal, wenn Sie eine neue Testdaten haben, oder speichern Sie das NB-Modell (verwenden Sie sklearn.externals.joblib.dump/load, und für jeden neuen Test, laden Sie Ihr Modell und verwenden Sie können den Klassifikator inkrementell trainieren, aber der alte Klassifikator müsste ersetzt werden. – pmaniyan

Antwort

1

Sie verwenden Ihr Modell bereits zur Vorhersage von E-Mail-Etiketten in Ihrem Testset. Dies ist, was pred = clf.predict(features_test) tut. Wenn Sie diese Beschriftungen sehen möchten, tun Sie print pred.

Aber vielleicht Sie, was Sie wissen können, wie Sie Etiketten für E-Mails, die Sie in der Zukunft entdecken und die derzeit nicht in Ihrem Test-Set sind, vorhersagen können? Wenn dies der Fall ist, können Sie sich Ihre neue (n) E-Mail (s) als neues Testset vorstellen. Wie bei Ihrem vorherigen Test müssen Sie mehrere wichtige Verarbeitungsschritte für die Daten ausführen:

1) Zunächst müssen Sie Funktionen für Ihre neuen E-Mail-Daten generieren. Der Feature-Generierungsschritt ist in Ihrem Code oben nicht enthalten, muss aber auftreten.

2) Sie verwenden einen Tfidf-Vektorisierer, der eine Sammlung von Dokumenten in eine Matrix von Tfidf-Features konvertiert, die auf der Häufigkeit der Terme und der Häufigkeit der inversen Dokumente basiert. Sie müssen Ihre neuen E-Mail-Testfunktionsdaten über den Vektorizer bereitstellen, den Sie auf Ihre Trainingsdaten anpassen.

3) Dann müssen Ihre neuen E-Mail-Testfunktionsdaten die Dimensionalitätsreduktion durchlaufen, indem Sie dieselbe selector verwenden, die Sie in Ihre Trainingsdaten einfügen.

4) Schließlich, laufen Sie auf Ihren neuen Testdaten voraussagen. Verwenden Sie print pred, wenn Sie die neuen Etiketten anzeigen möchten.

Um auf Ihre letzte Frage über das iterative Umschulung Ihres Modells zu antworten, können Sie dies auf jeden Fall tun. Es kommt nur darauf an, eine Frequenz auszuwählen, ein Skript zu erstellen, das Ihren Datensatz mit eingehenden Daten erweitert, und dann alle Schritte von der Vorverarbeitung zur Tfidf-Vektorisierung, zur Reduzierung der Dimensionalität, zur Anpassung und Vorhersage erneut auszuführen.

+0

Danke für die Lösung Jason. Genau das habe ich versucht zu fragen. Wie man Funktionen für die neuen E-Mail-Daten generiert. Dort war ich Können Sie bitte ein wenig zu diesem Punkt? Vielen Dank im Voraus. – harshlal028

+0

Hi @ user2168281, alle Feature Engineering Schritte außerhalb des Codes, die Sie oben veröffentlicht, so ist es unmöglich zu sagen. Sie ziehen Ihre Feature-Daten hier " feature_data_file = Pfad + "./createdDataset/dataSet.pkl" 'und hier' feature_data = pickle.load (open (Feature_Daten_Datei, "rb")) '. Wenn Sie das Feature Engineering nicht selbst gemacht haben, müssen Sie mindestens den Quellcode aufspüren, um zu sehen was die Funktionen sind und wie sie gebaut wurden, damit Sie am Ende für neue Daten weiterarbeiten können. Entschuldigung, ich kann nicht mehr helfen. Wenn Sie den Quellcode für die Funktionserstellung finden, lassen Sie es uns wissen. – user6275647

+0

Ich sollte sagen, dass es möglich ist, dass die Feature-Daten tatsächlich nur der E-Mail-Text selbst ist und dass es der Tfidf-Vektorizer ist, der diese rohen E-Mail-Textdaten in Features umwandelt. Wenn dies der Fall ist, wird die Feature-Generierung für Ihre neuen E-Mail-Daten im oben genannten Tfidf-Schritt ausgeführt. Aber ich kann nicht mit Sicherheit sagen, da wir nicht wissen, wie "features_data" aussieht, nachdem es in diesem Schritt "importator_data = pickle.load (open (feature_data_file," rb "))' importiert wurde. – user6275647