所以我在MNIST数据集上使用一个简单的SGDClassifier(根据动手ML书),我似乎无法弄清楚其decision_function的行为。
我更改了original_decision函数的最后一行,专门检查是否有任何不同。带后缀"检查"的变量是这里的decision_function返回的那些。代码:
from sklearn.datasets import fetch_mldata
mnist = fetch_mldata("MNIST original")
import numpy as np
from sklearn.linear_model import SGDClassifier
from sklearn.utils.extmath import safe_sparse_dot
from sklearn.utils import check_array
X, y = mnist["data"], mnist["target"]
X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]
shuffle_index = np.random.permutation(60000)
X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]
# converting the problem into a binary classification problem.
y_train_5 = (y_train == 5)
y_test_5 = (y_test == 5)
sgd_clf = SGDClassifier(random_state=42)
sgd_clf.fit(X_train, y_train_5)
# modified decision_func to ouput vars
X_check, coef_check, intcpt_check = sgd_clf.decision_function([X_train[36000]])
print((X_check == X_train[36000]).all())
print((coef_check == sgd_clf.coef_).all())
print((intcpt_check == sgd_clf.intercept_).all())
# using same funcs as used by decision_function to calc.
# i.e. check_array safe_sparse_dot
X_mod = check_array(X[36000].reshape(1,-1), "csr")
my_score = safe_sparse_dot(X_mod,sgd_clf.coef_.T) + sgd_clf.intercept_
sk_score = safe_sparse_dot(X_check, coef_check.T) + intcpt_check
print(my_score)
print(sk_score)
这是输出(单次运行):
True
True
True
[[ 49505.1725926]]
[[-347904.18757136]]
这是我对decision_function的修改(在注释掉原始版本之前的第二行):
scores = safe_sparse_dot(X, self.coef_.T,
dense_output=True) + self.intercept_
return X, self.coef_, self.intercept_
#return scores.ravel() if scores.shape[1] == 1 else scores
即使涉及的3个实体(实例X,系数,截距)都与我的变量匹配,但乘法仍会导致截然不同的结果。
为什么会这样?
编辑:奇怪的是我发现如果我注释掉负责改组数据集的两条线:
shuffle_index = np.random.permutation(60000)
X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]
问题消失了......
答案 0 :(得分:0)
这可能是由于X_mod使用的原始" X" (非抽动)矩阵,而X_check使用X_train(混洗)索引。
即。 X_train [36000]!= X [36000]当然,你的分数应该不一样。
答案 1 :(得分:0)
也许可以原因是由于缺席线:
np.random.seed(42)
您为模型使用了随机状态,但没有使用任何替换状态
import numpy as np
np.random.seed(42)
shuffle_index = np.random.permutation(60000)
X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]