Как отладить неправильные прогнозы при использовании TfidfVectorizer и RandomForestClassifier - PullRequest
0 голосов
/ 01 августа 2020

У меня есть небольшой набор данных, с помощью которого я пытаюсь предсказать store_id (y) для данного элемента (X). Например, я ожидал store_id (62) при поиске SHARP TV, но я получаю store_id (74), соответствующий item = «Roller Bru sh».

Я просмотрел данные обучения, созданные после вызова файл TfidfVectorizer.fit_transform (X). Он имеет tf_idf для «Roller Bru sh» = 0,57735 и для «SHARP TV» = 0,40248.

Затем я попытался применить (преобразовать) векторизатор к элементу поиска = «SHARP TV», и Я вижу, что преобразованные данные имеют нули для всех строк, кроме «SHARP», «SHARP TV» и «TV» со значением 0,57735 (что соответствует значению Tfidf, которое я видел в обучающем наборе для Roller bru sh). Это причина, по которой был предсказан store_id (74), соответствующий Roller bru sh?

Проблема наблюдается даже с большим набором данных, поэтому я уменьшил размер набора данных, чтобы помочь с проверкой данных / устранением неполадок.

Есть идеи, как я должен устранять такие проблемы?

Набор данных и значение tf-idf в обучающем наборе набор данных

Прогнозируемые данные Прогнозные данные

** Код **

#
# Given an item (X), predict the store_id(y) to find the item
# dataset is past purchases of item and store_id
#
import pandas as pd
from sklearn.model_selection import train_test_split
import re     # librarie for cleaning data
import nltk   # library for NLP
from nltk.corpus import stopwords
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.ensemble import RandomForestClassifier

#nltk.download('stopwords', quiet=True, raise_on_error=True)
#nltk.download('punkt')

tokenized_stop_words = stopwords.words('english')
stemmer=nltk.PorterStemmer()
stemmed_words = [stemmer.stem(word) for word in tokenized_stop_words]

all_stopwords = stopwords.words('english')
 
def stop_words(str_input):
   word_list = str_input.apply(lambda x: [item for item in x if item not in all_stopwords])
   return word_list

def Tokenizer(str_input):
    words = re.sub(r"[^A-Za-z0-9\-]", " ", str_input).lower().split()
    porter_stemmer=nltk.PorterStemmer()
    words = [porter_stemmer.stem(word) for word in words]
    return words

df=pd.read_csv("data_least.txt", sep='\t')

X=df.loc[:,['ITEM']]
y=df.loc[:,['STORE_ID']]

vectorizer=TfidfVectorizer(sublinear_tf=True, tokenizer=Tokenizer, stop_words=stemmed_words,
                     min_df=.0025, max_df=0.5, ngram_range=(1,3))
tf_idf = vectorizer.fit_transform(X['ITEM'])
vectorized_X = pd.DataFrame(tf_idf.toarray(), columns=vectorizer.get_feature_names())
X_train, X_test, y_train, y_test = train_test_split(vectorized_X, y, test_size=0.30)

#
classifier=RandomForestClassifier(n_estimators=100, max_depth=2,
                                  random_state=0)
model = classifier.fit(X_train,y_train.values.ravel())

# Predict for test data
y_pred=model.predict(X_test) 
from sklearn.metrics import accuracy_score
acc= accuracy_score(y_test,y_pred)

print('Accuracy = '+str(acc))  

######### Prediction a new test data ##########
#Item=SHARP TV   ; Expected Store_Id=62
item='SHARP TV'
data={'ITEM': [item]} 
# Transform the new data ('SHARP TV') using the vectorizer
# used for the train-=test data, earlier
tf_idf = vectorizer.transform(data['ITEM'])
pred_data = pd.DataFrame(tf_idf.toarray(), columns=vectorizer.get_feature_names())
prediction=model.predict(pred_data)  

print("Input Item = "+  item)
print("==== Predicted Storeid="+ str(prediction) + " Expected Store id = 62 ")
...