为什么我的keras模型预测的概率总是零
Why is the probability predicted by my keras model always zero
我建立了一个模型来预测 Kaggle 数据集上的贷款适用性 here
dataset = df.values
X = dataset[:,0:11].astype(float)
Y = dataset[:,11]
scaler = StandardScaler()
X = scaler.fit_transform(X)
model = Sequential()
model.add(Dense(5, input_dim=11, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X, Y, epochs=150, batch_size=10, verbose=0)
scores = model.evaluate( X, Y, verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
model.save("model.h5")
该模型的准确率为 81.43%。当我尝试基于此模型进行预测时,问题就出现了。在这里,我已将数据集中的第三行数据作为数组传递给模型,并且与其他行一样,概率为零。
model = load_model('model.h5')
X = np.array([[0, 1, 0, 0, 1, 3000, 0, 66, 360, 1, 0]], dtype=np.float32)
scaler = StandardScaler()
X = scaler.fit_transform(X)
X = scaler.transform(X.reshape(1, -1))
pred = model.predict(X)
print(X)
print("Probability that eligibility = 1:")
print(pred)
我得到输出:
[[ 0.000e+00 -1.000e+00 -1.000e+00 0.000e+00 0.000e+00 -4.583e+03
-1.508e+03 -1.280e+02 -3.600e+02 -1.000e+00 -1.000e+00]]
Probability that eligibility = 1:
[[0.]]
我无法在 Whosebug 或其他网站上找到解决方案。
你正在对训练部分进行标准化,这很棒。但是,系统会用错误标准化的值预测您。当你对训练部分进行标准化时,你计算每列的均值和标准差并进行操作。
然而,预测部分并不好,因为你计算了行的均值和标准差。
正确的训练过程是:
- 计算训练数据集中所有列的均值和标准差
- 对列值进行标准化操作:
X_standard = (X - mean_column) / std_column
- 训练您的模型
正确的预测过程是:
- Select 一行并通过在 1 处计算的相应均值和标准差对每个元素进行标准化。
- 预测
不适合新数据的新标量对象,除了模型之外,您还需要保存用于训练数据的 StandardScaler,加载它并转换新数据,
保存
from pickle import dump
scaler = StandardScaler()
X = scaler.fit_transform(X)
dump(scaler, open('scaler.pkl', 'wb'))
然后在你想预测的时候加载它
from pickle import load
scaler = load(open('scaler.pkl', 'rb'))
X = np.array([[0, 1, 0, 0, 1, 3000, 0, 66, 360, 1, 0]], dtype=np.float32)
scaler.transform(X)
我建立了一个模型来预测 Kaggle 数据集上的贷款适用性 here
dataset = df.values
X = dataset[:,0:11].astype(float)
Y = dataset[:,11]
scaler = StandardScaler()
X = scaler.fit_transform(X)
model = Sequential()
model.add(Dense(5, input_dim=11, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X, Y, epochs=150, batch_size=10, verbose=0)
scores = model.evaluate( X, Y, verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
model.save("model.h5")
该模型的准确率为 81.43%。当我尝试基于此模型进行预测时,问题就出现了。在这里,我已将数据集中的第三行数据作为数组传递给模型,并且与其他行一样,概率为零。
model = load_model('model.h5')
X = np.array([[0, 1, 0, 0, 1, 3000, 0, 66, 360, 1, 0]], dtype=np.float32)
scaler = StandardScaler()
X = scaler.fit_transform(X)
X = scaler.transform(X.reshape(1, -1))
pred = model.predict(X)
print(X)
print("Probability that eligibility = 1:")
print(pred)
我得到输出:
[[ 0.000e+00 -1.000e+00 -1.000e+00 0.000e+00 0.000e+00 -4.583e+03
-1.508e+03 -1.280e+02 -3.600e+02 -1.000e+00 -1.000e+00]]
Probability that eligibility = 1:
[[0.]]
我无法在 Whosebug 或其他网站上找到解决方案。
你正在对训练部分进行标准化,这很棒。但是,系统会用错误标准化的值预测您。当你对训练部分进行标准化时,你计算每列的均值和标准差并进行操作。
然而,预测部分并不好,因为你计算了行的均值和标准差。
正确的训练过程是:
- 计算训练数据集中所有列的均值和标准差
- 对列值进行标准化操作:
X_standard = (X - mean_column) / std_column
- 训练您的模型
正确的预测过程是:
- Select 一行并通过在 1 处计算的相应均值和标准差对每个元素进行标准化。
- 预测
不适合新数据的新标量对象,除了模型之外,您还需要保存用于训练数据的 StandardScaler,加载它并转换新数据,
保存
from pickle import dump
scaler = StandardScaler()
X = scaler.fit_transform(X)
dump(scaler, open('scaler.pkl', 'wb'))
然后在你想预测的时候加载它
from pickle import load
scaler = load(open('scaler.pkl', 'rb'))
X = np.array([[0, 1, 0, 0, 1, 3000, 0, 66, 360, 1, 0]], dtype=np.float32)
scaler.transform(X)