train_test_split 中的 random_state 会影响模型的实际性能吗?
Does random_state in train_test_split effect the actual performance of a model?
我明白为什么每个 random_state 的模型得分都不同,但确实预计最高得分和最低得分之间的差异(从 random_state 0-100)为 0.37,这是很多。也试过十折交叉验证,差别还是挺大的
所以这真的重要还是我应该忽略?
The Data-set link
(下载 -> 数据文件夹 -> student.zip -> student-mat.csv)
完整代码:
import pandas as pd
acc_dic = {}
grade_df_main = pd.read_csv(r'F:\Python\Jupyter Notebook\ML Projects\data\student-math-grade.csv', sep = ";")
grade_df = grade_df_main[["G1", "G2", "G3", "studytime", "failures", "absences"]]
X = grade_df.drop("G3", axis = "columns")
Y = grade_df["G3"].copy()
def cross_val_scores(scores):
print("Cross validation result :-")
#print("Scores: {}".format(scores))
print("Mean: {}".format(scores.mean()))
print("Standard deviation: {}".format(scores.std()))
def start(rand_state):
print("Index {}".format(rand_state))
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=.1, random_state=rand_state)
from sklearn.linear_model import LinearRegression
lin_reg_obj = LinearRegression()
lin_reg_obj.fit(x_train, y_train)
accuracy = lin_reg_obj.score(x_test, y_test)
print("Accuracy: {}".format(accuracy))
acc_dic[rand_state] = accuracy
from sklearn.model_selection import cross_val_score
scores = cross_val_score(lin_reg_obj, x_test, y_test, scoring="neg_mean_squared_error", cv=10)
cross_val_scores(scores)
print()
for i in range(0, 101):
start(i)
print("Overview : \n")
result_val = list(acc_dic.values())
min_index = result_val.index(min(result_val))
max_index = result_val.index(max(result_val))
print("Minimum Accuracy : ")
start(min_index)
print("Maximum Accuracy : ")
start(max_index)
结果:
Only included the highest and the lowest results
Minimum Accuracy :
Index 54
Accuracy: 0.5635271419142645
Cross validation result :-
Mean: -8.969894370977539
Standard deviation: 5.614516642510817
Maximum Accuracy :
Index 97
Accuracy: 0.9426035720345269
Cross validation result :-
Mean: -0.7063598117158191
Standard deviation: 0.3149445166291036
TL;DR
决定最终模型在部署后的实际执行情况的并不是您用于训练和评估模型的数据集的拆分。拆分和评估技术更多地是关于对模型在现实生活中的表现进行有效估计。正如您所看到的,拆分和评估技术的选择会对这种估计产生很大影响。您的数据集的结果强烈建议使用 k 折交叉验证而不是简单的 train/test 拆分。
更长的版本
我相信你已经明白了你在数据集上做的将它分成训练集和测试集的分割与你最终模型的性能无关,它很可能是在整个数据集上训练的然后部署。
测试的目的是了解对未见数据的预测性能。在最佳情况下,理想情况下,您将拥有来自不同 cohorts/sources 的两个完全不同的数据集来训练和测试您的模型( 外部验证 )。这是评估模型部署后性能的最佳方法。但是,由于您通常没有这样的第二个数据源,因此您进行 内部验证 ,从相同的 cohort/source.[=10 中获取用于训练和测试的样本=]
通常,假设此数据集足够大,随机性将确保训练集和测试集的拆分很好地表示原始数据集,并且您获得的性能指标是对模型预测的公平估计现实生活中的表现。
但是,正如您在自己的数据集上看到的那样,在某些情况下拆分确实会严重影响结果。正是在这种情况下,您最好使用交叉验证技术(例如 k 折交叉验证)来评估您的性能,并计算不同拆分的平均值。
我明白为什么每个 random_state 的模型得分都不同,但确实预计最高得分和最低得分之间的差异(从 random_state 0-100)为 0.37,这是很多。也试过十折交叉验证,差别还是挺大的
所以这真的重要还是我应该忽略?
The Data-set link (下载 -> 数据文件夹 -> student.zip -> student-mat.csv)
完整代码:
import pandas as pd
acc_dic = {}
grade_df_main = pd.read_csv(r'F:\Python\Jupyter Notebook\ML Projects\data\student-math-grade.csv', sep = ";")
grade_df = grade_df_main[["G1", "G2", "G3", "studytime", "failures", "absences"]]
X = grade_df.drop("G3", axis = "columns")
Y = grade_df["G3"].copy()
def cross_val_scores(scores):
print("Cross validation result :-")
#print("Scores: {}".format(scores))
print("Mean: {}".format(scores.mean()))
print("Standard deviation: {}".format(scores.std()))
def start(rand_state):
print("Index {}".format(rand_state))
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=.1, random_state=rand_state)
from sklearn.linear_model import LinearRegression
lin_reg_obj = LinearRegression()
lin_reg_obj.fit(x_train, y_train)
accuracy = lin_reg_obj.score(x_test, y_test)
print("Accuracy: {}".format(accuracy))
acc_dic[rand_state] = accuracy
from sklearn.model_selection import cross_val_score
scores = cross_val_score(lin_reg_obj, x_test, y_test, scoring="neg_mean_squared_error", cv=10)
cross_val_scores(scores)
print()
for i in range(0, 101):
start(i)
print("Overview : \n")
result_val = list(acc_dic.values())
min_index = result_val.index(min(result_val))
max_index = result_val.index(max(result_val))
print("Minimum Accuracy : ")
start(min_index)
print("Maximum Accuracy : ")
start(max_index)
结果:
Only included the highest and the lowest results
Minimum Accuracy :
Index 54
Accuracy: 0.5635271419142645
Cross validation result :-
Mean: -8.969894370977539
Standard deviation: 5.614516642510817
Maximum Accuracy :
Index 97
Accuracy: 0.9426035720345269
Cross validation result :-
Mean: -0.7063598117158191
Standard deviation: 0.3149445166291036
TL;DR
决定最终模型在部署后的实际执行情况的并不是您用于训练和评估模型的数据集的拆分。拆分和评估技术更多地是关于对模型在现实生活中的表现进行有效估计。正如您所看到的,拆分和评估技术的选择会对这种估计产生很大影响。您的数据集的结果强烈建议使用 k 折交叉验证而不是简单的 train/test 拆分。
更长的版本
我相信你已经明白了你在数据集上做的将它分成训练集和测试集的分割与你最终模型的性能无关,它很可能是在整个数据集上训练的然后部署。
测试的目的是了解对未见数据的预测性能。在最佳情况下,理想情况下,您将拥有来自不同 cohorts/sources 的两个完全不同的数据集来训练和测试您的模型( 外部验证 )。这是评估模型部署后性能的最佳方法。但是,由于您通常没有这样的第二个数据源,因此您进行 内部验证 ,从相同的 cohort/source.[=10 中获取用于训练和测试的样本=]
通常,假设此数据集足够大,随机性将确保训练集和测试集的拆分很好地表示原始数据集,并且您获得的性能指标是对模型预测的公平估计现实生活中的表现。
但是,正如您在自己的数据集上看到的那样,在某些情况下拆分确实会严重影响结果。正是在这种情况下,您最好使用交叉验证技术(例如 k 折交叉验证)来评估您的性能,并计算不同拆分的平均值。