keras:98% 的准确率,但 NN 总是预测相同。可能是什么原因?
keras: 98% of accuracy but the NN always predicts the same. What could be the cause?
我们在训练 DL 模型以预测贷款评分(分类为 0,1 或 3)时遇到以下问题。
这些是步骤:
第 1 步:创建新列 "scoring"(输出)
conditions = [
(df2['Credit Score'] >= 0) & (df2['Credit Score'] < 1000),
(df2['Credit Score'] >= 1000) & (df2['Credit Score'] < 6000),
(df2['Credit Score'] >= 6000) & (df2['Credit Score'] <= 7000)]
choices = [0,1,2]
df2['Scoring'] = np.select(conditions, choices)
步2:preparing训练
array = df2.values
X = np.vstack((array[:,2:3].T, array[:,5:15].T)).T
Y = array[:,15:]
N = Y.shape[0]
T = np.zeros((N, np.max(Y)+1))
for i in range(N):
T[i,Y[i]] = 1
x_train, x_test, y_train, y_test = train_test_split(X, T, test_size=0.2, random_state=42)
第 3 步:拓扑
model = Sequential()
model.add(Dense(80, input_shape=(11,), activation='tanh'))
model.add(Dropout(0.2))
model.add(Dense(80, activation='tanh'))
model.add(Dropout(0.1))
model.add(Dense(40, activation='relu'))
model.add(Dense(3, activation='softmax'))
epochs =200
learning_rate = 0.00001
decay_rate = learning_rate / epochs
momentum = 0.002
sgd = SGD(lr=learning_rate, momentum=momentum, decay=decay_rate, nesterov=False)
ad = Adamax(lr=learning_rate)
第 4 步:训练
epochs = 200
batch_size = 16
history = model.fit(x_train, y_train, validation_data=(x_test, y_test), nb_epoch=epochs,
batch_size=batch_size,validation_split=0.1)
print ('fit done!')
指标
365/365 [==============================] - 0s 60us/样本 - 损失:0.0963 -累计:0.9808
测试集
损失:0.096
精度:0.981
accuracy
第五步:预测
text1 = [1358,1555,1,3,1741,8,0,1596,1518,0,0] #scoring 0
text2 = [1454,1601,3,11,1763,10,0,685,1044,0,0] #scoring 1
text3 = [1209,1437,3,11,199,18,1,761,1333,1,0] #scoring 2
tmp = np.vstack(text1).T
textA = tmp.reshape(1,-1)
tmp = np.vstack(text2).T
textB = tmp.reshape(1,-1)
tmp = np.vstack(text3).T
print(tmp)
textC = tmp.reshape(1,-1)
p = model.predict(textA)
t = p[0]
print(textA,np.argmax(t))
p = model.predict(textB)
t = p[0]
print(textB,np.argmax(t))
p = model.predict(textC)
t = p[0]
print(textC,np.argmax(t))
问题:预测的输出总是一样的!!!
[9.9205679e-01 3.8634153e-04 7.5568780e-03]
[[1358 1555 1 3 1741 8 0 1596 1518 0 0]] 0 --- scoring 0
[0.9862417 0.00205712 0.01170125]
[[1454 1601 3 11 1763 10 0 685 1044 0 0]] 0 --- scoring 0
[9.9251783e-01 2.5733517e-04 7.2247880e-03]
[[1209 1437 3 11 199 18 1 761 1333 1 0]] 0 ---- scoring 0
¿这种行为的原因是什么?
提前致谢!
您的数据集极度不平衡。一个很好的看待它的方法是:如果总是预测 0 能让你达到 98% 的准确率,那么说某物属于不同的 class 是相当冒险的(或者它必须非常明显)。 NN 可能发现的使任何少数 class 不同于多数 class (0) 的每个模式都必须非常独特,因为即使重叠很小,不预测 0 的成本也太高.
考虑这个例子:你有一个包含两个 class 的数据集,A 和 B,它们都服从正态分布。 Class A 的平均值为 1,标准差为 1,class B 的平均值为 3,标准差为 0.1。您有 1,000,000 个 class 0 样本和 20,000 个 class 1 样本,因此始终预测 A 会给您 98% 的准确率。 class B 的所有样本将位于 2.743 和 3.257 之间,置信度为 99%。在这些值之间,class A 预计有 29,300 个样本,因此将任何观察结果预测为 class B 的成本在 29,300 个 A 样本中出现错误,但将所有内容预测为 A 的成本是只有 20,000 个 B 样本有错误。
下面是该示例的图形显示方式:
import numpy as np
import matplotlib.pyplot as plt
# Get A and B
A = np.random.normal(1, 1, 1000000)
B = np.random.normal(3, 0.1, 20000)
# Count the number of observations in A for each B
B.sort()
a = A[np.logical_and(A >= B.min(), A <= B.max())]
a = [(a<i).sum() for i in B]
# Plot results
plt.plot(B, np.arange(B.shape[0]), label='Class B')
plt.plot(B, a, label='Class A')
plt.ylabel('Count of samples')
plt.xlabel('Values')
plt.legend()
plt.show()
请参阅这篇关于平衡数据集的文章:https://www.kdnuggets.com/2017/06/7-techniques-handle-imbalanced-data.html
我们在训练 DL 模型以预测贷款评分(分类为 0,1 或 3)时遇到以下问题。
这些是步骤:
第 1 步:创建新列 "scoring"(输出)
conditions = [
(df2['Credit Score'] >= 0) & (df2['Credit Score'] < 1000),
(df2['Credit Score'] >= 1000) & (df2['Credit Score'] < 6000),
(df2['Credit Score'] >= 6000) & (df2['Credit Score'] <= 7000)]
choices = [0,1,2]
df2['Scoring'] = np.select(conditions, choices)
步2:preparing训练
array = df2.values
X = np.vstack((array[:,2:3].T, array[:,5:15].T)).T
Y = array[:,15:]
N = Y.shape[0]
T = np.zeros((N, np.max(Y)+1))
for i in range(N):
T[i,Y[i]] = 1
x_train, x_test, y_train, y_test = train_test_split(X, T, test_size=0.2, random_state=42)
第 3 步:拓扑
model = Sequential()
model.add(Dense(80, input_shape=(11,), activation='tanh'))
model.add(Dropout(0.2))
model.add(Dense(80, activation='tanh'))
model.add(Dropout(0.1))
model.add(Dense(40, activation='relu'))
model.add(Dense(3, activation='softmax'))
epochs =200
learning_rate = 0.00001
decay_rate = learning_rate / epochs
momentum = 0.002
sgd = SGD(lr=learning_rate, momentum=momentum, decay=decay_rate, nesterov=False)
ad = Adamax(lr=learning_rate)
第 4 步:训练
epochs = 200
batch_size = 16
history = model.fit(x_train, y_train, validation_data=(x_test, y_test), nb_epoch=epochs,
batch_size=batch_size,validation_split=0.1)
print ('fit done!')
指标
365/365 [==============================] - 0s 60us/样本 - 损失:0.0963 -累计:0.9808 测试集 损失:0.096 精度:0.981
accuracy
第五步:预测
text1 = [1358,1555,1,3,1741,8,0,1596,1518,0,0] #scoring 0
text2 = [1454,1601,3,11,1763,10,0,685,1044,0,0] #scoring 1
text3 = [1209,1437,3,11,199,18,1,761,1333,1,0] #scoring 2
tmp = np.vstack(text1).T
textA = tmp.reshape(1,-1)
tmp = np.vstack(text2).T
textB = tmp.reshape(1,-1)
tmp = np.vstack(text3).T
print(tmp)
textC = tmp.reshape(1,-1)
p = model.predict(textA)
t = p[0]
print(textA,np.argmax(t))
p = model.predict(textB)
t = p[0]
print(textB,np.argmax(t))
p = model.predict(textC)
t = p[0]
print(textC,np.argmax(t))
问题:预测的输出总是一样的!!!
[9.9205679e-01 3.8634153e-04 7.5568780e-03] [[1358 1555 1 3 1741 8 0 1596 1518 0 0]] 0 --- scoring 0
[0.9862417 0.00205712 0.01170125] [[1454 1601 3 11 1763 10 0 685 1044 0 0]] 0 --- scoring 0
[9.9251783e-01 2.5733517e-04 7.2247880e-03] [[1209 1437 3 11 199 18 1 761 1333 1 0]] 0 ---- scoring 0
¿这种行为的原因是什么?
提前致谢!
您的数据集极度不平衡。一个很好的看待它的方法是:如果总是预测 0 能让你达到 98% 的准确率,那么说某物属于不同的 class 是相当冒险的(或者它必须非常明显)。 NN 可能发现的使任何少数 class 不同于多数 class (0) 的每个模式都必须非常独特,因为即使重叠很小,不预测 0 的成本也太高.
考虑这个例子:你有一个包含两个 class 的数据集,A 和 B,它们都服从正态分布。 Class A 的平均值为 1,标准差为 1,class B 的平均值为 3,标准差为 0.1。您有 1,000,000 个 class 0 样本和 20,000 个 class 1 样本,因此始终预测 A 会给您 98% 的准确率。 class B 的所有样本将位于 2.743 和 3.257 之间,置信度为 99%。在这些值之间,class A 预计有 29,300 个样本,因此将任何观察结果预测为 class B 的成本在 29,300 个 A 样本中出现错误,但将所有内容预测为 A 的成本是只有 20,000 个 B 样本有错误。
下面是该示例的图形显示方式:
import numpy as np
import matplotlib.pyplot as plt
# Get A and B
A = np.random.normal(1, 1, 1000000)
B = np.random.normal(3, 0.1, 20000)
# Count the number of observations in A for each B
B.sort()
a = A[np.logical_and(A >= B.min(), A <= B.max())]
a = [(a<i).sum() for i in B]
# Plot results
plt.plot(B, np.arange(B.shape[0]), label='Class B')
plt.plot(B, a, label='Class A')
plt.ylabel('Count of samples')
plt.xlabel('Values')
plt.legend()
plt.show()
请参阅这篇关于平衡数据集的文章:https://www.kdnuggets.com/2017/06/7-techniques-handle-imbalanced-data.html