为什么 LogisticRegression 每次都给出相同的结果,即使随机状态不同?
Why does LogisticRegression give the same result every time, even with different random state?
我不是逻辑回归方面的专家,但我认为在使用 lgfgs
解决它时它正在做优化,为 objective 函数找到局部最小值。但每次我 运行 它使用 scikit-learn
,它返回相同的结果,即使我给它提供不同的随机状态。
下面是重现我的问题的代码。
首先通过生成数据设置问题
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn import datasets
# generate data
X, y = datasets.make_classification(n_samples=1000,
n_features=10,
n_redundant=4,
n_clusters_per_class=1,
random_state=42)
# Set up the test/training data
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25)
其次,训练模型并检查结果
# Set up a different random state each time
rand_state = np.random.randint(1000)
print(rand_state)
model = LogisticRegression(max_iter=1000,
solver='lbfgs',
random_state=rand_state)
model.fit(X_train,y_train)
y_pred = model.predict(X_test)
conf_mat = metrics.confusion_matrix(y_test, y_pred)
print(y_pred[:20],"\n", conf_mat)
我每次 运行 都会得到相同的 y_pred
(显然是混淆矩阵),即使我使用的 lbfgs
解算器每个 运行。我很困惑,因为我认为这是一个随机求解器,它沿着梯度向下移动到局部最小值。
也许我没有正确随机化初始状态?我还没能从 the documentation.
弄明白
相关问题的讨论
有一个相关的问题,我在研究中没有找到:
Does logistic regression always find global optimum, assuming that the optimisation converges?
答案是代价函数是凸的,所以如果数值解是良性的,它会找到一个全局最小值。也就是说,您的优化算法不会陷入一堆局部最小值:它每次都会达到相同的(全局)最小值(可能取决于您选择的求解器?)。
然而,在有人指出的评论中,根据您选择的求解器,有时您无法获得相同的解决方案,这取决于 random_state
参数。至少,我认为这有助于解决。
首先,让我来回答是什么让这个问题早先因为重复而关闭:逻辑回归问题(没有完美分离)有一个全局最优解,所以没有局部最优解会陷入不同的随机种子.如果求解器收敛令人满意,它将在全局最优值上收敛。所以只有当求解器无法收敛时 random_state
才会产生影响。
现在,LogisticRegression
的参数 random_state
的 the documentation 声明:
Used when solver
== ‘sag’, ‘saga’ or ‘liblinear’ to shuffle the data. [...]
所以你的代码,用solver='lbfgs'
,确实没有预期的效果。
不难让sag
和saga
不收敛,不同的random_state
以不同的解结束;为方便起见,设置 max_iter=1
。 liblinear
显然不使用 random_state
除非解决对偶,因此也设置 dual=True
承认不同的解决方案。我发现这要归功于 this comment on a github issue(本期的其余部分可能值得阅读更多背景知识)。
我不是逻辑回归方面的专家,但我认为在使用 lgfgs
解决它时它正在做优化,为 objective 函数找到局部最小值。但每次我 运行 它使用 scikit-learn
,它返回相同的结果,即使我给它提供不同的随机状态。
下面是重现我的问题的代码。
首先通过生成数据设置问题
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn import datasets
# generate data
X, y = datasets.make_classification(n_samples=1000,
n_features=10,
n_redundant=4,
n_clusters_per_class=1,
random_state=42)
# Set up the test/training data
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25)
其次,训练模型并检查结果
# Set up a different random state each time
rand_state = np.random.randint(1000)
print(rand_state)
model = LogisticRegression(max_iter=1000,
solver='lbfgs',
random_state=rand_state)
model.fit(X_train,y_train)
y_pred = model.predict(X_test)
conf_mat = metrics.confusion_matrix(y_test, y_pred)
print(y_pred[:20],"\n", conf_mat)
我每次 运行 都会得到相同的 y_pred
(显然是混淆矩阵),即使我使用的 lbfgs
解算器每个 运行。我很困惑,因为我认为这是一个随机求解器,它沿着梯度向下移动到局部最小值。
也许我没有正确随机化初始状态?我还没能从 the documentation.
弄明白相关问题的讨论
有一个相关的问题,我在研究中没有找到:
Does logistic regression always find global optimum, assuming that the optimisation converges?
答案是代价函数是凸的,所以如果数值解是良性的,它会找到一个全局最小值。也就是说,您的优化算法不会陷入一堆局部最小值:它每次都会达到相同的(全局)最小值(可能取决于您选择的求解器?)。
然而,在有人指出的评论中,根据您选择的求解器,有时您无法获得相同的解决方案,这取决于 random_state
参数。至少,我认为这有助于解决。
首先,让我来回答是什么让这个问题早先因为重复而关闭:逻辑回归问题(没有完美分离)有一个全局最优解,所以没有局部最优解会陷入不同的随机种子.如果求解器收敛令人满意,它将在全局最优值上收敛。所以只有当求解器无法收敛时 random_state
才会产生影响。
现在,LogisticRegression
的参数 random_state
的 the documentation 声明:
Used when
solver
== ‘sag’, ‘saga’ or ‘liblinear’ to shuffle the data. [...]
所以你的代码,用solver='lbfgs'
,确实没有预期的效果。
不难让sag
和saga
不收敛,不同的random_state
以不同的解结束;为方便起见,设置 max_iter=1
。 liblinear
显然不使用 random_state
除非解决对偶,因此也设置 dual=True
承认不同的解决方案。我发现这要归功于 this comment on a github issue(本期的其余部分可能值得阅读更多背景知识)。