我如何取消对决策树中的特征进行编码以查看重要特征?
How may I un-encode the features from a decision tree to see the important features?
我有一个正在使用的数据集。我正在将它们从分类特征转换为我的决策树的数字特征。转换发生在整个数据帧上,包含以下几行:
le = LE()
df = df.apply(le.fit_transform)
我稍后将这些数据分成训练和测试数据如下:
target = ['label']
df_y = df['label']
df_x = df.drop(target, axis=1)
# Split into training and testing data
train_x, test_x, train_y, test_y = tts(df_x, df_y, test_size=0.3, random_state=42)
然后我将它传递给训练决策树的方法:
def Decision_Tree_Classifier(train_x, train_y, test_x, test_y, le):
print " - Candidate: Decision Tree Classifier"
dec_tree_classifier = DecisionTreeClassifier(random_state=0) # Load Module
dec_tree_classifier.fit(train_x, train_y) # Fit
accuracy = dec_tree_classifier.score(test_x, test_y) # Acc
predicted = dec_tree_classifier.predict(test_x)
mse = mean_squared_error(test_y, predicted)
tree_feat = list(le.inverse_transform(dec_tree_classifier.tree_.feature))
print "Tree Features:"
print tree_feat
print "Tree Thresholds:"
print dec_tree_classifier.tree_.threshold
scores = cross_val_score(dec_tree_classifier, test_x, test_y.values.ravel(), cv=10)
return (accuracy, mse, scores.mean(), scores.std())
在上述方法中,我传递了最初用于对数据帧进行编码的 LabelEncoder 对象。我有行
tree_feat = list(le.inverse_transform(dec_tree_classifier.tree_.feature))
尝试将特征转换回其原始分类表示,但我不断收到此堆栈跟踪错误:
File "<ipython-input-6-c2005f8661bc>", line 1, in <module>
runfile('main.py', wdir='/Users/mydir)
File "/Users/me/anaconda2/lib/python2.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 668, in runfile
execfile(filename, namespace)
File "/Users/me/anaconda2/lib/python2.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 100, in execfile
builtins.execfile(filename, *where)
File "/Users/me/mydir/main.py", line 125, in <module>
main() # Run main routine
File "candidates.py", line 175, in get_baseline
dec_tre_acc = Decision_Tree_Classifier(train_x, train_y, test_x, test_y, le)
File "candidates.py", line 40, in Decision_Tree_Classifier
tree_feat = list(le.inverse_transform(dec_tree_classifier.tree_.feature))
File "/Users/me/anaconda2/lib/python2.7/site-packages/sklearn/preprocessing/label.py", line 281, in inverse_transform
"y contains previously unseen labels: %s" % str(diff))
ValueError: y contains previously unseen labels: [-2]
我需要更改什么才能查看实际功能本身?
当你这样做时:
df = df.apply(le.fit_transform)
您正在为所有列使用单个 LabelEncoder
实例。当调用fit()
或fit_transform()
时,le
会忘记之前的数据,只学习当前的数据。因此,您拥有的 le
仅存储有关它看到的最后一列的信息,而不是所有列。
有多种方法可以解决这个问题:
您可以维护多个 LabelEncoder 对象(每列一个)。在这里查看这个出色的答案:
Label encoding across multiple columns in scikit-learn
from collections import defaultdict
d = defaultdict(LabelEncoder)
df = df.apply(lambda x: d[x.name].fit_transform(x))
如果你想保留一个对象来处理所有列,你可以使用 OrdinalEncoder
如果你安装了最新版本的 scikit-learn。
from sklearn.preprocessing import OrdinalEncoder
enc = OrdinalEncoder()
df = enc.fit_transform(df)
但是仍然没有解决这个错误,因为tree_.feature
不对应于特征的值,而是对应于该节点用于分裂的索引(df
中的列)。因此,如果数据中有 3 个特征(列)(无论该列中的值如何),tree_.feature
可以具有以下值:
0, 1, 2, -2
-2是一个特殊的占位符值,表示该节点是叶节点,因此不使用任何特征来分割任何东西。
tree_.threshold
将包含与您的数据值相对应的值。但那将是浮动的,所以你必须根据类别到数字的转换进行转换。
查看此示例以详细了解树结构:
我有一个正在使用的数据集。我正在将它们从分类特征转换为我的决策树的数字特征。转换发生在整个数据帧上,包含以下几行:
le = LE()
df = df.apply(le.fit_transform)
我稍后将这些数据分成训练和测试数据如下:
target = ['label']
df_y = df['label']
df_x = df.drop(target, axis=1)
# Split into training and testing data
train_x, test_x, train_y, test_y = tts(df_x, df_y, test_size=0.3, random_state=42)
然后我将它传递给训练决策树的方法:
def Decision_Tree_Classifier(train_x, train_y, test_x, test_y, le):
print " - Candidate: Decision Tree Classifier"
dec_tree_classifier = DecisionTreeClassifier(random_state=0) # Load Module
dec_tree_classifier.fit(train_x, train_y) # Fit
accuracy = dec_tree_classifier.score(test_x, test_y) # Acc
predicted = dec_tree_classifier.predict(test_x)
mse = mean_squared_error(test_y, predicted)
tree_feat = list(le.inverse_transform(dec_tree_classifier.tree_.feature))
print "Tree Features:"
print tree_feat
print "Tree Thresholds:"
print dec_tree_classifier.tree_.threshold
scores = cross_val_score(dec_tree_classifier, test_x, test_y.values.ravel(), cv=10)
return (accuracy, mse, scores.mean(), scores.std())
在上述方法中,我传递了最初用于对数据帧进行编码的 LabelEncoder 对象。我有行
tree_feat = list(le.inverse_transform(dec_tree_classifier.tree_.feature))
尝试将特征转换回其原始分类表示,但我不断收到此堆栈跟踪错误:
File "<ipython-input-6-c2005f8661bc>", line 1, in <module>
runfile('main.py', wdir='/Users/mydir)
File "/Users/me/anaconda2/lib/python2.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 668, in runfile
execfile(filename, namespace)
File "/Users/me/anaconda2/lib/python2.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 100, in execfile
builtins.execfile(filename, *where)
File "/Users/me/mydir/main.py", line 125, in <module>
main() # Run main routine
File "candidates.py", line 175, in get_baseline
dec_tre_acc = Decision_Tree_Classifier(train_x, train_y, test_x, test_y, le)
File "candidates.py", line 40, in Decision_Tree_Classifier
tree_feat = list(le.inverse_transform(dec_tree_classifier.tree_.feature))
File "/Users/me/anaconda2/lib/python2.7/site-packages/sklearn/preprocessing/label.py", line 281, in inverse_transform
"y contains previously unseen labels: %s" % str(diff))
ValueError: y contains previously unseen labels: [-2]
我需要更改什么才能查看实际功能本身?
当你这样做时:
df = df.apply(le.fit_transform)
您正在为所有列使用单个 LabelEncoder
实例。当调用fit()
或fit_transform()
时,le
会忘记之前的数据,只学习当前的数据。因此,您拥有的 le
仅存储有关它看到的最后一列的信息,而不是所有列。
有多种方法可以解决这个问题:
您可以维护多个 LabelEncoder 对象(每列一个)。在这里查看这个出色的答案:
Label encoding across multiple columns in scikit-learn
from collections import defaultdict d = defaultdict(LabelEncoder) df = df.apply(lambda x: d[x.name].fit_transform(x))
如果你想保留一个对象来处理所有列,你可以使用
OrdinalEncoder
如果你安装了最新版本的 scikit-learn。from sklearn.preprocessing import OrdinalEncoder enc = OrdinalEncoder() df = enc.fit_transform(df)
但是仍然没有解决这个错误,因为tree_.feature
不对应于特征的值,而是对应于该节点用于分裂的索引(df
中的列)。因此,如果数据中有 3 个特征(列)(无论该列中的值如何),tree_.feature
可以具有以下值:
0, 1, 2, -2
-2是一个特殊的占位符值,表示该节点是叶节点,因此不使用任何特征来分割任何东西。
tree_.threshold
将包含与您的数据值相对应的值。但那将是浮动的,所以你必须根据类别到数字的转换进行转换。
查看此示例以详细了解树结构: