【问题标题】:Training a decision tree using id3 algorithm by sklearnsklearn 使用 id3 算法训练决策树
【发布时间】:2018-07-07 04:15:24
【问题描述】:

我正在尝试使用 id3 算法训练决策树。 目的是获取所选特征的索引,估计出现率,并建立一个总混淆矩阵。

算法应将数据集拆分为训练集和测试集,并使用 4 折交叉验证。

我是这个主题的新手,我已经阅读了关于 sklearn 的教程和关于学习过程的理论,但我仍然很困惑。

我尝试过的操作:

from sklearn.model_selection import cross_val_predict,KFold,cross_val_score, 
train_test_split, learning_curve
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import confusion_matrix


X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=1)
clf = DecisionTreeClassifier(criterion='entropy', random_state=0)
clf.fit(X_train,y_train)
results = cross_val_score(estimator=clf, X=X_train, y=y_train, cv=4)
print("Accuracy: %0.2f (+/- %0.2f)" % (results.mean(), results.std()))
y_pred = cross_val_predict(estimator=clf, X=x, y=y, cv=4)
conf_mat = confusion_matrix(y,y_pred)
print(conf_mat)
dot_data = tree.export_graphviz(clf, out_file='tree.dot') 

我有一些问题:

  1. 如何获取训练中使用的特征索引列表?我必须穿过 clf 中的树吗?找不到任何 api 方法来检索它们。

  2. 我必须使用“fit”、“cross_val_score”和“cross_val_predict”吗?似乎他们所有人都进行了某种学习过程,但我无法仅从其中一个人那里获得 clf 拟合、准确性和混淆矩阵。

  3. 我是否必须使用测试集进行估计或数据集折叠的分区?

【问题讨论】:

    标签: scikit-learn python-3.5 decision-tree cross-validation confusion-matrix


    【解决方案1】:
    1. 要检索训练过程中使用的特征列表,您可以通过以下方式从 x 中获取列:

      feature_list = x.columns

      如您所知,并非每个特征都可用于预测。你可以看到,在训练模型之后,使用

      clf.feature_importances_

      feature_list 中特征的索引与 feature_importances 列表中的相同。

    2. 如果您使用交叉验证,则无法立即检索分数。
      cross_val_score 达成了交易,但获得分数的更好方法是使用 cross_validate。它的工作方式与 cross_val_score 相同,但您可以检索更多分数值,只需使用 make_score 创建所需的每个分数并传递它,这里是一个示例:

      from sklearn.model_selection import train_test_split,  cross_validate
      from sklearn.metrics import classification_report, confusion_matrix, accuracy_score, f1_score, precision_score, make_scorer, recall_score 
      import pandas as pd, numpy as np       
      
      x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
      dtc = DecisionTreeClassifier()
      dtc_fit = dtc.fit(x_train, y_train)
      
      def tn(y_true, y_pred): return confusion_matrix(y_true, y_pred)[0, 0]
      def fp(y_true, y_pred): return confusion_matrix(y_true, y_pred)[0, 1]
      def fn(y_true, y_pred): return confusion_matrix(y_true, y_pred)[1, 0]
      def tp(y_true, y_pred): return confusion_matrix(y_true, y_pred)[1, 1]
      
      scoring = {
          'tp' : make_scorer(tp), 
          'tn' : make_scorer(tn), 
          'fp' : make_scorer(fp), 
          'fn' : make_scorer(fn), 
          'accuracy' : make_scorer(accuracy_score),
          'precision': make_scorer(precision_score),
          'f1_score' : make_scorer(f1_score),
          'recall'   : make_scorer(recall_score)
      }
      
      sc = cross_validate(dtc_fit, x_train, y_train, cv=5, scoring=scoring)
      
      print("Accuracy: %0.2f (+/- %0.2f)" % (sc['test_accuracy'].mean(), sc['test_accuracy'].std() * 2))
      print("Precision: %0.2f (+/- %0.2f)" % (sc['test_precision'].mean(), sc['test_precision'].std() * 2))
      print("f1_score: %0.2f (+/- %0.2f)" % (sc['test_f1_score'].mean(), sc['test_f1_score'].std() * 2))
      print("Recall: %0.2f (+/- %0.2f)" % (sc['test_recall'].mean(), sc['test_recall'].std() * 2), "\n")
      
      stp = math.ceil(sc['test_tp'].mean())
      stn = math.ceil(sc['test_tn'].mean())
      sfp = math.ceil(sc['test_fp'].mean())
      sfn = math.ceil(sc['test_fn'].mean())
      
      confusion_matrix = pd.DataFrame(
          [[stn, sfp], [sfn, stp]],
          columns=['Predicted 0', 'Predicted 1'],
          index=['True 0', 'True 1']
      )
      print(conf_m)
      
    3. 当您使用 cross_val 函数时,函数本身会为测试和训练创建折叠。如果您想管理训练折叠和测试折叠,您可以使用 K_Fold 类自己完成。
      如果您需要保持班级平衡,总是需要通过 DecisionTreeClassifier 获得良好的评分,则必须使用 StratifiedKFold。如果要随机打乱折叠中包含的值,可以使用 StratifiedShuffleSplit。举个例子:

      from sklearn.tree import DecisionTreeClassifier
      from sklearn.model_selection import StratifiedShuffleSplit
      from sklearn.metrics import classification_report, confusion_matrix, accuracy_score, f1_score, precision_score, make_scorer, recall_score
      import pandas as pd, numpy as np
      
      precision = []; recall = []; f1score = []; accuracy = []
      
      sss = StratifiedShuffleSplit(n_splits=10, test_size=0.2)    
      dtc = DecisionTreeClassifier()
      
      for train_index, test_index in sss.split(X, y):
          X_train, X_test = X.iloc[train_index], X.iloc[test_index]
          y_train, y_test = y.iloc[train_index], y.iloc[test_index]
      
          dtc.fit(X_train, y_train)
          pred = dtc.predict(X_test)
      
          precision.append(precision_score(y_test, pred))
          recall.append(recall_score(y_test, pred))
          f1score.append(f1_score(y_test, pred))
          accuracy.append(accuracy_score(y_test, pred))   
      
      print("Accuracy: %0.2f (+/- %0.2f)" % (np.mean(accuracy),np.std(accuracy) * 2))
      print("Precision: %0.2f (+/- %0.2f)" % (np.mean(precision),np.std(precision) * 2))
      print("f1_score: %0.2f (+/- %0.2f)" % (np.mean(f1score),np.std(f1score) * 2))
      print("Recall: %0.2f (+/- %0.2f)" % (np.mean(recall),np.std(recall) * 2))
      

    我希望我已经回答了你需要的一切!

    【讨论】:

    • 非常感谢! 1.我的意思是在结果中获得选择的特征,所以我假设我可以使用 feature_importances_ 吗? 2.如果我使用“accurancy”参数进行评分,它如何改变算法?我是否必须提供一个评分函数来使用那里的熵来实现 gainInfo 以使其成为“id3”? 3. cross_validate 是否保持类平衡?
    • 1.你是对的。只看feature_importances_,您可以选择预测中最重要的特征,以降低预测模型的复杂性(此步骤也称为特征选择) 2. 当您评估模型时,您不会'不仅要使用准确率,还要使用准确率、召回率和其他分数。这个分数可以改变你的特征选择过程 3. cross_validate 支持类平衡。使用我发布的解决方案,您也可以检索自己的混淆矩阵。很快,我已经向您展示了 cross_validate 在这一点上的工作原理
    • 你是用pandas做pd的吗?我收到一个错误“AttributeError:模块'pandas'没有属性'DataFrame'”
    • 帮了大忙,谢谢,还有一个问题——你说准确率、召回率和其他分数与学习过程有关,那为什么要在拟合之后才选择它们呢?它们是否仍然与 id3 相关?
    • 是的,我使用 pandas 作为 pd,抱歉我忘了包含它。无论如何,在验证步骤之后测量精度、召回率和其他分数。这些在每个预测模型中都是相关的,例如 ID3。某些模型,例如 DecitionTree,会受到过度拟合 (en.wikipedia.org/wiki/Overfitting) 的影响。精度为 0.99 的模型可能过拟合。只看分数就可以看到这些东西
    猜你喜欢
    • 2015-06-27
    • 2018-08-14
    • 2012-05-28
    • 2019-06-01
    • 2016-05-24
    • 2015-02-18
    • 1970-01-01
    • 2016-08-09
    • 2015-07-30
    相关资源
    最近更新 更多