StratifiedKFold vs StratifiedShuffleSplit vs StratifiedKFold + Shuffle
StratifiedKFold vs StratifiedShuffleSplit vs StratifiedKFold + Shuffle
StratifiedKFold、StratifiedShuffleSplit、StratifiedKFold + Shuffle 之间有什么区别?
我什么时候应该使用每一个?当我获得更好的准确度分数时?
为什么我没有得到类似的结果?
我已经把我的代码和结果。我正在使用朴素贝叶斯和 10x10 交叉验证。
#######SKF FOR LOOP########
from sklearn.cross_validation import StratifiedKFold
for i in range(10):
skf = StratifiedKFold(y, n_folds=10, shuffle=True)
scoresSKF2 = cross_validation.cross_val_score(clf, x, y , cv=skf)
print(scoresSKF2)
print("Accuracy SKF_NB: %0.2f (*/- %0.2f)" % (scoresSKF2.mean(), scoresSKF2.std()* 2))
print("")
[ 0.1750503 0.16834532 0.16417051 0.18205424 0.1625758 0.1750939
0.15495808 0.1712963 0.17096494 0.16918166]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.16297787 0.17956835 0.17309908 0.17686093 0.17239388 0.16093615
0.16970223 0.16956019 0.15473776 0.17208358]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.17102616 0.16719424 0.1733871 0.16560877 0.166041 0.16122508
0.16767852 0.17042824 0.18719212 0.1677307 ]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.17275079 0.16633094 0.16906682 0.17570687 0.17210511 0.15515747
0.16594391 0.18113426 0.16285135 0.1746953 ]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.1764875 0.17035971 0.16186636 0.1644547 0.16632977 0.16469229
0.17635155 0.17158565 0.17849899 0.17005223]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.16815177 0.16863309 0.17309908 0.17368725 0.17152758 0.16093615
0.17143683 0.17158565 0.16574906 0.16511898]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.16786433 0.16690647 0.17309908 0.17022504 0.17066128 0.16613695
0.17259324 0.17737269 0.16256158 0.17643645]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.16297787 0.16402878 0.17684332 0.16791691 0.16950621 0.1716267
0.18328997 0.16984954 0.15792524 0.17701683]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.16958896 0.16633094 0.17165899 0.17080208 0.16026567 0.17538284
0.17490604 0.16840278 0.17502173 0.16511898]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.17275079 0.15625899 0.17713134 0.16762839 0.18278949 0.16729269
0.16449841 0.17303241 0.16111272 0.1610563 ]
Accuracy SKF_NB: 0.17 (*/- 0.02)
#####StratifiedKFold + Shuffle######
from sklearn.utils import shuffle
for i in range(10):
X, y = shuffle(x, y, random_state=i)
skf = StratifiedKFold(y, 10)
scoresSKF2 = cross_validation.cross_val_score(clf, X, y , cv=skf)
print(scoresSKF2)
print("Accuracy SKF_NB: %0.2f (*/- %0.2f)" % (scoresSKF2.mean(), scoresSKF2.std()* 2))
print("")
[ 0.16700201 0.15913669 0.16359447 0.17772649 0.17297141 0.16931523
0.17172593 0.18576389 0.17125471 0.16134649]
Accuracy SKF_NB: 0.17 (*/- 0.02)
[ 0.02874389 0.02705036 0.02592166 0.02740912 0.02714409 0.02687085
0.02891009 0.02922454 0.0260794 0.02814858]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.0221328 0.02848921 0.02361751 0.02942874 0.02598903 0.02947125
0.02804279 0.02719907 0.02376123 0.02205456]
Accuracy SKF_NB: 0.03 (*/- 0.01)
[ 0.02788158 0.02848921 0.03081797 0.03289094 0.02829916 0.03293846
0.02862099 0.02633102 0.03245436 0.02843877]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02874389 0.0247482 0.02448157 0.02625505 0.02483396 0.02860445
0.02948829 0.02604167 0.02665894 0.0275682 ]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.0221328 0.02705036 0.02476959 0.02510098 0.02454519 0.02687085
0.02254987 0.02199074 0.02492031 0.02524666]
Accuracy SKF_NB: 0.02 (*/- 0.00)
[ 0.02615694 0.03079137 0.02102535 0.03029429 0.02252382 0.02889338
0.02197167 0.02604167 0.02752825 0.02843877]
Accuracy SKF_NB: 0.03 (*/- 0.01)
[ 0.02673182 0.02676259 0.03197005 0.03115984 0.02512273 0.03236059
0.02688638 0.02372685 0.03216459 0.02698781]
Accuracy SKF_NB: 0.03 (*/- 0.01)
[ 0.0258695 0.02964029 0.03081797 0.02740912 0.02916546 0.02976018
0.02717548 0.02922454 0.02694871 0.0275682 ]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.03506755 0.0247482 0.02592166 0.02740912 0.02772163 0.02773765
0.02948829 0.0234375 0.03332367 0.02118398]
Accuracy SKF_NB: 0.03 (*/- 0.01)
######StratifiedShuffleSplit##########
from sklearn.cross_validation import StratifiedShuffleSplit
for i in range(10):
sss = StratifiedShuffleSplit(y, 10, test_size=0.1, random_state=0)
scoresSSS = cross_validation.cross_val_score(clf, x, y , cv=sss)
print(scoresSSS)
print("Accuracy SKF_NB: %0.2f (*/- %0.2f)" % (scoresSSS.mean(), scoresSSS.std()* 2))
print("")
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
很难说哪个更好。选择应该更多地与您的建模策略和目标有关,但是社区强烈倾向于使用 K 折交叉验证来进行模型选择和性能评估。我将尝试让您对指导您选择采样技术的两个主要概念有一些直觉:Stratification 和 Cross Validation/Random Split.
另外请记住,您可以将这些采样技术用于两个截然不同的目标:模型选择和性能估计。
分层 通过保持数据集 labels/targets 之间的平衡或比率来工作。因此,如果您的整个数据集有两个标签(例如阳性和阴性)并且它们的比例为 30/70,并且您分成 10 个子样本,则每个分层子样本应保持相同的比例。推理:因为机器学习模型的性能通常对样本平衡非常敏感,所以使用这种策略通常会使模型对子样本更稳定。
拆分与随机拆分。拆分只是拆分,通常是为了具有单独的训练和测试子样本。但是,将第一个 X% 用于子样本,将剩余的 X% 用于另一个子样本可能不是一个好主意,因为它会引入非常高的偏差。通过为子采样引入随机性,随机分割开始发挥作用。
K 折交叉验证与随机拆分。 K 折包括创建 K 个子样本。因为您现在有更多的样本(而不是 2 个),所以您可以分离一个子样本用于测试,其余子样本用于训练,对每个可能的 testing/training 折叠组合执行此操作并对结果进行平均。这称为交叉验证。进行 K 折交叉验证就像进行(非随机)拆分 k 次,然后取平均值。小样本可能不会受益于 k 折交叉验证,而大样本通常总是受益于交叉验证。随机拆分是一种更有效(更快)的估计方式,但可能比 k 折交叉验证更容易出现抽样偏差。将分层和随机拆分相结合是一种尝试,旨在拥有一种有效且高效的抽样策略,以保留标签分布。
- StratifiedKFold:我在这里打乱两个数组,但保留每一行及其标签。
- StratifiedKFOld + Shuffle:这里我在交叉验证之前对两个数组进行洗牌。因此,每一行不再 link 编辑到其标签。这就是为什么准确率与 1 相比如此糟糕的原因。
- StratifiedShuffleSplit:这里的准确性仍然很差,与 2 相同,因为数组已经被 2 打乱,因此行和它们的标签之间不再有 link。但是当我 运行 它 "standalone" 准确度和 1 一样好。所以基本上 1 和 3 做同样的事情。
StratifiedKFold、StratifiedShuffleSplit、StratifiedKFold + Shuffle 之间有什么区别? 我什么时候应该使用每一个?当我获得更好的准确度分数时? 为什么我没有得到类似的结果? 我已经把我的代码和结果。我正在使用朴素贝叶斯和 10x10 交叉验证。
#######SKF FOR LOOP########
from sklearn.cross_validation import StratifiedKFold
for i in range(10):
skf = StratifiedKFold(y, n_folds=10, shuffle=True)
scoresSKF2 = cross_validation.cross_val_score(clf, x, y , cv=skf)
print(scoresSKF2)
print("Accuracy SKF_NB: %0.2f (*/- %0.2f)" % (scoresSKF2.mean(), scoresSKF2.std()* 2))
print("")
[ 0.1750503 0.16834532 0.16417051 0.18205424 0.1625758 0.1750939
0.15495808 0.1712963 0.17096494 0.16918166]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.16297787 0.17956835 0.17309908 0.17686093 0.17239388 0.16093615
0.16970223 0.16956019 0.15473776 0.17208358]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.17102616 0.16719424 0.1733871 0.16560877 0.166041 0.16122508
0.16767852 0.17042824 0.18719212 0.1677307 ]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.17275079 0.16633094 0.16906682 0.17570687 0.17210511 0.15515747
0.16594391 0.18113426 0.16285135 0.1746953 ]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.1764875 0.17035971 0.16186636 0.1644547 0.16632977 0.16469229
0.17635155 0.17158565 0.17849899 0.17005223]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.16815177 0.16863309 0.17309908 0.17368725 0.17152758 0.16093615
0.17143683 0.17158565 0.16574906 0.16511898]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.16786433 0.16690647 0.17309908 0.17022504 0.17066128 0.16613695
0.17259324 0.17737269 0.16256158 0.17643645]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.16297787 0.16402878 0.17684332 0.16791691 0.16950621 0.1716267
0.18328997 0.16984954 0.15792524 0.17701683]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.16958896 0.16633094 0.17165899 0.17080208 0.16026567 0.17538284
0.17490604 0.16840278 0.17502173 0.16511898]
Accuracy SKF_NB: 0.17 (*/- 0.01)
[ 0.17275079 0.15625899 0.17713134 0.16762839 0.18278949 0.16729269
0.16449841 0.17303241 0.16111272 0.1610563 ]
Accuracy SKF_NB: 0.17 (*/- 0.02)
#####StratifiedKFold + Shuffle######
from sklearn.utils import shuffle
for i in range(10):
X, y = shuffle(x, y, random_state=i)
skf = StratifiedKFold(y, 10)
scoresSKF2 = cross_validation.cross_val_score(clf, X, y , cv=skf)
print(scoresSKF2)
print("Accuracy SKF_NB: %0.2f (*/- %0.2f)" % (scoresSKF2.mean(), scoresSKF2.std()* 2))
print("")
[ 0.16700201 0.15913669 0.16359447 0.17772649 0.17297141 0.16931523
0.17172593 0.18576389 0.17125471 0.16134649]
Accuracy SKF_NB: 0.17 (*/- 0.02)
[ 0.02874389 0.02705036 0.02592166 0.02740912 0.02714409 0.02687085
0.02891009 0.02922454 0.0260794 0.02814858]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.0221328 0.02848921 0.02361751 0.02942874 0.02598903 0.02947125
0.02804279 0.02719907 0.02376123 0.02205456]
Accuracy SKF_NB: 0.03 (*/- 0.01)
[ 0.02788158 0.02848921 0.03081797 0.03289094 0.02829916 0.03293846
0.02862099 0.02633102 0.03245436 0.02843877]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02874389 0.0247482 0.02448157 0.02625505 0.02483396 0.02860445
0.02948829 0.02604167 0.02665894 0.0275682 ]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.0221328 0.02705036 0.02476959 0.02510098 0.02454519 0.02687085
0.02254987 0.02199074 0.02492031 0.02524666]
Accuracy SKF_NB: 0.02 (*/- 0.00)
[ 0.02615694 0.03079137 0.02102535 0.03029429 0.02252382 0.02889338
0.02197167 0.02604167 0.02752825 0.02843877]
Accuracy SKF_NB: 0.03 (*/- 0.01)
[ 0.02673182 0.02676259 0.03197005 0.03115984 0.02512273 0.03236059
0.02688638 0.02372685 0.03216459 0.02698781]
Accuracy SKF_NB: 0.03 (*/- 0.01)
[ 0.0258695 0.02964029 0.03081797 0.02740912 0.02916546 0.02976018
0.02717548 0.02922454 0.02694871 0.0275682 ]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.03506755 0.0247482 0.02592166 0.02740912 0.02772163 0.02773765
0.02948829 0.0234375 0.03332367 0.02118398]
Accuracy SKF_NB: 0.03 (*/- 0.01)
######StratifiedShuffleSplit##########
from sklearn.cross_validation import StratifiedShuffleSplit
for i in range(10):
sss = StratifiedShuffleSplit(y, 10, test_size=0.1, random_state=0)
scoresSSS = cross_validation.cross_val_score(clf, x, y , cv=sss)
print(scoresSSS)
print("Accuracy SKF_NB: %0.2f (*/- %0.2f)" % (scoresSSS.mean(), scoresSSS.std()* 2))
print("")
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
[ 0.02743286 0.02858793 0.02512273 0.02281259 0.02541149 0.02743286
0.02570026 0.02454519 0.02570026 0.02858793]
Accuracy SKF_NB: 0.03 (*/- 0.00)
很难说哪个更好。选择应该更多地与您的建模策略和目标有关,但是社区强烈倾向于使用 K 折交叉验证来进行模型选择和性能评估。我将尝试让您对指导您选择采样技术的两个主要概念有一些直觉:Stratification 和 Cross Validation/Random Split.
另外请记住,您可以将这些采样技术用于两个截然不同的目标:模型选择和性能估计。
分层 通过保持数据集 labels/targets 之间的平衡或比率来工作。因此,如果您的整个数据集有两个标签(例如阳性和阴性)并且它们的比例为 30/70,并且您分成 10 个子样本,则每个分层子样本应保持相同的比例。推理:因为机器学习模型的性能通常对样本平衡非常敏感,所以使用这种策略通常会使模型对子样本更稳定。
拆分与随机拆分。拆分只是拆分,通常是为了具有单独的训练和测试子样本。但是,将第一个 X% 用于子样本,将剩余的 X% 用于另一个子样本可能不是一个好主意,因为它会引入非常高的偏差。通过为子采样引入随机性,随机分割开始发挥作用。
K 折交叉验证与随机拆分。 K 折包括创建 K 个子样本。因为您现在有更多的样本(而不是 2 个),所以您可以分离一个子样本用于测试,其余子样本用于训练,对每个可能的 testing/training 折叠组合执行此操作并对结果进行平均。这称为交叉验证。进行 K 折交叉验证就像进行(非随机)拆分 k 次,然后取平均值。小样本可能不会受益于 k 折交叉验证,而大样本通常总是受益于交叉验证。随机拆分是一种更有效(更快)的估计方式,但可能比 k 折交叉验证更容易出现抽样偏差。将分层和随机拆分相结合是一种尝试,旨在拥有一种有效且高效的抽样策略,以保留标签分布。
- StratifiedKFold:我在这里打乱两个数组,但保留每一行及其标签。
- StratifiedKFOld + Shuffle:这里我在交叉验证之前对两个数组进行洗牌。因此,每一行不再 link 编辑到其标签。这就是为什么准确率与 1 相比如此糟糕的原因。
- StratifiedShuffleSplit:这里的准确性仍然很差,与 2 相同,因为数组已经被 2 打乱,因此行和它们的标签之间不再有 link。但是当我 运行 它 "standalone" 准确度和 1 一样好。所以基本上 1 和 3 做同样的事情。