Sklearn DecisionTreeClassifier每次运行可对不同结果进行F评分

时间:2018-11-22 16:00:20

标签: python machine-learning scikit-learn

我正在尝试使用Python训练决策树分类器。我正在使用MinMaxScaler()缩放数据,并使用f1_score作为评估指标。奇怪的是,我注意到我的模型在每次运行时都会以模式给出不同的结果。

我的代码中的

data(2000, 7) pandas.DataFrame,有6个要素列,最后一列是目标值。第1列,第3列和第5列是分类数据。

以下代码是我对数据进行预处理和格式化的步骤:

import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import f1_score


# Data Preprocessing Step
# =============================================================================
data = pd.read_csv("./data/train.csv")

X = data.iloc[:, :-1]
y = data.iloc[:, 6]

# Choose which columns are categorical data, and convert them to numeric data.
labelenc = LabelEncoder()
categorical_data = list(data.select_dtypes(include='object').columns)

for i in range(len(categorical_data)):
    X[categorical_data[i]] = labelenc.fit_transform(X[categorical_data[i]])


# Convert categorical numeric data to one-of-K data, and change y from Series to ndarray.
onehotenc = OneHotEncoder()
X = onehotenc.fit_transform(X).toarray()
y = y.values

X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2)

min_max_scaler = MinMaxScaler()
X_train_scaled = min_max_scaler.fit_transform(X_train)
X_val_scaled = min_max_scaler.fit_transform(X_val)


下一个代码用于实际的决策树模型训练:

dectree = DecisionTreeClassifier(class_weight='balanced')
dectree = dectree.fit(X_train_scaled, y_train)
predictions = dectree.predict(X_val_scaled)
score = f1_score(y_val, predictions, average='macro')

print("Score is = {}".format(score))


我得到的输出(即分数)有所不同,但有规律。例如,它将在0.390.42范围内的数据之间循环。

在某些迭代中,我什至得到UndefinedMetricWarning,它声称“ F分数定义不正确,并且在没有可预测样本的标签中被设置为0.0。”

在对该社区和Google进行了一些搜索之后,我熟悉UndefinedMetricWarning的含义。我想我可能要针对以下两个问题:


  1. 为什么每次迭代的输出都不同?在预处理阶段发生了我不知道的事情?

  2. 我也尝试过将F分数与其他数据拆分一起使用,但是我总是得到警告。这是无法预防的吗?

谢谢。

1 个答案:

答案 0 :(得分:2)

您正在将数据集分为训练和测试,这会随机将训练和测试的集合划分。因此,当您每次使用不同的训练数据训练模型,并使用不同的测试数据进行测试时,您将获得一定的F分数,具体取决于模型的训练程度。

为了每次运行都复制结果,请使用random_state参数。它将保持随机数状态,每次运行时都会为您提供相同的随机数。这表明随机数以相同顺序生成。这可以是任何数字。

#train test split
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=13)

#Decision tree model
dectree = DecisionTreeClassifier(class_weight='balanced', random_state=2018)