如何使用Orange对数据进行分层?

时间:2015-04-30 16:27:56

标签: python decision-tree orange

寻找Orange专家的帮助。

我有大约600万行的数据集。为简单起见,我们只考虑两列。一个是正​​十进制数,并作为连续值导入。另一个是离散值(0或1),其中1到0的比率为30:1。

我正在使用分类树(我将其标记为“学习者”)来获取分类器。我正在尝试对我的数据集进行交叉验证,同时调整压倒性的30:1样本偏差。我已经尝试了几种变体来做到这一点,但无论我是否对数据进行分层,都会继续得到相同的结果。

下面是我的代码,我已经注释掉了我尝试过的各种行(使用True和False值进行分层):

import Orange
import os
import time
import operator

start = time.time()
print "Starting"
print ""

mydata = Orange.data.Table("testData.csv")

# This is used only for the test_with_indices method below
indicesCV = Orange.data.sample.SubsetIndicesCV(mydata)

# I only want the highest level classifier so max_depth=1
learner = Orange.classification.tree.TreeLearner(max_depth=1)

# These are the lines I've tried:
#res = Orange.evaluation.testing.cross_validation([learner], mydata, folds=5, stratified=True)
#res = Orange.evaluation.testing.proportion_test([learner], mydata, 0.8, 100, store_classifiers=1)
res = Orange.evaluation.testing.proportion_test([learner], mydata, learning_proportion=0.8, times=10, stratification=True, store_classifiers=1)
#res = Orange.evaluation.testing.test_with_indices([learner], mydata, indicesCV)

f = open('results.txt', 'a')
divString = "\n##### RESULTS (" + time.strftime("%Y-%m-%d %H:%M:%S") + ") #####"
f.write(divString)
f.write("\nAccuracy:     %.2f" %  Orange.evaluation.scoring.CA(res)[0])
f.write("\nPrecision:    %.2f" % Orange.evaluation.scoring.Precision(res)[0])
f.write("\nRecall:       %.2f" % Orange.evaluation.scoring.Recall(res)[0])
f.write("\nF1:           %.2f\n" % Orange.evaluation.scoring.F1(res)[0])

tree = learner(mydata)

f.write(tree.to_string(leaf_str="%V (%M out of %N)"))
print tree.to_string(leaf_str="%V (%M out of %N)")

end = time.time()
print "Ending"
timeStr = "Execution time: " + str((end - start) / 60) + " minutes"
f.write(timeStr)

f.close()

注意:似乎存在语法错误(分层与分层),但程序按原样运行,没有例外。此外,我知道文档显示像stratified = StratifiedIfPossible之类的东西,但由于某种原因,只有布尔值才适合我。

1 个答案:

答案 0 :(得分:0)

我不知道你在哪里调整30:1的偏见。如果通过分层:不,分层意味着你想要的相反(在某种意义上):分层样本是一个样本,其中类分布与人口中的大致相同"。因此,通过stratified=True,您告诉Orange确保它保持30:1的偏差。如果您不进行分层,样本分布可能会随机偏离。

您可能希望沿着这些方向做点什么:

# First, split the table into two tables with rows from different classes:

filt = Orange.data.filter.SameValue()
filt.position = -1
filt.value = 0
class0 = filt(mydata)
filt.value = 1
class1 = filt(mydata)

# Now class0 and class1 contain the rows from class 0 and 1, respectively
# Take 100 rows from each table:

sampler = Orange.data.sample.SubsetIndices2(p0=100)
ind = sampler(class0)
samp0 = class0.select(ind, 0)
ind = sampler(class1)
samp1 = class1.select(ind, 0)

# samp0 and samp1 now contain 100 rows from each class
# We have to merge them into a single table

balanced_data = Orange.data.Table(samp0)
balanced_data.extend(samp1)

在此之后,balanced_data将具有1:1的班级比率。

现在这可能正是你想要的,但是这个分类器会更喜欢少数类,所以它的性能会非常糟糕。根据我的经验,你想降低30:1的比例,但不要太低。