2017-11-26 15 views
0

다음 코드를 사용하여 스포츠, 정치 및 돈의 세 가지 카테고리로 문서를 분류하고 있습니다. 나는이 코드가 정밀 리콜과 F1을 계산한다는 것을 알 수있다. 그러나이 코드를 사용하여 사용자 지정 문서에 대한 테스트를 통해 해당 레이블을 예측할 수있는 방법을 찾을 수 없습니다.Python3 : 로이터를 이용한 다중 라벨 텍스트 분류 21578 데이터 세트

from nltk.corpus import stopwords, reuters 
from nltk import word_tokenize 
from nltk.stem.porter import PorterStemmer 
import re 

from sklearn.feature_extraction.text import TfidfVectorizer 
from sklearn.preprocessing import MultiLabelBinarizer 
from sklearn.svm import LinearSVC 
from sklearn.multiclass import OneVsRestClassifier 
from sklearn.metrics import f1_score, precision_score, recall_score 

cachedStopWords = stopwords.words("english") 
def tokenize(text): 
    min_length = 3 
    words = map(lambda word: word.lower(), word_tokenize(text)) 
    words = [word for word in words if word not in cachedStopWords] 
    tokens = (list(map(lambda token: PorterStemmer().stem(token),words))) 
    p = re.compile('[a-zA-Z]+'); 
    filtered_tokens = list(filter (lambda token: p.match(token) and len(token) >= min_length,tokens)) 
    return filtered_tokens 

def represent(documents, representer): 
    train_docs_id = list(filter(lambda doc: doc.startswith("train"), documents)) 
    test_docs_id = list(filter(lambda doc: doc.startswith("test"), documents)) 

    train_docs = [reuters.raw(doc_id) for doc_id in train_docs_id] 
    test_docs = [reuters.raw(doc_id) for doc_id in test_docs_id] 

    # Learn and transform train documents 
    vectorised_train_documents = representer.fit_transform(train_docs) 
    vectorised_test_documents = representer.transform(test_docs) 

    # Transform multilabel labels 
    mlb = MultiLabelBinarizer() 
    train_labels = mlb.fit_transform([reuters.categories(doc_id) for doc_id in train_docs_id]) 
    test_labels = mlb.transform([reuters.categories(doc_id) for doc_id in test_docs_id]) 

    return (vectorised_train_documents, train_labels, vectorised_test_documents, test_labels) 

def evaluate(test_labels, predictions): 
    precision = precision_score(test_labels, predictions, average='micro') 
    recall = recall_score(test_labels, predictions, average='micro') 
    f1 = f1_score(test_labels, predictions, average='micro') 
    print("Micro-average quality numbers") 
    print("Precision: {:.4f}, Recall: {:.4f}, F1-measure: {:.4f}".format(precision, recall, f1)) 

    precision = precision_score(test_labels, predictions, average='macro') 
    recall = recall_score(test_labels, predictions, average='macro') 
    f1 = f1_score(test_labels, predictions, average='macro') 

    print("Macro-average quality numbers") 
    print("Precision: {:.4f}, Recall: {:.4f}, F1-measure: {:.4f}".format(precision, recall, f1)) 

documents = reuters.fileids() 
candidate = {'representer': TfidfVectorizer(tokenizer=tokenize), 
      'estimator': OneVsRestClassifier(LinearSVC(random_state=42))} 
train_docs, train_labels, test_docs, test_labels = represent(documents, candidate['representer']) 
candidate['estimator'].fit(train_docs, train_labels) 
predictions = candidate['estimator'].predict(test_docs) 
evaluate(test_labels, predictions) 

크레딧 : https://github.com/miguelmalvarez/reuters-tc/blob/master/notebook/Classification_Reuters.ipynb

+0

아래 코드가 효과가 있습니까? – oldmonk

+0

예. 도움을 주셔서 감사합니다 –

+0

하지만 라벨 목록이 이상합니다. 그것은 참조하고있는 문서를 말하지 않고 무작위로 레이블을 제공합니다. 그래서 한 번에 하나의 문서를 사용하고 있습니다. –

답변

0

당신은 폴더에 텍스트 파일로 사용자 정의 문서를 저장할 수는 yourfolder 말할 수 있습니다. 그런 다음 아래 코드를 사용하여 로이터 데이터를 학습하고 텍스트 문서의 레이블을 예측할 수 있습니다. all_labels에는 각 문서의 예상 레이블 목록 (튜플로) 목록이 포함됩니다.

import os 


classifier=OneVsRestClassifier(LinearSVC(random_state=42)) 
vectorizer=TfidfVectorizer(tokenizer=tokenize) 

#LOAD AND TRANSFORM TRAINING DOCS 
documents = reuters.fileids() 
train_docs_id = list(filter(lambda doc: doc.startswith("train"), documents)) 

train_docs = [reuters.raw(doc_id) for doc_id in train_docs_id] 
vectorised_train_documents = vectorizer.fit_transform(train_docs) 
mlb = MultiLabelBinarizer() 
train_labels = mlb.fit_transform([reuters.categories(doc_id) for doc_id in train_docs_id]) 

#LEARN CLASSIFICATION MODEL 
classifier=classifier.fit(vectorised_train_documents, train_labels) 


#LOAD AND TRANSFORM TEST DOCS 
documents_yours=os.listdir('yourfoldername') 
test_docs_yours = [open('yourfoldername/'+doc_id).read() for doc_id in documents_yours] 
vectorised_test_documents_yours = vectorizer.transform(test_docs_yours) 


#MAKEPREIDCTIONS 
predictions_yours=classifier.predict(vectorised_test_documents_yours) 
all_labels = mlb.inverse_transform(predictions_yours) 
all_labels