मैं एक तंत्रिका नेटवर्क को लागू कर रहा हूं और मैं क्रॉस सत्यापन के साथ इसके प्रदर्शन का आकलन करना चाहता हूं। यहाँ मेरा वर्तमान कोड है:

def recall_m(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    recall = true_positives / (possible_positives + K.epsilon())
    return recall

def precision_m(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision

def f1_m(y_true, y_pred):
    precision = precision_m(y_true, y_pred)
    recall = recall_m(y_true, y_pred)
    return 2*((precision*recall)/(precision+recall+K.epsilon()))

def build_model():
    hiddenLayers = 1
    neurons = 100
    #hidden_neurons = int(train_x.shape[0]/(3*(neurons+1)))
    hidden_neurons = 500
    opt = optimizers.Adam(learning_rate=0.00005, amsgrad=False)

    model = Sequential()
    model.add(Dense(units=neurons, activation="relu", input_shape=(15,)))

    model.add(Dense(units=2*hidden_neurons, activation="relu", input_shape=(18632,)))

    model.add(Dense(units=4, activation="softmax"))

    model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['acc',f1_m,precision_m, recall_m])
    return model

x = df[['start-sin', 'start-cos', 'start-sin-lag', 'start-cos-lag', 'prev-close-sin', 'prev-close-cos', 'prev-length', 'state-lag', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']]
y = df[['wait-categ-none', 'wait-categ-short', 'wait-categ-medium', 'wait-categ-long']]
print(y)
#enforce, this is gone wrong somewhere
y = y.replace(False, 0)
y = y.replace(True, 1)

ep = 1

#fit = model.fit(train_x, train_y, epochs=ep, verbose=1)

#pred = model.predict(test_x)

#loss, accuracy, f1_score, precision, recall = model.evaluate(test_x, test_y, verbose=0)
classifier = KerasClassifier(build_fn=build_model, batch_size=10, epochs=ep)
accuracies = cross_val_score(estimator=classifier, X=x, y=y, cv=10, scoring="f1_macro", verbose=5)

मैं cross_val_score का उपयोग कर रहा हूं और सटीकता से फ़ंक्शन में ही एक अलग मीट्रिक का उपयोग करने का प्रयास किया है लेकिन मुझे त्रुटि मिलती है

ValueError: वर्गीकरण मेट्रिक्स मल्टीलेबल-इंडिकेटर और बाइनरी टारगेट के मिश्रण को हैंडल नहीं कर सकता

और यहां पढ़ें भ्रम मैट्रिक्स त्रुटि "वर्गीकरण मेट्रिक्स कर सकते हैं 'मल्टीलेबल-इंडिकेटर और मल्टीक्लास टारगेट' के मिश्रण को हैंडल नहीं कर सकता" कि मुझे स्कोरिंग से पहले आउटपुट को अन-वन हॉट एन्कोड करना होगा, लेकिन मुझे इस फ़ंक्शन के साथ ऐसा करने का कोई तरीका नहीं मिला।

क्या पूरी प्रक्रिया को स्वयं लिखने की तुलना में एकाधिक स्कोरिंग लागू करने का कोई बेहतर तरीका है? जैसा कि आप देख सकते हैं कि मेरे पास पहले से ही स्कोरिंग लागू है और वे प्रशिक्षण के दौरान अपेक्षित रूप से काम करते हैं, लेकिन मैं cross_val_score के कारण जानकारी नहीं निकाल सकता

संपादित करें:

मैंने निम्नलिखित कोड के साथ केवल एक पुनरावृत्ति चलाई है:

train, test = train_test_split(df, test_size=0.1, shuffle=True)

train_x = train[['start-sin', 'start-cos', 'start-sin-lag', 'start-cos-lag', 'prev-close-sin', 'prev-close-cos', 'prev-length', 'state-lag', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']]
train_y = train[['wait-categ-none', 'wait-categ-short', 'wait-categ-medium', 'wait-categ-long']]
test_x = test[['start-sin', 'start-cos', 'start-sin-lag', 'start-cos-lag', 'prev-close-sin', 'prev-close-cos', 'prev-length', 'state-lag', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']]
test_y = test[['wait-categ-none', 'wait-categ-short', 'wait-categ-medium', 'wait-categ-long']]
test_y = test_y.replace(False, 0).replace(True,1)
train_y = train_y.replace(False, 0).replace(True,1)

ep = 500
model = build_model()
print("Train y")
print(train_y)
print("Test y")
print(test_y)
model.fit(train_x, train_y, epochs=1, verbose=1)
pred = model.predict(test_x)
print(pred)
loss, accuracy, f1_score, precision, recall = model.evaluate(test_x, test_y, verbose=0)

यह निम्नलिखित आउटपुट देता है:

ट्रेन यू

       wait-categ-none  wait-categ-short  wait-categ-medium  wait-categ-long
4629                 1                 0                  0                0
7643                 0                 1                  0                0
4425                 0                 1                  0                0
10548                1                 0                  0                0
14180                1                 0                  0                0
...                ...               ...                ...              ...
13661                1                 0                  0                0
10546                1                 0                  0                0
1966                 1                 0                  0                0
5506                 0                 1                  0                0
10793                1                 0                  0                0

[15632 rows x 4 columns]

टेस्ट y

       wait-categ-none  wait-categ-short  wait-categ-medium  wait-categ-long
10394                0                 1                  0                0
3804                 0                 1                  0                0
15136                0                 1                  0                0
7050                 1                 0                  0                0
30                   0                 1                  0                0
...                ...               ...                ...              ...
12040                0                 1                  0                0
4184                 0                 1                  0                0
12345                1                 0                  0                0
12629                0                 1                  0                0
664                  1                 0                  0                0

[1737 rows x 4 columns]

महीनो

[[2.63620764e-01 5.09552181e-01 1.72765702e-01 5.40613122e-02]
 [5.40941073e-07 9.99827385e-01 1.72021420e-04 5.32279255e-11]
 [5.91083081e-05 9.97556090e-01 2.38463446e-03 1.01058276e-07]
 ...
 [2.69533932e-01 3.99731129e-01 2.22193986e-01 1.08540975e-01]
 [5.87045122e-03 9.67754781e-01 2.62637101e-02 1.11028130e-04]
 [2.32783407e-01 4.53738511e-01 2.31750652e-01 8.17274228e-02]]

मैंने आउटपुट की प्रतिलिपि बनाई है जैसा कि यह है।

1
peterxz 28 अप्रैल 2020, 23:33

3 जवाब

सबसे बढ़िया उत्तर

मैं @desertnaut के उत्तर के साथ प्रयोग कर रहा हूं, हालांकि क्योंकि मेरे पास एक बहु वर्ग की समस्या है, मुझे लूप के साथ ही नहीं बल्कि np.argmax() लाइन के साथ भी समस्याओं का अनुभव हुआ। गुगल करने के बाद मुझे इसे आसानी से हल करने का कोई तरीका नहीं मिला, इसलिए मैंने हाथ से सीवी लागू करने (इस उपयोगकर्ता की सलाह पर) समाप्त कर दिया। यह थोड़ा अधिक जटिल था क्योंकि मैं एक पांडा डेटाफ्रेम का उपयोग कर रहा हूं (और कोड को निश्चित रूप से आगे साफ किया जा सकता है) लेकिन यहां काम करने वाला कोड है:

ep = 120
df_split = np.array_split(df, 10)
test_part = 0
acc = []
f1 = []
prec = []
recalls = []
while test_part < 10:
    model = build_model()
    train_x = []
    train_y = []
    test_x = []
    test_y = []
    print("CV Fold, with test partition i = " , test_part)

    for i in range(10):
        #on first iter that isnt a test part then set the train set to this 
        if len(train_x) == 0 and not i == test_part:
            train_x = df_split[i][['start-sin', 'start-cos', 'start-sin-lag', 'start-cos-lag', 'prev-close-sin', 'prev-close-cos', 'prev-length', 'state-lag', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']]
            train_y = df_split[i][['wait-categ-none', 'wait-categ-short', 'wait-categ-medium', 'wait-categ-long']]
            #terminate immediately
            continue
        #if current is not a test partition then concat with previous version
        if not i == test_part:
            train_x = pd.concat([train_x, df_split[i][['start-sin', 'start-cos', 'start-sin-lag', 'start-cos-lag', 'prev-close-sin', 'prev-close-cos', 'prev-length', 'state-lag', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']]], axis=0)
            train_y = pd.concat([train_y, df_split[i][['wait-categ-none', 'wait-categ-short', 'wait-categ-medium', 'wait-categ-long']]], axis=0)

        #set this to test partition
        else:
            test_x = df_split[i][['start-sin', 'start-cos', 'start-sin-lag', 'start-cos-lag', 'prev-close-sin', 'prev-close-cos', 'prev-length', 'state-lag', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']]
            test_y = df_split[i][['wait-categ-none', 'wait-categ-short', 'wait-categ-medium', 'wait-categ-long']]
    #enforce
    train_y = train_y.replace(False, 0)
    train_y = train_y.replace(True, 1)
    test_y = test_y.replace(False, 0)
    test_y = test_y.replace(True, 1)
    #fit
    model.fit(train_x, train_y, epochs=ep, verbose=1)
    pred = model.predict(test_x)
    #score
    loss, accuracy, f1_score, precision, recall = model.evaluate(test_x, test_y, verbose=0)
    #save
    acc.append(accuracy)
    f1.append(f1_score)
    prec.append(precision)
    recalls.append(recall)
    test_part += 1
print("CV finished.\n")

print("Mean Accuracy")
print(sum(acc)/len(acc))
print("Mean F1 score")
print(sum(f1)/len(f1))
print("Mean Precision")
print(sum(prec)/len(prec))
print("Mean Recall rate")
print(sum(recalls)/len(recalls))
0
peterxz 2 मई 2020, 18:46

cross_val_score यहां उपयुक्त टूल नहीं है; आपको अपनी सीवी प्रक्रिया पर मैन्युअल नियंत्रण रखना चाहिए। आपके द्वारा लिंक किए गए SO थ्रेड में मेरे उत्तर के पहलुओं के साथ-साथ प्रत्येक डेटा विभाजन के लिए स्किकिट-लर्न में क्रॉस-सत्यापन मीट्रिक, और सटीकता का उपयोग केवल एक उदाहरण मीट्रिक के रूप में:

from sklearn.model_selection import KFold
from sklearn.metrics import accuracy_score
import numpy as np

n_splits = 10
kf = KFold(n_splits=n_splits, shuffle=True)
cv_acc = []

# prepare a single-digit copy of your 1-hot encoded true labels:
y_single = np.argmax(y, axis=1)

for train_index, val_index in kf.split(x):
    # fit & predict
    model = KerasClassifier(build_fn=build_model, batch_size=10, epochs=ep)
    model.fit(x[train_index], y[train_index])
    pred = model.predict_classes(x[val_index]) # predicts single-digit classes

    # get fold accuracy & append
    fold_acc = accuracy_score(y_single[val_index], pred)
    cv_acc.append(fold_acc)

acc = mean(cv_acc)

लूप के पूरा होने पर, आपके पास सूची cv_acc में प्रत्येक तह की सटीकता होगी, और माध्य लेने से आपको औसत मूल्य मिलेगा।

इस तरह, आपको सटीक, स्मरण, और f1 के लिए आपके द्वारा उपयोग की जाने वाली कस्टम परिभाषाओं की आवश्यकता नहीं है; आप केवल scikit-learn से संबंधित लोगों का उपयोग कर सकते हैं। आप लूप में जितने चाहें उतने अलग मेट्रिक्स जोड़ सकते हैं (कुछ ऐसा जो आप cross_cal_score के साथ नहीं कर सकते), जब तक कि आप उन्हें scikit-learn से उचित रूप से आयात करते हैं जैसा कि यहां accuracy_score के साथ किया गया है।

1
desertnaut 29 अप्रैल 2020, 01:05

किसी भी व्यक्ति के लिए जो अभी भी एक-हॉट एन्कोडेड लेबल के साथ cross_validate का उपयोग करना चाहता है। इसके बारे में जाने के लिए यह एक अधिक विज्ञान उन्मुख तरीका है।

X, y = get_data()
# in my application I have words as labels, so y is a np.array with strings
encoder = LabelEncoder()
y_encoded = encoder.fit_transform(y)

# build a version of the scoring metrics for multi-class and one-hot encoding predictions
labels = sorted(set(np.unique(y_encoded)) - set(encoder.transform(['nan'])))

# these functions compare y (one-hot encoded) to y_pred (integer encoded)
# by making y integer encoded as well

def f1_categorical(y, y_pred, **kwargs):
    return f1_score(y.argmax(1), y_pred, **kwargs)

def precision_categorical(y, y_pred, **kwargs):
    return precision_score(y.argmax(1), y_pred, **kwargs)

def recall_categorical(y, y_pred, **kwargs):
    return recall_score(y.argmax(1), y_pred, **kwargs)

def accuracy_categorical(y, y_pred, **kwargs):
    return accuracy_score(y.argmax(1), y_pred, **kwargs)

# Wrap the functions abobe with `make_scorer` 
# (here I chose the micro average because it worked for my multi-class application)
our_f1 = make_scorer(f1_categorical, labels=labels, average="micro")
our_precision = make_scorer(precision_categorical, labels=labels, average="micro")
our_recall = make_scorer(recall_categorical, labels=labels, average="micro")
aur_accuracy = make_scorer(accuracy_categorical)
scoring = {
    'accuracy':aur_accuracy,
    'f1':our_f1,
    'precision':our_precision,
    'recall':our_recall
}

# one-hot encoding
y_categorical = tf.keras.utils.to_categorical(y_encoded)

# keras wrapper
estimator = tf.keras.wrappers.scikit_learn.KerasClassifier(
                build_fn=model_with_one_hot_encoded_output,
                epochs=1,
                batch_size=32,
                verbose=1)

# cross validate as usual
results = cross_validate(estimator, 
                         X_scaled, y_categorical, 
                         scoring=scoring)
0
torresmateo 1 अगस्त 2020, 06:25