Scikit learn 类权在线性回归和逻辑回归损失函数中的作用
我试图弄清楚损失函数公式到底是什么,以及在Scikit learn 类权在线性回归和逻辑回归损失函数中的作用,scikit-learn,svm,logistic-regression,Scikit Learn,Svm,Logistic Regression,我试图弄清楚损失函数公式到底是什么,以及在svm.svc、svm.linearSVC和linear\u model.logistic回归时如何手动计算它 对于平衡数据,假设您有一个经过训练的分类器:clf\u c。物流损失应为(我是否正确?) 我意识到logisticRegression具有predict\u log\u proba(),它精确地告诉您当数据平衡时: b, b0 = clf_c.coef_, clf_c.intercept_ w = np.ones(len(y))/len(y)
svm.svc
、svm.linearSVC
和linear\u model.logistic回归时如何手动计算它
对于平衡数据,假设您有一个经过训练的分类器:clf\u c
。物流损失应为(我是否正确?)
我意识到logisticRegression具有predict\u log\u proba()
,它精确地告诉您当数据平衡时:
b, b0 = clf_c.coef_, clf_c.intercept_
w = np.ones(len(y))/len(y)
-(clf_c.predict_log_proba(x[xrange(len(x)), np.floor((y+1)/2).astype(np.int8)]).mean() == logistic_loss(x,y,w,b,b0)
注意,np.floor((y+1)/2).astype(np.int8)
只是将y=(-1,1)映射到y=(0,1)
但当数据不平衡时,这就不起作用了
更重要的是,当数据处于平衡状态且class\u weight=None
与数据不平衡且class\u weight='auto'
时,您希望分类器(这里是logisticRegression)的性能类似(就损失函数值而言)。我需要有一种方法来计算这两种情况下的损失函数(没有正则化项),并对它们进行比较
简而言之,class\u weight='auto'
到底是什么意思?它是指class_weight={-1:(y==1.sum()/(y==1.sum(),1:1.}
还是说class_weight={-1:1./(y==1.sum(),1:1./(y==1.sum())
非常感谢您的帮助。我试着通读源代码,但我不是程序员,我被卡住了。
提前非常感谢。类权重
启发式
我对你关于class\u weight='auto'
启发式的第一个命题有点困惑,如下所示:
class_weight = {-1 : (y == 1).sum() / (y == -1).sum(),
1 : 1.}
与你的第二个命题相同,如果我们规范化它,使权重和为一
无论如何,要了解class\u weight=“auto”
的作用,请参见以下问题:
我将其复制到此处,以供以后比较:
这意味着每个类(在类中)的权重相等
到1除以该类在数据中出现的次数
(y) ,因此出现频率较高的类将获得较低的权重。这是
然后进一步除以所有逆类频率的平均值
请注意,这并非完全显而易见;)
此启发式已弃用,将在0.18中删除。它将被另一种启发式方法取代,class\u weight='balanced'
“平衡”启发式按类的频率的倒数成比例地对类进行加权
从文档中:
“平衡”模式使用y值自动调整
与输入数据中的类别频率成反比的权重:
n个样本/(n个类*np.bincount(y))
np.bincount(y)
是一个数组,元素i是类i样本的计数
这里有一段代码来比较这两种情况:
import numpy as np
from sklearn.datasets import make_classification
from sklearn.utils import compute_class_weight
n_classes = 3
n_samples = 1000
X, y = make_classification(n_samples=n_samples, n_features=20, n_informative=10,
n_classes=n_classes, weights=[0.05, 0.4, 0.55])
print("Count of samples per class: ", np.bincount(y))
balanced_weights = n_samples /(n_classes * np.bincount(y))
# Equivalent to the following, using version 0.17+:
# compute_class_weight("balanced", [0, 1, 2], y)
print("Balanced weights: ", balanced_weights)
print("'auto' weights: ", compute_class_weight("auto", [0, 1, 2], y))
输出:
Count of samples per class: [ 57 396 547]
Balanced weights: [ 5.84795322 0.84175084 0.60938452]
'auto' weights: [ 2.40356854 0.3459682 0.25046327]
损失函数
现在真正的问题是:如何使用这些权重来训练分类器
不幸的是,我没有一个完整的答案
对于SVC
和linearSVC
而言,docstring非常清晰
将SVC的i类参数C设置为i类权重[i]*C
因此,高权重意味着类的正则化程度较低,支持向量机更容易正确分类
我不知道他们如何使用逻辑回归。我将尝试研究它,但大多数代码都是liblinear或libsvm,我对它们不太熟悉
但是,请注意,class\u weight
中的权重不会直接影响方法,例如predict\u proba
。它们更改其输出,因为分类器优化了不同的损失函数。
不确定这是否清楚,所以这里有一个片段来解释我的意思(您需要为导入和变量定义运行第一个片段):
希望这能有所帮助。感谢您回来,也感谢您对重量的详细解释!所以根据第一个版本:w0=2*n_1/(n_0+n_1)和w1=2*n_0/(n_0+n_1),其中w0是类0的权重,n_0是类0中的样本数,n_1是类1中的样本数。超级奇怪的启发。也许我不太清楚,但您引用的较新版本也具有相同的权重(至少对于二进制情况)。我还发现这个讨论可能对其他读者也有帮助:我明白了。加权方案未包含在predict\u proba()
或predict\u log\u proba()
中:-(但也许我可以这样把它合并:loss\u unbalanced=loss\u balanced[index\u of_class\u 0]*w0+loss\u balanced[index\u of_class\u 1]*w1
。我会尝试一下,然后公布结果。不要难过;)。请注意,“平衡”启发式是不同的,即使是二进制情况。考虑<代码> y=(0, 0, 1)< /代码>,您将得到:<代码> Auto:(0.66666667,1,33333333)< /代码>和<代码>平衡:[0.75,1.5 ] < /代码>。至于predict_(log_)proba()
,将函数包装成使用权重的东西是相当简单的。
Count of samples per class: [ 57 396 547]
Balanced weights: [ 5.84795322 0.84175084 0.60938452]
'auto' weights: [ 2.40356854 0.3459682 0.25046327]
lr = LogisticRegression(class_weight="auto")
lr.fit(X, y)
# We get some probabilities...
print(lr.predict_proba(X))
new_lr = LogisticRegression(class_weight={0: 100, 1: 1, 2: 1})
new_lr.fit(X, y)
# We get different probabilities...
print(new_lr.predict_proba(X))
# Let's cheat a bit and hand-modify our new classifier.
new_lr.intercept_ = lr.intercept_.copy()
new_lr.coef_ = lr.coef_.copy()
# Now we get the SAME probabilities.
np.testing.assert_array_equal(new_lr.predict_proba(X), lr.predict_proba(X))