Кръстосаното валидиране е широко използвана техника в машинното обучение за оценка на производителността на модел и избор на хиперпараметри. Това включва разделяне на наличните данни на няколко гънки, обучение на модела върху някои от гънките и оценката му върху останалите гънки. Този процес се повтаря многократно, като се използват различни комбинации от гънки за обучение и оценка, за да се получи стабилна оценка на производителността на модела.
В този урок ще разгледаме основите на използването на кръстосано валидиране в Python, включително как да го внедрим ръчно и как да използваме вградените функции за кръстосано валидиране на scikit-learn. Ще обсъдим също различни стратегии за кръстосано валидиране и как да използваме кръстосано валидиране за избор на модел и настройка на хиперпараметър.
Внедряване на кръстосано валидиране ръчно
За да приложите ръчно кръстосано валидиране в Python, можете да използвате класа model_selection.KFold
от scikit-learn. Този клас предоставя итератор, който дава обучаващи/тестови разделяния на данните за даден брой сгъвания.
Ето пример за използване на KFold
за извършване на k-кратно кръстосано валидиране на набор от данни за класификация:
import numpy as np from sklearn.model_selection import KFold from sklearn.linear_model import LogisticRegression from sklearn.datasets import load_breast_cancer # Load the breast cancer dataset from scikit-learn data = load_breast_cancer() X = data['data'] y = data['target'] # Define the model model = LogisticRegression() # Define the cross-validation iterator kfold = KFold(n_splits=5, shuffle=True, random_state=42) # Initialize an array to store the evaluation scores scores = [] # Loop over the folds for train_index, test_index in kfold.split(X): # Get the training and test data for this fold X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index] # Fit the model to the training data and evaluate on the test data model.fit(X_train, y_train) score = model.score(X_test, y_test) scores.append(score) # Print the mean and standard deviation of the evaluation scores print(f'Mean score: {np.mean(scores):.2f}') print(f'Standard deviation: {np.std(scores):.2f}')
Този код зарежда набора от данни за рак на гърдата от scikit-learn, дефинира модел на логистична регресия и след това дефинира итератор за 5-кратно кръстосано валидиране, използвайки KFold
. След това кодът преминава през гънките, като използва данните за обучение, за да пасне на модела, и данните от теста, за да оцени модела. Резултатите за оценка се съхраняват в масив и след това средната стойност и стандартното отклонение се отпечатват на конзолата.
Използване на функциите за кръстосано валидиране на scikit-learn
Scikit-learn предоставя редица удобни функции за извършване на кръстосано валидиране, което може да бъде по-ефективно и по-лесно за използване, отколкото ръчното им прилагане. Тези функции включват:
model_selection.cross_val_score
: Тази функция извършва к-кратно кръстосано валидиране на модел и връща оценките за оценка за всяко сгъване.
import numpy as np from sklearn.model_selection import cross_val_score from sklearn.linear_model import LogisticRegression from sklearn.datasets import load_breast_cancer # Load the breast cancer dataset from scikit-learn data = load_breast_cancer() X = data['data'] y = data['target'] # Define the model model = LogisticRegression() # Perform k-fold cross-validation scores = cross_val_score(model, X, y, cv=5) # Print the mean and standard deviation of the evaluation scores print(f'Mean score: {np.mean(scores):.2f}') print(f'Standard deviation: {np.std(scores):.2f}')
Този код е еквивалентен на предишния пример, но използва cross_val_score
за извършване на k-кратно кръстосано валидиране и връща директно оценките за оценка.
model_selection.cross_val_predict
: Тази функция извършва k-кратно кръстосано валидиране и връща предвидените етикети за всяка проба.
import numpy as np from sklearn.model_selection import cross_val_predict from sklearn.linear_model import LogisticRegression from sklearn.datasets import load_breast_cancer # Load the breast cancer dataset from scikit-learn data = load_breast_cancer() X = data['data'] y = data['target'] # Define the model model = LogisticRegression() # Perform k-fold cross-validation and get the predicted labels for each sample predictions = cross_val_predict(model, X, y, cv=5) # Print the mean and standard deviation of the predicted labels print(f'Mean prediction: {np.mean(predictions):.2f}') print(f'Standard deviation: {np.std(predictions):.2f}')
Този код е подобен на предишния пример, но използва cross_val_predict
, за да получи предвидените етикети за всяка проба вместо оценките за оценка.
model_selection.GridSearchCV
: Тази функция извършва изчерпателно търсене върху определена решетка с хиперпараметри, използвайки k-кратно кръстосано валидиране. Той връща най-добрите хиперпараметри въз основа на производителността на модела върху данните за валидиране.
import numpy as np from sklearn.model_selection import GridSearchCV from sklearn.linear_model import LogisticRegression from sklearn.datasets import load_breast_cancer # Load the breast cancer dataset from scikit-learn data = load_breast_cancer() X = data['data'] y = data['target'] # Define the model and the hyperparameter grid model = LogisticRegression() param_grid = {'C': [0.1, 1, 10, 100]} # Use grid search with k-fold cross-validation to tune the hyperparameters grid_search = GridSearchCV(model, param_grid, cv=5) grid_search.fit(X, y)
Избор на броя на гънките
Броят на сгъванията в k-кратното кръстосано валидиране е важен хиперпараметър, който може да повлияе на производителността на модела и надеждността на оценките за оценка. По-големият брой сгъвания ще осигури по-точна оценка на производителността на модела, но също така ще бъде по-бавно за изчисляване.
Често срещан избор е да използвате 5 или 10 сгъвания, които постигат добър баланс между точност и скорост.
Възможно е също така да се използва стратифицирано k-кратно кръстосано валидиране, което гарантира, че пропорциите на различните класове в гънките са същите като в оригиналния набор от данни. Това може да бъде полезно за небалансирани набори от данни, където един клас е много по-често срещан от останалите.
Различни стратегии за кръстосано валидиране
В допълнение към k-кратното кръстосано валидиране, има няколко други стратегии за кръстосано валидиране, които могат да бъдат полезни в различни ситуации.
- Кръстосано валидиране с изключване с един навън (LOOCV): Това е специален случай на кръстосано валидиране с k-кратно, където
k
е равно на размера на набора за обучение. Това означава, че една извадка се използва като набор за валидиране, докато останалите данни се използват за обучение. LOOCV може да бъде много точен, но също така е много бавен за изчисляване, особено за големи масиви от данни. - Стратифицирано кръстосано валидиране на k-кратно: Както бе споменато по-рано, това е вариант на кръстосано валидиране на k-кратно, който гарантира, че пропорциите на различните класове в гънките са същите като в оригиналния набор от данни. Това може да бъде полезно за небалансирани набори от данни, където един клас е много по-често срещан от останалите.
- Кръстосано валидиране с разбъркано разделяне: Това е вариант на кръстосано валидиране с k-кратно, при което данните се разбъркват, преди да бъдат разделени на гънки. Това може да бъде полезно, ако данните имат някакъв вид подреждане или ако редът на извадките е важен.
- Кръстосано валидиране на времеви серии: Това е вариант на k-кратно кръстосано валидиране, който е специално проектиран за данни от времеви редове. Това включва разделяне на данните на фиксиран брой гънки, но разделянето се извършва на базата на време, а не на случаен принцип. Това може да бъде полезно, ако данните имат времеви зависимости, които трябва да бъдат запазени в гънките.
Използване на кръстосано валидиране за избор на модел и настройка на хиперпараметър
Едно от основните приложения на кръстосаното валидиране е за избор на модел и настройка на хиперпараметър. Чрез използване на кръстосано валидиране можете да оцените ефективността на различни модели и различни комбинации от хиперпараметри върху едни и същи данни и да изберете модела и хиперпараметрите, които се представят най-добре.
За да използвате кръстосано валидиране за избор на модел и настройка на хиперпараметър, можете да използвате функцията GridSearchCV
на scikit-learn. Тази функция извършва изчерпателно търсене върху определена решетка с хиперпараметри, използвайки k-кратно кръстосано валидиране, и връща най-добрите хиперпараметри въз основа на производителността на модела върху данните за валидиране.
Ето пример за използване на GridSearchCV
за настройка на хиперпараметрите на логистичен регресионен модел:
import numpy as np from sklearn.model_selection import GridSearchCV from sklearn.linear_model import LogisticRegression from sklearn.datasets import load_breast_cancer # Load the breast cancer dataset from scikit-learn data = load_breast_cancer() X = data['data'] y = data['target'] # Define the model and the hyperparameter grid model = LogisticRegression() param_grid = {'C': [0.1, 1, 10, 100], 'penalty': ['l1', 'l2']} # Use grid search with k-fold cross-validation to tune the hyperparameters grid_search = GridSearchCV(model, param_grid, cv=5) grid_search.fit(X, y) # Print the best hyperparameters print(f'Best hyperparameters: {grid_search.best_params_}') # Print the mean and standard deviation of the evaluation scores for the best model scores = grid_search.cv_results_['mean_test_score'] stds = grid_search.cv_results_['std_test_score'] for mean, std, params in zip(scores, stds, grid_search.cv_results_['params']): print(f'{mean:.3f} (+/-{std * 2:.3f}) for {params}')
Този код дефинира логистичен регресионен модел и мрежа от хиперпараметри за търсене. След това използва `GridSearchCV`, за да извърши изчерпателно търсене в мрежата с хиперпараметри, използвайки k-кратно кръстосано валидиране. След това се отпечатват най-добрите хиперпараметри, заедно със средната стойност и стандартното отклонение на оценките за най-добрия модел.
Заключение
В този урок разгледахме основите на използването на кръстосано валидиране в машинно обучение с помощта на Python. Разгледахме как да приложим ръчно кръстосано валидиране и как да използваме вградените функции за кръстосано валидиране на scikit-learn. Обсъдихме също различни стратегии за кръстосано валидиране и как да използваме кръстосано валидиране за избор на модел и настройка на хиперпараметри.
Надявам се, че този урок е предоставил добро въведение в използването на кръстосано валидиране в машинното обучение.