Альтернативный способ переполнения фрейма данных с предсказаниями модели классификации, когда вы закончите тестирование? - PullRequest
0 голосов
/ 11 мая 2018

Как только вы будете удовлетворены результатами вашей модели классификации, какую альтернативу вы можете порекомендовать сопоставить значения прогноза с их текстовой формой?Классификационная модель была создана с использованием scikit.

Что я делал, так это просто инвертировал словарь, а затем переназначал, см. Ниже.

d={'Reported Harms':['Fell','Constipation','Surgical Delay'],'Complaint Description':['Patient Fell on face','Could not use bathroom','Medical rep was late']}
df=pd.DataFrame(data=d)

harms=df["Reported Harms"].unique()
harms_dict={value:index for index, value in enumerate(harms)}
results=df["Reported Harms"].map(harms_dict)

df['prediction']=[0,1,2]

inv_map={v:k for k, v in harms_dict.items()}
df["prediction"]=df["prediction"].map(inv_map)

Спасибо

Как некоторые просиличтобы увидеть модель,

import matplotlib.pyplot as plt
import pandas as pd

from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
import seaborn as sns

from sklearn.feature_extraction.text import CountVectorizer
vect=CountVectorizer(min_df=1)

df=pd.read_excel('Test_data.xlsx',sheet_name='Test')
dff=pd.read_excel('Data_input.xlsx',sheet_name='Complaints')

corpus=df["Complaint Description"]
vectorizer=CountVectorizer(min_df=1)
X=vectorizer.fit_transform(corpus).toarray()
print(X.shape)

harms=df["Reported Harms"].unique()
harms_dict={value:index for index, value in enumerate(harms)}
results=df["Reported Harms"].map(harms_dict)

x_train,x_test,y_train,y_test=train_test_split(X,results,test_size=1,random_state=1,)

clf=MultinomialNB()
clf.fit(x_train,y_train)
clf.score(x_test,y_test)


vec_text=vectorizer.transform(dff["Complaint Description"]).toarray()
ids=dff["Complaint Description"]
dff['prediction']=clf.predict(vec_text)

inv_map={v:k for k, v in harms_dict.items()}
dff["prediction"]=dff["prediction"].map(inv_map)
s=dff['prediction'].value_counts()
sns.barplot(x=s.index,y=s.values)

writer = pd.ExcelWriter('Legacy_list.xlsx')
dff.to_excel(writer, 'Complaints edit',index=False)
writer.save()

Ответы [ 3 ]

0 голосов
/ 11 мая 2018

Одним из распространенных подходов будет использование sklearn.preprocessing.LabelEncoder :

In [15]: from sklearn.preprocessing import LabelEncoder

In [18]: le = LabelEncoder()

In [19]: df['harms'] = le.fit_transform(df['Reported Harms'])

In [20]: df
Out[20]:
    Complaint Description  Reported Harms  harms
0    Patient Fell on face            Fell      1
1  Could not use bathroom    Constipation      0
2    Medical rep was late  Surgical Delay      2

In [21]: df['decoded'] = le.inverse_transform(df['harms'])
C:\Users\Max\Anaconda3_5.0\envs\py36\lib\site-packages\sklearn\preprocessing\label.py:151: DeprecationWarning: The truth value of an empty array is ambiguous. R
eturning False, but in future this will result in an error. Use `array.size > 0` to check that an array is not empty.
  if diff:

In [22]: df
Out[22]:
    Complaint Description  Reported Harms  harms         decoded
0    Patient Fell on face            Fell      1            Fell
1  Could not use bathroom    Constipation      0    Constipation
2    Medical rep was late  Surgical Delay      2  Surgical Delay
0 голосов
/ 11 мая 2018

В вашем примерном фрейме данных вы можете просто опустить отображение Harms на части int, которые будут автоматически обрабатываться оценщиками Scikit (MultinomialNB в вашем случае).

Что вы можете сделать так:

d={'Reported Harms':['Fell','Constipation','Surgical Delay'],
   'Complaint Description':['Patient Fell on face','Could not use bathroom','Medical rep was late']}
df=pd.DataFrame(data=d)

# Convert the text features to numerical
corpus=df["Complaint Description"]
vectorizer=CountVectorizer(min_df=1)
X = vectorizer.fit_transform(corpus).toarray()


# No need to do anything to target classes
results = df["Reported Harms"]

# Now continue with your code

clf=MultinomialNB()

# You can directly do this (or continue with train_test_split as you originally had)
clf.fit(X, results)

А теперь для прогнозов, когда вы делаете clf.predict(), исходные тексты будут возвращаться автоматически.

d={'Reported Harms':['Surgical Delay', 'Constipation', 'Fell'], 
   'Complaint Description':['Ambulance arrived late', 'Having problems passing urine in bathroom', 'Fell on road',]}
dff = pd.DataFrame(data=d)

vec_text=vectorizer.transform(dff["Complaint Description"]).toarray()
ids=dff["Complaint Description"]
predictions = clf.predict(vec_text)

print(predictions)
# Output: 
          array(['Surgical Delay', 
                 'Constipation', 
                 'Fell'], dtype='|S14')

, которые вы можете напрямую назначить кадру данных без какого-либо сопоставления или обратного сопоставления.

dff['prediction'] = predictions

Хитрость в том, что оценщики Scikit автоматически преобразуют предоставленные текстовые цели в числовые, используя внутренний кодировщик LabelEncoder, как предложено @MaxU в его ответе, поэтому вам не нужно делать это явно.

Надеюсь, это прояснит.

0 голосов
/ 11 мая 2018

pd.factorize на помощь:

i, j = pd.factorize(df['Reported Harms'])
# Transform
df['encoded'] = i
# Inverse Transform
mapping = dict(zip(j, i))
df["decoded"] = df['encoded'].map(mapping)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...