Незначительные колебания в точности, используя перекрестную проверку KFold
Я тестирую проблему классификации по нескольким меткам, используя текстовые функции. Всего у меня 1503 текстовых документа. Моя модель показывает небольшие различия в результатах каждый раз, когда я запускаю скрипт вручную. Я не уверен, подходит ли мне моя модель или это нормально, так как я новичок.
http://zacstewart.com/2015/04/28/document-classification-with-scikit-learn.html
Я построил модель, используя точный сценарий, найденный в следующем блоге. Один из вариантов заключается в том, что я использую Linear SVC из scikit learn
Мой показатель точности варьируется от 89 до 90, а у Каппа от 87 до 88. Нужно ли вносить какие-то изменения, чтобы сделать его стабильным?
Это образец для 2 ручных прогонов
Total emails classified: 1503
F1 Score: 0.902158940397
classification accuracy: 0.902158940397
kappa accuracy: 0.883691169128
precision recall f1-score support
Arts 0.916 0.878 0.897 237
Music 0.932 0.916 0.924 238
News 0.828 0.876 0.851 242
Politics 0.937 0.900 0.918 230
Science 0.932 0.791 0.855 86
Sports 0.929 0.948 0.938 233
Technology 0.874 0.937 0.904 237
avg / total 0.904 0.902 0.902 1503
Second run
Total emails classified: 1503
F1 Score: 0.898181015453
classification accuracy: 0.898181015453
kappa accuracy: 0.879002051427
Ниже приведен код
def compute_classification():
#- 1. Load dataset
data = DataFrame({'text': [], 'class': []})
for path, classification in SOURCES:
data = data.append(build_data_frame(path, classification))
data = data.reindex(numpy.random.permutation(data.index))
#- 2. Apply different classification methods
"""
SVM
"""
pipeline = Pipeline([
# SVM using TfidfVectorizer
('vectorizer', TfidfVectorizer(max_features = 25000, ngram_range=(1,2), sublinear_tf=True, max_df=0.95, min_df=2,stop_words=stop_words1)),
('clf', LinearSVC(loss='squared_hinge', penalty='l2', dual=False, tol=1e-3))
])
#- 3. Perform K Fold Cross Validation
k_fold = KFold(n=len(data), n_folds=10)
f_score = []
c_accuracy = []
k_score = []
confusion = numpy.array([[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]])
y_predicted_overall = None
y_test_overall = None
for train_indices, test_indices in k_fold:
train_text = data.iloc[train_indices]['text'].values
train_y = data.iloc[train_indices]['class'].values.astype(str)
test_text = data.iloc[test_indices]['text'].values
test_y = data.iloc[test_indices]['class'].values.astype(str)
# Train the model
pipeline.fit(train_text, train_y)
# Predict test data
predictions = pipeline.predict(test_text)
confusion += confusion_matrix(test_y, predictions, binary=False)
score = f1_score(test_y, predictions, average='micro')
f_score.append(score)
caccuracy = metrics.accuracy_score(test_y, predictions)
c_accuracy.append(caccuracy)
kappa = cohen_kappa_score(test_y, predictions)
k_score.append(kappa)
# collect the y_predicted per fold
if y_predicted_overall is None:
y_predicted_overall = predictions
y_test_overall = test_y
else:
y_predicted_overall = numpy.concatenate([y_predicted_overall, predictions])
y_test_overall = numpy.concatenate([y_test_overall, test_y])
# Print Metrics
print_metrics(data,k_score,c_accuracy,y_predicted_overall,y_test_overall,f_score,confusion)
return pipeline
1 ответ
Вы видите вариацию, потому что LinearSVC
использует генератор случайных чисел при подгонке:
Базовая реализация C использует генератор случайных чисел для выбора объектов при подгонке модели. Таким образом, нередко иметь несколько разные результаты для одних и тех же входных данных. Если это произойдет, попробуйте с меньшим
tol
параметр.
Вы также можете попробовать установить random_state
параметр. Фактически, большинство объектов sklearn, которые используют генератор случайных чисел, берут random_state
в качестве необязательного параметра. Вы можете передать любой экземпляр RandomState
или int
семена:
pipeline = Pipeline([
# SVM using TfidfVectorizer
('vectorizer', TfidfVectorizer(max_features = 25000, ngram_range=(1,2), sublinear_tf=True, max_df=0.95, min_df=2,stop_words=stop_words1)),
('clf', LinearSVC(loss='squared_hinge', penalty='l2', dual=False, tol=1e-5, random_state=42))
])
РЕДАКТИРОВАТЬ: как упоминалось в комментариях, cross_validation.KFold
также занимает random_state
параметр, чтобы определить, как отделить данные. Чтобы обеспечить воспроизводимость, вы также должны передать семена илиRandomState
вKFold
,
ПО ВТОРОЙ МЫСЛИ: документация дляKFold
предполагает, что по умолчанию не рандомизировать расщепления, еслиshuffle=True
также указано, поэтому я не знаю, поможет ли приведенное выше предложение.
КАК ПОБОЧНОЕ ПРИМЕЧАНИЕ:cross_validation.KFold
устарела с версии 0.18, поэтому я рекомендую использоватьmodel_selection.KFold
вместо:
from sklearn.model_selection import KFold
k_fold = KFold(n_splits=10, random_state=42)
...
for train_indices, test_indices in k_fold.split(data):