为什么我的 Python RandomForestRegressor 不能准确预测训练集数据?
Why doesn't my Python RandomForestRegressor accurately predict training set data?
我正在学习机器学习,我想在相当复杂的数据集上使用 scikit-learn 的 RandomForestRegressor()
。不过,为了首先掌握它,我正在尝试通过一个基本示例来工作,如下所示:
import sklearn.ensemble as se
import numpy as np
forest = se.RandomForestRegressor(n_estimators=1000)
traindata = np.arange(1000).reshape(200,5)
forest = forest.fit(traindata[0::,1::],traindata[0::,0])
此时,我认为我所做的是:我创建了一个 200 行的矩阵,每行 5 个值,格式为 [ x, x+1, x+2, x+3, x+4 ]
,其中 x
是以下的倍数5(例如 [0,1,2,3,4]
、[5,6,7,8,9]
等)。
我已经让我的森林适应特征 [ x+1, x+2, x+3, x+4 ]
来预测 x
。这是我预测时会发生的事情:
forest.predict([1,2,3,4])
>> array([2.785])
这对我来说真的很不直观。考虑到 [1,2,3,4]
的特征值在 x = 0
的训练数据中,难道我的森林不能比 2.785 更准确地预测它吗?
我更进一步看到特征重要性如下:
forest.feature_importances_
>> array([0.26349716, 0.23664264, 0.23360533, 0.26625487])
对我来说,这并不意味着我所看到的方式存在重大偏差。我在这里错过了什么?
当我尝试你的代码时,我得到 AttributeError: 'module' object has no attribute 'arrange'
所以这是你的示例的可重现版本(一般来说,我建议明确创建单独的 X 和 Y 以避免犯愚蠢的错误,这是我在看到时的第一个想法你的问题)。正如您在下面看到的,随机森林分类器在训练集中对您的示例表现完美。随机森林回归器不会产生完美的预测。我不确定这是为什么,但这是一个起点。
import numpy as np
import sklearn.ensemble as se
import numpy as np
x = 0
X_train = []
Y_train = []
while x < 1000:
Y_train.append(x)
X_train.append([x + 1, x + 2, + x + 3, x + 4])
x += 5
forestregression = se.RandomForestRegressor(n_estimators=1000)
forestregression.fit(X_train, Y_train)
print(forestregression.predict(X_train))
[ 3.005 4.96 9.015 13.875 18.9 23.985 29.18 34.24
39.035 43.765 49.135 54.06 59.15 63.99 68.85 74.205
79.12 84.01 88.9 93.92 98.995 104.13 108.825 114.14
119.1 123.84 128.895 134.15 138.905 144.075 148.91 153.895
159.165 163.83 169.065 174.195 179.03 183.975 188.915 194.06
198.9 204.105 208.975 214.11 218.79 224.135 228.985 234.205
239.13 244.025 249.04 254.065 258.975 264.14 269.03 274.105
278.985 284. 288.935 294.055 299.04 304.025 308.895 313.92
318.82 324.1 328.92 334.18 338.985 344.07 348.905 353.94
359.115 364.11 369. 374.11 379.07 383.995 388.975 394.005
399.035 403.91 408.99 414.125 419.165 424.17 428.86 434.14
438.945 444.155 449.12 453.97 459.075 464.075 469.025 474.105
478.895 483.98 489.085 494.105 498.985 504.045 508.99 514.02
519.02 524.115 529.115 533.985 538.95 544.085 548.915 553.94
558.935 564.035 568.925 574.12 578.925 583.995 589.21 593.99
599.17 603.925 608.93 613.98 619.105 623.975 629.11 634.08
638.99 644.06 648.85 654.05 659.175 664.155 669.03 673.85
679.01 684.005 689.015 694.02 699.225 704.135 708.965 713.86
718.88 723.84 728.99 733.835 738.985 744.205 748.99 753.74
759.1 764.125 768.935 774.195 778.925 783.835 789.25 793.8
798.925 804.03 809.06 813.98 819.135 823.9 828.9 834.04
839.035 844.18 848.955 854.1 858.98 864.095 868.995 874.02
879.165 883.795 888.905 894.245 898.965 903.8 908.98 913.945
918.92 924.26 929.05 933.915 938.815 944.04 949.175 953.815
959.025 963.925 968.99 974.07 979.1 984.095 988.715 992.18 ]
forestclassifier = se.RandomForestClassifier(n_estimators=1000)
forestclassifier.fit(X_train, Y_train)
print(forestclassifier.predict(X_train))
[ 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85
90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175
180 185 190 195 200 205 210 215 220 225 230 235 240 245 250 255 260 265
270 275 280 285 290 295 300 305 310 315 320 325 330 335 340 345 350 355
360 365 370 375 380 385 390 395 400 405 410 415 420 425 430 435 440 445
450 455 460 465 470 475 480 485 490 495 500 505 510 515 520 525 530 535
540 545 550 555 560 565 570 575 580 585 590 595 600 605 610 615 620 625
630 635 640 645 650 655 660 665 670 675 680 685 690 695 700 705 710 715
720 725 730 735 740 745 750 755 760 765 770 775 780 785 790 795 800 805
810 815 820 825 830 835 840 845 850 855 860 865 870 875 880 885 890 895
900 905 910 915 920 925 930 935 940 945 950 955 960 965 970 975 980 985
990 995]
为什么预测不准确?
简短版本: 由于聪明的 Breiman 提出的方法的性质。
更长的版本:
随机森林是非常有趣的学习者。
但是,您需要一点耐心才能调整它们。
forest.setp_param( oob_score = True, # set True to be able to read
# # oob-samples score
random_state = 2015 # set so as to keep retesting
# # possible / meaniningfull on
# # an otherwise randomised
# # learner construction
)
原则上,任何使用 .fit()
方法的尝试都会在幕后做大量工作来构建一组随机的决策树,使其成为 RandomForest,工作为您的数据集。
.fit()
的“质量”表示为.oob_score_
显示了已经使用的 oob
-样本的(准确)程度(Breiman 方法的真实部分) 在给定 RandomForest
的训练完成后。这有助于您估计“好”或“差[=73” =]" 你训练的 RandomForest
是否在可用数据集上执行。
然而,更重要的是(或应该是),学习者的概括能力如何——即,一旦处理未见过的问题,它的预测能力与现实的吻合程度如何例如。
这个可以通过 .score()
训练有素的 RandomForest
实例的方法进行测试。
RandomForest 是一个 "majority-vote" 预测器,为了感受这一点,请尝试显示随机树大军的内部状态:
def printLDF( aPopulationSET ):
LDF_example, LDF_counts = np.unique( aPopulationSET, return_counts = True )
GDF_sum_scaler = float( LDF_counts.sum() )
for i in xrange( LDF_example.shape[0] ):
print "{0: > 6d}: {1: > 6d} x {2: > 15.2f} {3: > 15.4f} % {4: > 15.1f} %".format( i, LDF_counts[i], LDF_example[i], 100 * LDF_counts[i] / GDF_sum_scaler, 100 * LDF_counts[:i].sum() / GDF_sum_scaler )
return
>>> printLDF( forest.estimators_[:].predict( anExample ) )
这将向您展示单个树的预测,用于整个基于森林的预测的多数票计算。
这意味着,除此之外,RandomForest
基本上不会预测 "visited" 值范围中的值 "outside"培训(不能设计"extrapolate")。
如何让它变得更好?
嗯,特征工程是关键。如果您知道 RandomForest 对于您的案例来说是一个可行的学习器,并且您认为它 观察到的预测能力很差 ,则首先要归咎于特征选择。
检查森林
检查学习者的内部状态 - 检查森林中的树木在做什么:
您可能会通过以下方式更深入地了解模型:
def prediction_up_dn_intervals( aPredictorMODEL, # >>> http://blog.datadive.net/prediction-intervals-for-random-forests/
X_, # aStateVECTOR: X_sampled
aPredictorOutputIDX = 0, # (4,2,2) -> singleQUAD ( LONG.TP/SL, SHORT.TP/SL ) <-- idxMAP( 'LONG', 'TP', 1 )
aRequiredPercentile = 95
):
err_dn = []
err_up = []
#-----------------------------------------------------------------------------------------------
if len( X_.shape ) == 1: # for a single X_example run
preds = []
for pred in aPredictorMODEL.estimators_:
preds.append( pred.predict( X_ )[0,aPredictorOutputIDX] ) # de-array-ification
err_dn.append( np.percentile( preds, ( 100 - aRequiredPercentile ) / 2. ) )
err_up.append( np.percentile( preds, 100 - ( 100 - aRequiredPercentile ) / 2. ) )
else:
#------------------------------------------------------------------------------------------
for x in xrange( len( X_ ) ): # for a multi X_example run
preds = []
for pred in aPredictorMODEL.estimators_:
preds.append( pred.predict( X_[x] )[0,aPredictorOutputIDX] ) # de-array-ification
err_dn.append( np.percentile( preds, ( 100 - aRequiredPercentile ) / 2. ) )
err_up.append( np.percentile( preds, 100 - ( 100 - aRequiredPercentile ) / 2. ) )
#-----------------------------------------------------------------------------------------------
return err_up, err_dn
#numba.jit( 'f8(<<OBJECT>>,f8[:,:],f8[:,:],i8,f8)' ) # <<OBJECT>> prevents JIT
def getPredictionsOnINTERVAL( aPredictorENGINE, # a MULTI-OBJECTIVE PREDICTOR -> a singleQUAD or a full 4-QUAD (16,0) <-(4,2,2)
X_,
y_GndTRUTH, # (4,2,2) -> (16,0) a MULTI-OBJECTIVE PREDICTOR
aPredictionIDX = 0, # (4,2,2) -> singleQUAD ( LONG.TP/SL, SHORT.TP/SL ) <-- idxMAP( 'LONG', 'TP', 1 )
percentile = 75
):
"""
|>>> getPredictionsOnINTERVAL( loc_PREDICTOR, X_sampled, y_sampled, idxMAP( "LONG", "TP", 1 ), 75 ) 1.0 +0:01:29.375000
|>>> getPredictionsOnINTERVAL( loc_PREDICTOR, X_sampled, y_sampled, idxMAP( "LONG", "TP", 1 ), 55 ) 0.9992532724237898 +0:03:59.922000
|>>> getPredictionsOnINTERVAL( loc_PREDICTOR, X_sampled, y_sampled, idxMAP( "LONG", "TP", 1 ), 50 ) 0.997100939998243 +0:09:16.328000
|>>> getPredictionsOnINTERVAL( loc_PREDICTOR, X_sampled, y_sampled, idxMAP( "LONG", "TP", 1 ), 5 ) 0.31375735746288325 +0:01:16.422000
"""
correct_on_interval = 0 # correct = 0. ____________________- faster to keep asINTEGER ... +=1 and only finally make DIV on FLOAT(s) in RET
#ruth = y_ # Y[idx[trainsize:]]
err_up, err_dn = prediction_up_dn_intervals( aPredictorENGINE, # ( rf,
X_, # X[idx[trainsize:]],
aPredictionIDX, # idxMAP( "LONG", "TP", 1 ),
percentile # percentile = 90
) # )
#-------------------------------------------------------------------# for a single X_ run
if ( len( X_.shape ) == 1 ):
if ( err_dn[0] <= y_GndTRUTH[aPredictionIDX] <= err_up[0] ):
return 1.
else:
return 0.
#-------------------------------------------------------------------# for a multi X_ run
for i, val in enumerate( y_GndTRUTH[:,aPredictionIDX] ): # enumerate( truth )
if err_dn[i] <= val <= err_up[i]:
correct_on_interval += 1
#-------------------------------------------------------------------
return correct_on_interval / float( y_GndTRUTH.shape[0] ) # print correct / len( truth )
def mapPredictionsOnINTERVAL( aPredictorENGINE, #
X_,
y_GndTRUTH,
aPredictionIDX = 0,
aPercentilleSTEP = 5
):
for aPercentille in xrange( aPercentilleSTEP, 100, aPercentilleSTEP ):
Quotient = getPredictionsOnINTERVAL( aPredictorENGINE, X_, y_GndTRUTH, aPredictionIDX, aPercentille )
print "{0: > 3d}-percentil {1: > 6.3f} %".format( aPercentille, 100 * Quotient )
"""
5% 0.313757
10% 0.420847
15% 0.510191
20% 0.628481
25% 0.719758
30% 0.839058
35% 0.909646
40% 0.963454
45% 0.986603
50% 0.997101
55% 0.999253
60% 0.999912
65% 1.000000 >>> RET/JIT
70% 1.000000 xxxxxxxxxxxxxx
75% 1.000000 xxxxxxxxxxxxxx ???? .fit( X_, y_[:,8:12] ) # .fit() on HORIZON-T0+3???? ... y_GndTRUTH.shape[1] v/s .predict().shape[1]
"""
if ( Quotient == 1 ):
return
您正在做几件事wrong/suboptimally:
- 您只有 200 棵 rows/observations,但您尝试训练 N=1000 棵树。这是没有意义的。你应该没有。树木<<没有。观察。 N=3-40 棵树中的任何地方。
- 您正在尝试学习一条线:您的数据是完全线性的(而 RF 用于正态分布的响应变量)。对于线性数据,使用更适合像线性回归这样的分类器会优于 RF 并给出完美的结果(事实上你所有的四个特征都是线性相关的,你可以扔掉任何三列,回归仍然会给出完美的结果)
然后,您正尝试预测其中一个端点,这是一个已知会产生偏差的问题,原因如下。考虑 RF 是 1000 棵树的集合,其行是随机选择的;有些树不会包含那些底部观察 [1,2,3,4] 或 [6,7,8,9] 或 [11,12,13,14] 或 [16,17,18,19] 因此必然不可能正确预测底部端点(如果它位于正态分布的尾部,这就不是什么大问题)。输出预测将是集合中每棵树的个体预测的平均值:
for i in range(1000):
forest.estimators_[i].predict([1,2,3,4])
或:np.hstack([ forest.estimators_[i].predict([1,2,3,4]) for i in range(1000) ])
然后你会看到很多 0 和 5,一些 10,甚至一些 15、20 和 25。所以你的最终预测将是某个数字 >0 并且可能 <5.
如果您的预测性能仍然很差,您可以让训练集具有相等数量的 class 0 和 class 1 数据,以赋予数据中信号更多的重要性。请参阅 以获得进一步的解释。
我正在学习机器学习,我想在相当复杂的数据集上使用 scikit-learn 的 RandomForestRegressor()
。不过,为了首先掌握它,我正在尝试通过一个基本示例来工作,如下所示:
import sklearn.ensemble as se
import numpy as np
forest = se.RandomForestRegressor(n_estimators=1000)
traindata = np.arange(1000).reshape(200,5)
forest = forest.fit(traindata[0::,1::],traindata[0::,0])
此时,我认为我所做的是:我创建了一个 200 行的矩阵,每行 5 个值,格式为 [ x, x+1, x+2, x+3, x+4 ]
,其中 x
是以下的倍数5(例如 [0,1,2,3,4]
、[5,6,7,8,9]
等)。
我已经让我的森林适应特征 [ x+1, x+2, x+3, x+4 ]
来预测 x
。这是我预测时会发生的事情:
forest.predict([1,2,3,4])
>> array([2.785])
这对我来说真的很不直观。考虑到 [1,2,3,4]
的特征值在 x = 0
的训练数据中,难道我的森林不能比 2.785 更准确地预测它吗?
我更进一步看到特征重要性如下:
forest.feature_importances_
>> array([0.26349716, 0.23664264, 0.23360533, 0.26625487])
对我来说,这并不意味着我所看到的方式存在重大偏差。我在这里错过了什么?
当我尝试你的代码时,我得到 AttributeError: 'module' object has no attribute 'arrange'
所以这是你的示例的可重现版本(一般来说,我建议明确创建单独的 X 和 Y 以避免犯愚蠢的错误,这是我在看到时的第一个想法你的问题)。正如您在下面看到的,随机森林分类器在训练集中对您的示例表现完美。随机森林回归器不会产生完美的预测。我不确定这是为什么,但这是一个起点。
import numpy as np
import sklearn.ensemble as se
import numpy as np
x = 0
X_train = []
Y_train = []
while x < 1000:
Y_train.append(x)
X_train.append([x + 1, x + 2, + x + 3, x + 4])
x += 5
forestregression = se.RandomForestRegressor(n_estimators=1000)
forestregression.fit(X_train, Y_train)
print(forestregression.predict(X_train))
[ 3.005 4.96 9.015 13.875 18.9 23.985 29.18 34.24
39.035 43.765 49.135 54.06 59.15 63.99 68.85 74.205
79.12 84.01 88.9 93.92 98.995 104.13 108.825 114.14
119.1 123.84 128.895 134.15 138.905 144.075 148.91 153.895
159.165 163.83 169.065 174.195 179.03 183.975 188.915 194.06
198.9 204.105 208.975 214.11 218.79 224.135 228.985 234.205
239.13 244.025 249.04 254.065 258.975 264.14 269.03 274.105
278.985 284. 288.935 294.055 299.04 304.025 308.895 313.92
318.82 324.1 328.92 334.18 338.985 344.07 348.905 353.94
359.115 364.11 369. 374.11 379.07 383.995 388.975 394.005
399.035 403.91 408.99 414.125 419.165 424.17 428.86 434.14
438.945 444.155 449.12 453.97 459.075 464.075 469.025 474.105
478.895 483.98 489.085 494.105 498.985 504.045 508.99 514.02
519.02 524.115 529.115 533.985 538.95 544.085 548.915 553.94
558.935 564.035 568.925 574.12 578.925 583.995 589.21 593.99
599.17 603.925 608.93 613.98 619.105 623.975 629.11 634.08
638.99 644.06 648.85 654.05 659.175 664.155 669.03 673.85
679.01 684.005 689.015 694.02 699.225 704.135 708.965 713.86
718.88 723.84 728.99 733.835 738.985 744.205 748.99 753.74
759.1 764.125 768.935 774.195 778.925 783.835 789.25 793.8
798.925 804.03 809.06 813.98 819.135 823.9 828.9 834.04
839.035 844.18 848.955 854.1 858.98 864.095 868.995 874.02
879.165 883.795 888.905 894.245 898.965 903.8 908.98 913.945
918.92 924.26 929.05 933.915 938.815 944.04 949.175 953.815
959.025 963.925 968.99 974.07 979.1 984.095 988.715 992.18 ]
forestclassifier = se.RandomForestClassifier(n_estimators=1000)
forestclassifier.fit(X_train, Y_train)
print(forestclassifier.predict(X_train))
[ 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85
90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175
180 185 190 195 200 205 210 215 220 225 230 235 240 245 250 255 260 265
270 275 280 285 290 295 300 305 310 315 320 325 330 335 340 345 350 355
360 365 370 375 380 385 390 395 400 405 410 415 420 425 430 435 440 445
450 455 460 465 470 475 480 485 490 495 500 505 510 515 520 525 530 535
540 545 550 555 560 565 570 575 580 585 590 595 600 605 610 615 620 625
630 635 640 645 650 655 660 665 670 675 680 685 690 695 700 705 710 715
720 725 730 735 740 745 750 755 760 765 770 775 780 785 790 795 800 805
810 815 820 825 830 835 840 845 850 855 860 865 870 875 880 885 890 895
900 905 910 915 920 925 930 935 940 945 950 955 960 965 970 975 980 985
990 995]
为什么预测不准确?
简短版本: 由于聪明的 Breiman 提出的方法的性质。
更长的版本:
随机森林是非常有趣的学习者。
但是,您需要一点耐心才能调整它们。
forest.setp_param( oob_score = True, # set True to be able to read
# # oob-samples score
random_state = 2015 # set so as to keep retesting
# # possible / meaniningfull on
# # an otherwise randomised
# # learner construction
)
原则上,任何使用 .fit()
方法的尝试都会在幕后做大量工作来构建一组随机的决策树,使其成为 RandomForest,工作为您的数据集。
.fit()
的“质量”表示为.oob_score_
显示了已经使用的 oob
-样本的(准确)程度(Breiman 方法的真实部分) 在给定 RandomForest
的训练完成后。这有助于您估计“好”或“差[=73” =]" 你训练的 RandomForest
是否在可用数据集上执行。
然而,更重要的是(或应该是),学习者的概括能力如何——即,一旦处理未见过的问题,它的预测能力与现实的吻合程度如何例如。
这个可以通过 .score()
训练有素的 RandomForest
实例的方法进行测试。
RandomForest 是一个 "majority-vote" 预测器,为了感受这一点,请尝试显示随机树大军的内部状态:
def printLDF( aPopulationSET ):
LDF_example, LDF_counts = np.unique( aPopulationSET, return_counts = True )
GDF_sum_scaler = float( LDF_counts.sum() )
for i in xrange( LDF_example.shape[0] ):
print "{0: > 6d}: {1: > 6d} x {2: > 15.2f} {3: > 15.4f} % {4: > 15.1f} %".format( i, LDF_counts[i], LDF_example[i], 100 * LDF_counts[i] / GDF_sum_scaler, 100 * LDF_counts[:i].sum() / GDF_sum_scaler )
return
>>> printLDF( forest.estimators_[:].predict( anExample ) )
这将向您展示单个树的预测,用于整个基于森林的预测的多数票计算。
这意味着,除此之外,RandomForest
基本上不会预测 "visited" 值范围中的值 "outside"培训(不能设计"extrapolate")。
如何让它变得更好?
嗯,特征工程是关键。如果您知道 RandomForest 对于您的案例来说是一个可行的学习器,并且您认为它 观察到的预测能力很差 ,则首先要归咎于特征选择。
检查森林
检查学习者的内部状态 - 检查森林中的树木在做什么:
您可能会通过以下方式更深入地了解模型:
def prediction_up_dn_intervals( aPredictorMODEL, # >>> http://blog.datadive.net/prediction-intervals-for-random-forests/
X_, # aStateVECTOR: X_sampled
aPredictorOutputIDX = 0, # (4,2,2) -> singleQUAD ( LONG.TP/SL, SHORT.TP/SL ) <-- idxMAP( 'LONG', 'TP', 1 )
aRequiredPercentile = 95
):
err_dn = []
err_up = []
#-----------------------------------------------------------------------------------------------
if len( X_.shape ) == 1: # for a single X_example run
preds = []
for pred in aPredictorMODEL.estimators_:
preds.append( pred.predict( X_ )[0,aPredictorOutputIDX] ) # de-array-ification
err_dn.append( np.percentile( preds, ( 100 - aRequiredPercentile ) / 2. ) )
err_up.append( np.percentile( preds, 100 - ( 100 - aRequiredPercentile ) / 2. ) )
else:
#------------------------------------------------------------------------------------------
for x in xrange( len( X_ ) ): # for a multi X_example run
preds = []
for pred in aPredictorMODEL.estimators_:
preds.append( pred.predict( X_[x] )[0,aPredictorOutputIDX] ) # de-array-ification
err_dn.append( np.percentile( preds, ( 100 - aRequiredPercentile ) / 2. ) )
err_up.append( np.percentile( preds, 100 - ( 100 - aRequiredPercentile ) / 2. ) )
#-----------------------------------------------------------------------------------------------
return err_up, err_dn
#numba.jit( 'f8(<<OBJECT>>,f8[:,:],f8[:,:],i8,f8)' ) # <<OBJECT>> prevents JIT
def getPredictionsOnINTERVAL( aPredictorENGINE, # a MULTI-OBJECTIVE PREDICTOR -> a singleQUAD or a full 4-QUAD (16,0) <-(4,2,2)
X_,
y_GndTRUTH, # (4,2,2) -> (16,0) a MULTI-OBJECTIVE PREDICTOR
aPredictionIDX = 0, # (4,2,2) -> singleQUAD ( LONG.TP/SL, SHORT.TP/SL ) <-- idxMAP( 'LONG', 'TP', 1 )
percentile = 75
):
"""
|>>> getPredictionsOnINTERVAL( loc_PREDICTOR, X_sampled, y_sampled, idxMAP( "LONG", "TP", 1 ), 75 ) 1.0 +0:01:29.375000
|>>> getPredictionsOnINTERVAL( loc_PREDICTOR, X_sampled, y_sampled, idxMAP( "LONG", "TP", 1 ), 55 ) 0.9992532724237898 +0:03:59.922000
|>>> getPredictionsOnINTERVAL( loc_PREDICTOR, X_sampled, y_sampled, idxMAP( "LONG", "TP", 1 ), 50 ) 0.997100939998243 +0:09:16.328000
|>>> getPredictionsOnINTERVAL( loc_PREDICTOR, X_sampled, y_sampled, idxMAP( "LONG", "TP", 1 ), 5 ) 0.31375735746288325 +0:01:16.422000
"""
correct_on_interval = 0 # correct = 0. ____________________- faster to keep asINTEGER ... +=1 and only finally make DIV on FLOAT(s) in RET
#ruth = y_ # Y[idx[trainsize:]]
err_up, err_dn = prediction_up_dn_intervals( aPredictorENGINE, # ( rf,
X_, # X[idx[trainsize:]],
aPredictionIDX, # idxMAP( "LONG", "TP", 1 ),
percentile # percentile = 90
) # )
#-------------------------------------------------------------------# for a single X_ run
if ( len( X_.shape ) == 1 ):
if ( err_dn[0] <= y_GndTRUTH[aPredictionIDX] <= err_up[0] ):
return 1.
else:
return 0.
#-------------------------------------------------------------------# for a multi X_ run
for i, val in enumerate( y_GndTRUTH[:,aPredictionIDX] ): # enumerate( truth )
if err_dn[i] <= val <= err_up[i]:
correct_on_interval += 1
#-------------------------------------------------------------------
return correct_on_interval / float( y_GndTRUTH.shape[0] ) # print correct / len( truth )
def mapPredictionsOnINTERVAL( aPredictorENGINE, #
X_,
y_GndTRUTH,
aPredictionIDX = 0,
aPercentilleSTEP = 5
):
for aPercentille in xrange( aPercentilleSTEP, 100, aPercentilleSTEP ):
Quotient = getPredictionsOnINTERVAL( aPredictorENGINE, X_, y_GndTRUTH, aPredictionIDX, aPercentille )
print "{0: > 3d}-percentil {1: > 6.3f} %".format( aPercentille, 100 * Quotient )
"""
5% 0.313757
10% 0.420847
15% 0.510191
20% 0.628481
25% 0.719758
30% 0.839058
35% 0.909646
40% 0.963454
45% 0.986603
50% 0.997101
55% 0.999253
60% 0.999912
65% 1.000000 >>> RET/JIT
70% 1.000000 xxxxxxxxxxxxxx
75% 1.000000 xxxxxxxxxxxxxx ???? .fit( X_, y_[:,8:12] ) # .fit() on HORIZON-T0+3???? ... y_GndTRUTH.shape[1] v/s .predict().shape[1]
"""
if ( Quotient == 1 ):
return
您正在做几件事wrong/suboptimally:
- 您只有 200 棵 rows/observations,但您尝试训练 N=1000 棵树。这是没有意义的。你应该没有。树木<<没有。观察。 N=3-40 棵树中的任何地方。
- 您正在尝试学习一条线:您的数据是完全线性的(而 RF 用于正态分布的响应变量)。对于线性数据,使用更适合像线性回归这样的分类器会优于 RF 并给出完美的结果(事实上你所有的四个特征都是线性相关的,你可以扔掉任何三列,回归仍然会给出完美的结果)
然后,您正尝试预测其中一个端点,这是一个已知会产生偏差的问题,原因如下。考虑 RF 是 1000 棵树的集合,其行是随机选择的;有些树不会包含那些底部观察 [1,2,3,4] 或 [6,7,8,9] 或 [11,12,13,14] 或 [16,17,18,19] 因此必然不可能正确预测底部端点(如果它位于正态分布的尾部,这就不是什么大问题)。输出预测将是集合中每棵树的个体预测的平均值:
for i in range(1000): forest.estimators_[i].predict([1,2,3,4])
或:np.hstack([ forest.estimators_[i].predict([1,2,3,4]) for i in range(1000) ])
然后你会看到很多 0 和 5,一些 10,甚至一些 15、20 和 25。所以你的最终预测将是某个数字 >0 并且可能 <5.
如果您的预测性能仍然很差,您可以让训练集具有相等数量的 class 0 和 class 1 数据,以赋予数据中信号更多的重要性。请参阅