正如蒂姆在上面所写的,逻辑回归可以预测每个类别的概率。具体来说,您将得到
和
,其中和是异常类和正常类,是您的数据。根据贝叶定理:
根据
经验,P(Ca|D)
P(Cn|D)
CaCnDP(Ca|D)=P(D|Ca)P(Ca)P(D)
P(Cn|D)=P(D|Cn)P(Cn)P(D)
P(Ca)=Number of anomaliesTotal samples
因此,如果总样本数量发生显着变化而异常数量保持不变,那么您就有一个发生显着变化的因素(20/220 与 20/20020)。这可能会改变您从逻辑回归中获得的概率。我们需要更多地关注 200 和 20000 个样本来自哪里。如果您正在用不同的实验测试同一个系统,并且在一个实验中,您有 200 个异常中的 20 个,而在另一个实验中,20000 个中有 20 个异常,那么这些实验大相径庭。
由于您提到异常检测,我假设您正好有 20 个异常和许多样本(可能超过 20000 个),并且您想知道我应该将多少正常样本放入我的分类中。
使用逻辑回归,因为您正在拟合模型,从而使总成本最小化,您拥有的决策越倾向于将数据分类为该类的成员(多数类)。我认为这不是您在异常检测中通常想要的。想想寻找癌症患者或早期发现飞机发动机。在这些情况下,您甚至不想错过任何一个。在大样本不平衡的情况下,如果您使用逻辑回归而不进行进一步修改(例如应用权重或重采样),那么您的分类器将不是异常检测的最佳选择。在下图中,您可以看到类别不平衡对决策边界的影响。随着普通类成员数量的增加,决策边界会发生变化。



下图显示了两个类的平均异常概率的演变。

所以回到你原来的问题:是的,概率受样本量的影响并不是很直接。
我包括用于实验的 python 脚本。改变的一个关键因素是每个类别的方差。
from sklearn.linear_model import LogisticRegression
import numpy as np
from numpy.random import randn
import matplotlib.pyplot as plt
plt.close('all')
#%%
def genData(n0=20,m0=np.array([0,0]),s0=np.array([0.5, 0.5])/2, n1=200,m1=np.array ([1,1]),s1=np.array([0.5, 0.5])/2):
D0=np.concatenate ([randn(n0,1)*s0[0]+m0[0] , randn(n0,1)*s0[1]+m0[1]],1)
D1=np.concatenate ([randn(n1,1)*s1[0]+m1[0] , randn(n1,1)*s1[1]+m1[1]],1)
return D0,D1
#%%
n1v=[20,200,400,1000,2000,4000, 10000,20000]
nTrial=20
n0Pr=[]
n1Pr=[]
for n1 in n1v:
n0PrS=[]
n1PrS=[]
print(n1)
for iT in range(0,nTrial):
n0=20
D0,D1 = genData(n0=n0,n1=n1)
X=np.concatenate ( [D0,D1] , 0)
y=np.concatenate ( (np.zeros([n0,1]),np.ones([n1,1])),0)
class_weight =None
#class_weight = {0:1, 1:1./np.sqrt(n1)} # Use class weight to neutralize the impact of the class imbalance
clf = LogisticRegression(random_state=0, solver='lbfgs',multi_class='multinomial',class_weight=class_weight ).fit(X, y[:,0])
if iT==0:
plt.figure()
plt.plot(D0[:,0],D0[:,1],'.r',label='Anomaly')
plt.plot(D1[:,0],D1[:,1],'.b',label='Normal class')
plt.xlabel('Feature 1');plt.ylabel('Feature 2');
xx = np.linspace(-0.5,2)
plt.plot(xx,-xx*clf.coef_[0,0]/clf.coef_[0,1]-clf.intercept_/clf.coef_[0,1],label='Decision boundary')
plt.xlim(-0.5, 2);plt.ylim(-0.5, 2)
plt.legend()
plt.title('Number of anomaly samples: {0}, Number of normal samples: {1}'.format(n0,n1))
plt.show()
#%%
pr0=clf.predict_log_proba(D0)
pr1=clf.predict_log_proba(D1)
n0PrS.append(np.exp(np.mean(pr0,0)[0]))
n1PrS.append(np.exp(np.mean(pr1,0)[0]))
n0Pr.append(np.mean(n0PrS))
n1Pr.append(np.mean(n1PrS))
#%%
plt.figure()
plt.plot(n1v,n0Pr,label='Gemetric Mean Probablity for members of Minority class')
plt.plot(n1v,n1Pr,label='Gemetric Mean Probablity for members of Majority class')
plt.xlabel('Sample size of the majority class')
plt.ylabel('Probablity of being anomaly')
plt.legend()