Scikit-Learn 与 Keras (Tensorflow) 用于多项逻辑回归

mat*_*252 5 python classification scikit-learn logistic-regression keras

我正在尝试使用 Keras 进行简单的多项式逻辑回归,但结果与标准 scikit-learn 方法相比有很大不同。

以虹膜数据为例:

import numpy as np
import pandas as pd
df = pd.read_csv("./data/iris.data", header=None)

from sklearn.model_selection import train_test_split
df_train, df_test = train_test_split(df, test_size=0.3, random_state=52)

X_train = df_train.drop(4, axis=1)
y_train = df_train[4]

X_test = df_test.drop(4, axis=1)
y_test = df_test[4]
Run Code Online (Sandbox Code Playgroud)

使用 scikit-learn:

from sklearn.linear_model import LogisticRegression

scikit_model = LogisticRegression(multi_class='multinomial', solver ='saga', max_iter=500)
scikit_model.fit(X_train, y_train)
Run Code Online (Sandbox Code Playgroud)

测试集上的平均加权 f1 分数:

y_test_pred = scikit_model.predict(X_test)

from sklearn.metrics import classification_report
print(classification_report(y_test, y_test_pred, scikit_model.classes_))
Run Code Online (Sandbox Code Playgroud)

0.96

然后使用 Keras:

from sklearn.preprocessing import LabelEncoder
from keras.utils import np_utils

# first we have to encode class values as integers
encoder = LabelEncoder()
encoder.fit(y_train)
y_train_encoded = encoder.transform(y_train)
Y_train = np_utils.to_categorical(y_train_encoded)
y_test_encoded = encoder.transform(y_test)
Y_test = np_utils.to_categorical(y_test_encoded)

from tensorflow import keras
from tensorflow.keras.models import Sequential 
from tensorflow.keras.layers import Dense, Activation
from keras.regularizers import l2

#model construction
input_dim = 4 # 4 variables
output_dim = 3 # 3 possible outputs

def classification_model():
    model = Sequential()
    model.add(Dense(output_dim, input_dim=input_dim, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
    return model

#training
keras_model = classification_model()
keras_model.fit(X_train, Y_train, epochs=500, verbose=0)
Run Code Online (Sandbox Code Playgroud)

测试集上的平均加权 f1 分数:

classes = np.argmax(keras_model.predict(X_test), axis = 1)
y_test_pred = encoder.inverse_transform(classes)

from sklearn.metrics import classification_report
print(classification_report(y_test, y_test_pred, encoder.classes_))
Run Code Online (Sandbox Code Playgroud)

0.89

是否可以使用 Keras 执行与 scikit-learn 相同(或至少尽可能多)的逻辑回归?

ale*_*s_t 3

我尝试运行你的示例并注意到一些潜在的来源:

  • 测试集非常小,只有 45 个实例。这意味着要使准确度从 0.89 提高到 0.96,模型只需正确预测另外三个实例即可。由于训练的随机性,您的 Keras 结果可能会出现很大的波动。
  • 正如 @meowongac /sf/answers/4175046571/所解释的,您正在使用不同的优化器。一点是scikit的算法会自动设置它的学习率。对于 Keras 中的 SGD,调整学习率和/或 epoch 数量可能会带来改进。
  • Scikit learn 默认使用 L2 正则化。

使用您的代码,通过运行学习率设置为 0.05 的 SGD,我能够获得从 0.89 到 0.96 的准确度。当切换到 Adam(同样具有相当高的学习率)时,我得到了更稳定的结果,范围从 0.92 到 0.96(尽管这更多是一个印象,因为我没有进行太多试验)。