我正在尝试预测一个整数值的时间序列。我通过滑动窗口来执行此操作,在该窗口中,它学会关联99个值以预测下一个值。值在0到128之间。X的表示形式是n个滑动窗口的立方体,长为99个,每个整数编码为一个128个元素长的热编码矢量。该数组的形状为(n,99,128)。 Y的形状为(n,128)。我认为这是一个多类问题,因为Y可以精确地得出一个结果。
这在Keras / Tensorflow上很好用,但是当我尝试从scikit-learn使用RandomForest时,它抱怨输入向量是3D而不是2D。因此,我将输入立方体X整形为形状为(n,99 * 128)的2D矩阵。结果不是很好,为了理解正在发生的事情,我请求了概率(请参见下面的代码)。
def rf(X_train, Y_train, X_val, Y_val, samples):
clf = RandomForestClassifier(n_estimators=32, n_jobs=-1)
clf.fit(X_train, Y_train)
score = clf.score(X_val, Y_val)
print('Score of randomforest =', score)
# compute some samples
for i in range(samples):
index = random.randrange(0, len(X_val) - 1)
xx = X_val[index].reshape(1, -1)
probs = clf.predict_proba(xx)
pred = clf.predict(xx)
y_true = np.argmax(Y_val[index])
y_hat = np.argmax(pred)
print(index, '-', y_true, y_hat, xx.shape, len(probs))
print(probs)
print(pred)
我从predict_proba
获得的输出是:
[array([[0.841, 0.159]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1., 0.]]), array([[1., 0.]]), array([[1., 0.]]),
array([[1., 0.]]), array([[1., 0.]]), array([[0.995, 0.005]]), array([[0.999,
0.001]]), array([[0.994, 0.006]]), array([[1., 0.]]), array([[0.994, 0.006]]),
array([[0.977, 0.023]]), array([[0.999, 0.001]]), array([[0.939, 0.061]]),
array([[0.997, 0.003]]), array([[0.969, 0.031]]), array([[0.997, 0.003]]),
array([[0.984, 0.016]]), array([[0.949, 0.051]]), array([[1., 0.]]),
array([[0.95, 0.05]]), array([[1., 0.]]), array([[0.918, 0.082]]),
array([[0.887, 0.113]]), array([[1.]]), array([[0.88, 0.12]]), array([[1.]]),
array([[0.884, 0.116]]), array([[0.941, 0.059]]), array([[1.]]), array([[0.941,
0.059]]), array([[1.]]), array([[0.965, 0.035]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]])]
输出向量的长度正确为128,但是为什么它由一个包含2D数组的列表组成,有时包含一个元素,有时包含两个元素?据我对the manual的了解,应该使用维数#个样本*#个类返回一个数组,因此在我的形状为(1,128)的示例中。
有人可以帮助我指出我做错了什么吗?
编辑1
我按照@Vivek Kumar(感谢Vivek)在他的评论中建议的方法进行了实验。我输入整数(X)序列,并将它们与序列(y)中的下一个整数匹配。这是代码:
def rff(X_train, Y_train, X_val, Y_val, samples, cont=False):
print('Input data:', X_train.shape, Y_train.shape, X_val.shape, Y_val.shape)
clf = RandomForestClassifier(n_estimators=64, n_jobs=-1)
clf.fit(X_train, Y_train)
score = clf.score(X_val, Y_val)
y_true = Y_val
y_prob = clf.predict_proba(X_val)
y_hat = clf.predict(X_val)
print('y_true', y_true.shape, y_true)
print('y_prob', y_prob.shape, y_prob)
print('y_hat', y_hat.shape, y_hat)
#sum_prob = np.sum(y_true == y_prob)
sum_hat = np.sum(y_true == y_hat)
print('Score of randomforest =', score)
print('Score y_hat', sum_hat / len(X_val))
#print('Score y_prob', sum_prob / len(X_val))
# compute some individual samples
for i in range(samples):
index = random.randrange(0, len(X_val) - 1)
y_true_i = Y_val[index]
#y_prob_i = y_prob[index]
y_hat_i = y_hat[index]
print('{:4d} - {:3d}{:3d}'.format(index, y_true_i, y_hat_i))
其输出为:
Input data: (4272, 99) (4272,) (1257, 99) (1257,)
y_true (1257,) [ 0 0 0 ... 69 70 70]
y_prob (1257, 29) [[0.09375 0. 0. ... 0.078125 0.078125 0.015625]
[0.109375 0. 0. ... 0.046875 0.0625 0.0625 ]
[0.125 0. 0. ... 0.015625 0.078125 0.015625]
...
[0.078125 0. 0. ... 0. 0. 0. ]
[0.046875 0. 0. ... 0. 0. 0. ]
[0.078125 0. 0. ... 0. 0. 0. ]]
y_hat (1257,) [81 81 79 ... 67 67 65]
Score of randomforest = 0.20047732696897375
Score y_hat 0.20047732696897375
228 - 76 77
51 - 76 0
563 - 81 0
501 - 0 77
457 - 79 79
285 - 76 77
209 - 81 0
1116 - 79 0
178 - 72 77
1209 - 67 65
概率数组具有一致的大小,但是其形状是完全怪异的(128,29)。这29是从哪里来的...?但是,报告有一些改进:准确性已大大提高。过去大约是0.0015,现在大约是0.20。
关于概率数组代表什么的任何想法?
编辑2
我的错误是,从128个单编码的值返回到整数后,我没有考虑到只有29个唯一值。 predict_proba
巧妙地预测了这29个值,因为这是它学到的。
剩下的唯一问题是概率预测哪些值?让我们假设要预测的类为0,101-128,predict_proba
返回索引0..28的值。概率到类的映射是什么:0-> 0、1-> 101、2-> 102,...,29-128?我在手册中找不到关于此的任何提示。
答案 0 :(得分:3)
y
。 2-d y
被视为标签指示器矩阵,用于scikit-learn中的多标签或多输出多类任务。从您的数据来看,情况似乎并非如此,因此我认为您不希望对y
进行一次热编码。
关于问题中目标的第二件事是,您首先需要确定是要分类任务还是回归任务。您说您有一个"time series of integer values"
。所以问题是可以将这些整数与另一个数字进行比较吗?
示例1 :考虑到您遇到一个问题,您想将一些数据归类为“日本”,“俄罗斯”,“美国”三个国家。
现在这些字符串可以被编码为1(“日本”),2(“俄罗斯”)和3(“美国”),以便可以在机器学习模型中使用。但是我们无法将这些编码作为数字进行比较,因为2中的数字大于1或小于3。这里的1,2,3只是类别数据的数字表示形式,实际上对其没有任何数字意义。在这种情况下,分类任务适合将数据放入这三个类中。
但是在任何其他情况下,例如预测股票价格或预测温度等,这些数字可以并且应该相互比较,因此应该使用回归(预测实际价值目标)。 / p>
示例2 :为了更好地理解,您还可以考虑模型的正确性(损失函数)。让我们假设一个模型可以预测1到10的目标,并且特定样本的正确目标是9。
在分类任务中,只有正确的预测才重要。模型预测目标是8还是1都没关系。
但是在回归模型中,如果一个模型将输出预测为8,则可以说比同一样本将输出预测为1的模型更好。
希望您明白我的意思。因此,对于您的问题,即使您有有限数量的整数(128)作为目标,也需要确定它们在分类或回归中是否有意义。
注意:我现在将分类作为您的原始问题进行进一步的研究。
X
如果类别中没有排序,或者您无法正确确定该排序,则使用单热编码。我上面给出的类别之间的数值比较的解释也适用于此。
考虑三个类别的另一个示例:“高”,“中”,“低”。它们在其中具有固有的顺序。如果您将其编码为0(低),1(中)和2(高),则可以对其进行数值比较。因此,您可以决定将它们保留为0,1,2或一键编码。
正如我在评论中说的那样,如果对类别进行战略性编码,则随机森林对于此类情况非常强大,并且不会对性能产生太大影响。例如,如果您编码0(高),1(低),2(中)等,性能可能会下降。
现在再次从第1点开始讨论您的问题和我的问题:可以将这些整数与另一个数字进行比较吗?如果是,则无需对功能进行一次热编码。如果没有,那就这样做。