Хорошо, здесь есть пара вопросов. У меня есть полный рабочий пример ниже, но сначала эти проблемы. В основном утверждение, что «Это правильно дает« NaN »для первых 2 строк».
Это связано с тем, как используются алгоритмы классификации и что они могут делать. Данные обучения содержат всю информацию, которую вы хотите, чтобы ваш алгоритм знал и мог действовать. Тестовые данные будут обрабатываться только с учетом этой информации. Даже если вы (человек) знаете, что метка теста 5
и не включена в данные обучения, алгоритм не знает этого. Он только собирается посмотреть на данные объекта и затем попытаться предсказать метку из них. Таким образом, он не может возвратить nan
(или 5
, или что-либо, отсутствующее в обучающем наборе) - что nan
исходит от вашей работы, переходя от df_R
до df_S
.
Это приводит ко второй проблеме - строке df_Te_Y = TEST .iloc[ : , 1 : ]
, эта строка должна быть df_Te_Y = TEST .iloc[ : , 2 : ]
, чтобы она не включала данные метки. Данные метки появляются только в тренировочном наборе. Предсказанные метки будут извлечены только из набора меток, которые появляются в обучающих данных.
Примечание: я изменил метки классов на Y
, а данные объектов на X
, потому что это стандартно в литературе.
from sklearn.naive_bayes import BernoulliNB
from sklearn.metrics import accuracy_score
import pandas as pd
BNB = BernoulliNB()
# Training Data
train_df = pd.DataFrame({'Y' : [1,2,3,9], 'X1': [1,1,0,0], 'X2': [0,0,0,0], 'X3': [0,0,0,0], 'X4': [1,0,0,0]})
# Test Data
test_df = pd.DataFrame({'Y' : [5,0,1,1,1,2,2,2,2],
'X1': [1,1,0,1,0,1,0,0,0],
'X2': [1,0,1,0,1,0,1,0,1],
'X3': [1,1,0,1,1,0,0,0,0],
'X4': [1,1,0,1,1,0,0,0,0]})
X = train_df.drop('Y', axis=1) # Known training data - all but 'Y' column.
Y = train_df['Y'] # Known training labels - just the 'Y' column.
X_te = test_df.drop('Y', axis=1) # Test data.
Y_te = test_df['Y'] # Only used to measure accuracy of prediction - if desired.
Ar_R = BNB.fit(X, Y).predict_proba(X_te) # Can be combined to a single line.
df_R = pd.DataFrame(Ar_R)
df_R.columns = BNB.classes_ # Rename as per class labels.
# Columns are class labels and Rows are observations.
# Each entry is a probability of that observation being assigned to that class label.
print(df_R)
predicted_labels = df_R.idxmax(axis=1).values # For each row, take the column with the highest prob in that row.
print(predicted_labels) # [1 1 3 1 3 2 3 3 3]
print(accuracy_score(Y_te, predicted_labels)) # Percent accuracy of prediction.
print(BNB.fit(X, Y).predict(X_te)) # [1 1 3 1 3 2 3 3 3], can be used in one line if predicted_label is all we want.
# NOTE: change train_df to have 'Y': [1,2,1,9] and we get predicted_labels = [1 1 9 1 1 1 9 1 9].
# So probabilities have changed.
Я рекомендую просмотреть некоторые учебные пособия или другие материалы по алгоритмам кластеризации, если это не имеет смысла после прочтения кода.