簡體   English   中英

使用train_test_split與手動拆分數據時的結果不同

[英]Different results when using train_test_split vs manually splitting the data

我有一個熊貓數據框,我想對其進行預測並得到每個特征的均方根誤差。 我正在按照手動分割數據集的在線指南,但我認為從sklearn.model_selection使用train_test_split會更方便。 不幸的是,在使用train_test_split手動分割數據后查看rmse值時,我得到的結果不同。

一個(希望)可重復的例子:

import pandas as pd
import numpy as np
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split

np.random.seed(0)
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=['feature_1','feature_2','feature_3','feature_4'])
df['target'] = np.random.randint(2,size=100)
df2 = df.copy()

這是一個函數knn_train_test ,它可以手動分割數據,適合模型,進行預測等:

def knn_train_test(train_col, target_col, df):
    knn = KNeighborsRegressor()
    np.random.seed(0)

    # Randomize order of rows in data frame.
    shuffled_index = np.random.permutation(df.index)
    rand_df = df.reindex(shuffled_index)

    # Divide number of rows in half and round.
    last_train_row = int(len(rand_df) / 2)

    # Select the first half and set as training set.
    # Select the second half and set as test set.
    train_df = rand_df.iloc[0:last_train_row]
    test_df = rand_df.iloc[last_train_row:]

    # Fit a KNN model using default k value.
    knn.fit(train_df[[train_col]], train_df[target_col])

    # Make predictions using model.
    predicted_labels = knn.predict(test_df[[train_col]])

    # Calculate and return RMSE.
    mse = mean_squared_error(test_df[target_col], predicted_labels)
    rmse = np.sqrt(mse)
    return rmse

rmse_results = {}
train_cols = df.columns.drop('target')

# For each column (minus `target`), train a model, return RMSE value
# and add to the dictionary `rmse_results`.
for col in train_cols:
    rmse_val = knn_train_test(col, 'target', df)
    rmse_results[col] = rmse_val

# Create a Series object from the dictionary so 
# we can easily view the results, sort, etc
rmse_results_series = pd.Series(rmse_results)
rmse_results_series.sort_values()

#Output
feature_3    0.541110
feature_2    0.548452
feature_4    0.559285
feature_1    0.569912
dtype: float64

現在,這是一個函數knn_train_test2,它使用train_test_split分割數據:

def knn_train_test2(train_col, target_col, df2):

    knn = KNeighborsRegressor()
    np.random.seed(0)

    X_train, X_test, y_train, y_test = train_test_split(df2[[train_col]],df2[[target_col]], test_size=0.5)

    knn.fit(X_train,y_train)

    predictions = knn.predict(X_test)

    mse = mean_squared_error(y_test,predictions)

    rmse = np.sqrt(mse)

    return rmse

rmse_results = {}
train_cols = df2.columns.drop('target')

for col in train_cols:
    rmse_val = knn_train_test2(col, 'target', df2)
    rmse_results[col] = rmse_val


rmse_results_series = pd.Series(rmse_results)
rmse_results_series.sort_values()

# Output
feature_4    0.522303
feature_3    0.556417
feature_1    0.569210
feature_2    0.572713
dtype: float64

為什么我會得到不同的結果? 我想我總是誤解了分裂>訓練>測試過程,或者誤解/錯誤指定train_test_split 先感謝您

手動拆分數據只是切片,但train_test_split也會隨機化切片數據。 嘗試修復隨機數種子,看看每次使用train_test_split時是否可以獲得相同的結果。

這是基本的機器學習性質。 手動拆分數據時,您將擁有不同版本的培訓和測試集。 當您使用sklearn功能時,您將獲得不同的培訓和測試集。 您的模型將根據收到的訓練數據進行預測,因此您的最終結果會有所不同。

如果要重現結果,請使用train_test_split通過設置種子值來創建多個訓練集。 種子值用於在train_test_split函數中重現相同的結果。 然后在運行你的ml函數時,在那里設置一個種子,因為即使ML函數也開始用隨機權重訓練。 在具有相同種子的這些數據集上嘗試您的模型,您將獲得結果。

您的自定義train_test_split實現與scikit-learn的實現不同,這就是您為同一種子獲得不同結果的原因。

在這里您可以找到官方實施。 值得注意的第一件事是,scikit-learn在默認情況下進行了10次重新混亂和分裂。 (查看n_splits參數)

只有當您的方法與scitkit-learn方法完全相同時 ,您才能期望對同一種子具有相同的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM