【问题标题】:Decision tree with a probability target具有概率目标的决策树
【发布时间】:2020-12-03 04:33:18
【问题描述】:

我目前正在研究一个模型,以预测一个人感染冠状病毒后的死亡概率。 我正在使用带有分类变量的荷兰数据集:感染日期、死亡或治愈、性别、年龄组等。 建议使用我已经构建的决策树。 由于我是决策树的新手,我需要一些帮助。 我想让预测(目标变量)以概率(%)表示,而不是二进制输出。 我怎样才能做到这一点? 我也想通过自己输入数据来玩弄样本,看看结果是什么。 例如:让我们以 40 岁、男性等为例,计算其生存机会。 我怎样才能做到这一点? 我附上了以下代码:

from pandas import read_csv
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier 
import pandas as pd
import random as rnd

filename = '/Users/sef/Downloads/pima-indians-diabetes.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(filename, names=names)
array = dataframe.values
X = array[:,0:8]
Y = array[:,8]

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=1234)

model = DecisionTreeClassifier()

model.fit(X_train, Y_train)

DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
            max_features=None, max_leaf_nodes=None,
            min_impurity_decrease=0.0, min_impurity_split=None,
            min_samples_leaf=1, min_samples_split=2,
            min_weight_fraction_leaf=0.0, presort=False, random_state=None,
            splitter='best')

rnd.seed(123458)
X_new = X[rnd.randrange(X.shape[0])]
X_new = X_new.reshape(1,8)
YHat = model.predict_proba(X_new)


df = pd.DataFrame(X_new, columns = names[:-1])
df["predicted"] = YHat
print(df)

【问题讨论】:

    标签: python scikit-learn decision-tree


    【解决方案1】:

    您可以使用DecisionTreeClassifier 的“predict_proba”方法来计算概率而不是二进制分类值。

    为了测试您可以手动创建的单个数据,您必须创建一个 X_test 数据形状的数组(只是它只有一个条目)。然后你可以将它与 model.predict(array) 或 model.predict_proba(array) 一起使用。

    顺便说一下,您的树目前对检索概率没有用处。有一篇文章很好的解释了这个问题:https://rpmcruz.github.io/machine%20learning/2018/02/09/probabilities-trees.html

    因此您可以通过定义树的 max_depths 来修复您的代码:

    from pandas import read_csv
    from sklearn.model_selection import train_test_split
    from sklearn.tree import DecisionTreeClassifier 
    import pandas as pd
    import random as rnd
    
    filename = 'pima-indians-diabetes.csv'
    names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
    dataframe = read_csv(filename, names=names)
    array = dataframe.values
    X = array[:,0:8]
    Y = array[:,8]
    
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=1234)
    
    model = DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=1,
                max_features=None, max_leaf_nodes=None,
                min_impurity_decrease=0.0, min_impurity_split=None,
                min_samples_leaf=1, min_samples_split=2,
                min_weight_fraction_leaf=0.0, presort=False, random_state=None,
                splitter='best')
    
    model.fit(X_train, Y_train)
    
    rnd.seed(123458)
    X_new = X[rnd.randrange(X.shape[0])]
    X_new = X_new.reshape(1,8)
    YHat = model.predict_proba(X_new)
    
    
    df = pd.DataFrame(X_new, columns = names[:-1])
    df["predicted"] = list(YHat)
    print(df)
    

    【讨论】:

    • 我在使用predict_proba函数时出现以下错误,ValueError: Wrong number of items passed 3, placement意味着1
    • 能否提供一个可重现的调试示例?
    • 清除控制台中的变量并重新运行代码后,我得到一个不同的错误:raise ValueError("Classification metrics can't handle a mix of {0}" ValueError: Classification metrics can't handle多类和连续多输出目标的混合。您对可重现的示例是什么意思?
    • 将其转换为列表就可以了。非常感谢金!
    • 我看到了,会深入研究。
    【解决方案2】:

    决策树还可以估计实例属于特定类的概率。使用如下的 predict_proba() 和您的训练特征数据来返回您想要预测的各种类别的概率。 model.predict() 返回概率最高的类

    model.predict_proba()
    
    

    【讨论】:

    • 谢谢普拉克斯!但是,我收到以下错误: ValueError: Wrong number of items passed 3, placement 意味着 1
    【解决方案3】:

    使用名为 predict_proba 的函数 model.predict_proba(X_test)

    对于你问题的第二部分,这是你必须做的。 使用与您训练过的完全相同的列名创建您自己的自定义数据集。 从 csv 读取数据并应用相同的编码器值(如果有)。

    您还可以以更有效的方式保存标签编码器对象。

    label = preprocessing.LabelEncoder() 
    label_encoded_columns=['Date_statistics_type', 'Agegroup', 'Sex', 'Province', 'Hospital_admission', 'Municipal_health_service', 'Deceased']
    for col in label_encoded_columns:
        dataframe[col] = dataframe[col].astype(str)
    Label_Encoder = labelencoder.fit(dataframe[label_encoded_columns].values.flatten())
    Encoded_Array = (Label_Encoder.transform(dataframe[label_encoded_columns].values.flatten())).reshape(dataframe[label_encoded_columns].shape)
    
    LE_Dataframe=pd.DataFrame(Encoded_DataFrame,columns=label_encoded_columns,index=dataframe.index)
    LE_mapping = dict(zip(Label_Encoder.classes_,Label_Encoder.transform(Label_Encoder.classes_).tolist()))
     #####This should give you dictionary in the form for all your list of values.
     ##### for eg: {'Apple':0,'Banana':1}
    

    对于问题的第二部分,可以有两种方法。 第一个非常简单,您可以在其中使用 X_test 的值来为您提供结果预测。 model.predict(X_test.iloc[0:30]) ###前 30 行 model.predict_proba(X_test.iloc[0:30])

    在第二个中,如果您正在谈论引入新数据,那么在这种情况下,您将不得不再次对原始数据进行标签编码。

    如果该数据不存在,它可能会给你从未见过的值错误。

    在这种情况下参考这个link

    【讨论】:

    • 谢谢,这样更清楚了!现在尝试使用 predict_proba 函数。
    猜你喜欢
    • 2016-03-27
    • 2015-01-04
    • 2015-01-13
    • 2012-08-04
    • 2016-09-04
    • 2020-11-09
    • 2014-06-09
    • 2019-05-24
    • 1970-01-01
    相关资源
    最近更新 更多