我正在完成微软的课程DAT210X – 用于数据科学的Python编程。
在创建SVC
模型用于机器学习时,我们被鼓励在进行预处理
(例如缩放
)和降维
(例如PCA/Isomap
)之前,使用sci-kit learn
中的train_test_split
将数据集X拆分为test
和train
集。我在下面提供了一个代码示例,展示了我使用这种方法解决一个给定问题的一部分解决方案。
然而,在将X拆分为test
和train
之前对X进行预处理
和PCA/IsoMap
似乎要快得多,并且准确率
得分更高。
我的问题是:
1) 为什么我们不能先提取标签(y),然后对整个X进行预处理和降维,最后再拆分为测试和训练集?
2) 对整个X(减去y)进行预处理和降维的得分比先拆分X然后再进行预处理和降维的得分更高。这可能是为什么?
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.30, random_state=7)step_c = .05endpt_c = 2 + step_cstartpt_c = .05step_g = .001endpt_g = .1 + step_gstartpt_g = .001bestscore = 0.0best_i = 0.0best_j = 0.0pre_proc = [ preprocessing.Normalizer(), preprocessing.MaxAbsScaler(), preprocessing.MinMaxScaler(), preprocessing.KernelCenterer(), preprocessing.StandardScaler() ]best_proc = ''best_score = 0print('running......')# pre-processing (scaling etc)for T in pre_proc: X_train_T = T.fit_transform(X_train) X_test_T = T.transform(X_test) # only apply transform to X_test! # dimensionality reduction for k in range(2, 6): for l in range(4, 7): iso = Isomap(n_neighbors = k, n_components = l) X_train_iso = iso.fit_transform(X_train_T) X_test_iso = iso.transform(X_test_T) # SVC parameter sweeping for i in np.arange(startpt_c,endpt_c, step_c): # print(i) for j in np.arange(startpt_g,endpt_g, step_g): clf = SVC(C=i, gamma=j , kernel='rbf' # max_iter=-1, probability=False, random_state=None, shrinking=True, tol=0.001, verbose=False) ) clf.fit(X_train_iso, y_train) score = clf.score(X_test_iso, y_test) if bestscore < score: bestscore = score best_c = i best_g = j best_proc = T best_n_neighbors = k best_n_components = l# Print final variables that gave best score:print('proc: ' + str(T), 'score:' + str(bestscore), 'C: ' + str(i), 'g: ' + str(j), 'n_neigh: ' + str(k), 'n_comp: ' + str(l))enter code here
回答:
关于
1) 为什么我们不能先提取标签(y),然后对整个X进行预处理和降维,最后再拆分为测试和训练集?
原因是你应该在不使用任何关于测试数据的信息的情况下,在训练数据上训练模型。如果你在训练模型之前对整个数据(包括测试数据)应用PCA,那么你实际上是使用了一些来自测试数据的信息。因此,你不能真正用测试数据来判断模型的行为,因为它不再是未见过的数据了。
关于:
2) 对整个X(减去y)进行预处理和降维的得分比先拆分X然后再进行预处理和降维的得分更高。这可能是为什么?
这是完全合理的。你使用了来自测试数据的一些信息来训练模型,所以测试数据上的得分更高是合理的。然而,这个得分不再真正反映模型在未见数据上的表现。