使用Iris数据集重现LASSO / Logistic回归导致R与Python
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了使用Iris数据集重现LASSO / Logistic回归导致R与Python,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4303字,纯文字阅读大概需要7分钟。
内容图文
![使用Iris数据集重现LASSO / Logistic回归导致R与Python](/upload/InfoBanner/zyjiaocheng/811/b747e906bfd3491fa73f060c50526b6c.jpg)
我试图在Python中重现以下R结果.在这种特殊情况下,R预测技能低于Python技能,但在我的经验中通常不是这种情况(因此想要在Python中重现结果的原因),所以请在此处忽略该细节.
目的是预测花种(‘versicolor’0或’virginica’1).我们有100个标记样本,每个样本由4个花特征组成:萼片长度,萼片宽度,花瓣长度,花瓣宽度.我将数据分为训练(60%的数据)和测试集(40%的数据).将10倍交叉验证应用于训练集以搜索最佳λ(在scikit-learn中优化的参数是“C”).
我在R中使用glmnet,alpha设置为1(对于LASSO惩罚),对于python,scikit-learn的LogisticRegressionCV函数与“liblinear”解算器(唯一可以与L1惩罚一起使用的求解器).交叉验证中使用的评分指标在两种语言之间是相同的.然而,不知何故,模型结果是不同的(每个特征的截距和系数变化相当大).
R代码
library(glmnet)
library(datasets)
data(iris)
y <- as.numeric(iris[,5])
X <- iris[y!=1, 1:4]
y <- y[y!=1]-2
n_sample = NROW(X)
w = .6
X_train = X[0:(w * n_sample),] # (60, 4)
y_train = y[0:(w * n_sample)] # (60,)
X_test = X[((w * n_sample)+1):n_sample,] # (40, 4)
y_test = y[((w * n_sample)+1):n_sample] # (40,)
# set alpha=1 for LASSO and alpha=0 for ridge regression
# use class for logistic regression
set.seed(0)
model_lambda <- cv.glmnet(as.matrix(X_train), as.factor(y_train),
nfolds = 10, alpha=1, family="binomial", type.measure="class")
best_s <- model_lambda$lambda.1se
pred <- as.numeric(predict(model_lambda, newx=as.matrix(X_test), type="class" , s=best_s))
# best lambda
print(best_s)
# 0.04136537
# fraction correct
print(sum(y_test==pred)/NROW(pred))
# 0.75
# model coefficients
print(coef(model_lambda, s=best_s))
#(Intercept) -14.680479
#Sepal.Length 0
#Sepal.Width 0
#Petal.Length 1.181747
#Petal.Width 4.592025
Python代码
from sklearn import datasets
from sklearn.linear_model import LogisticRegressionCV
from sklearn.preprocessing import StandardScaler
import numpy as np
iris = datasets.load_iris()
X = iris.data
y = iris.target
X = X[y != 0] # four features. Disregard one of the 3 species.
y = y[y != 0]-1 # two species: 'versicolor' (0), 'virginica' (1). Disregard one of the 3 species.
n_sample = len(X)
w = .6
X_train = X[:int(w * n_sample)] # (60, 4)
y_train = y[:int(w * n_sample)] # (60,)
X_test = X[int(w * n_sample):] # (40, 4)
y_test = y[int(w * n_sample):] # (40,)
X_train_fit = StandardScaler().fit(X_train)
X_train_transformed = X_train_fit.transform(X_train)
clf = LogisticRegressionCV(n_jobs=2, penalty='l1', solver='liblinear', cv=10, scoring = ‘accuracy’, random_state=0)
clf.fit(X_train_transformed, y_train)
print clf.score(X_train_fit.transform(X_test), y_test) # score is 0.775
print clf.intercept_ #-1.83569557
print clf.coef_ # [ 0, 0, 0.65930981, 1.17808155] (sepal length, sepal width, petal length, petal width)
print clf.C_ # optimal lambda: 0.35938137
解决方法:
以上示例中有一些不同之处:
>系数的比例
> glmnet(https://cran.r-project.org/web/packages/glmnet/glmnet.pdf)标准化数据和“系数总是以原始比例返回”.因此,在调用glmnet之前,您没有扩展数据.
> Python代码标准化数据,然后适合标准化数据.在这种情况下,coefs是标准化的规模,而不是原始规模.这使得示例之间的系数不可比较.
>默认情况下,LogisticRegressionCV使用分层折叠. glmnet使用k-fold.
>他们拟合不同的方程式.请注意,scikit-learn logistic(http://scikit-learn.org/stable/modules/linear_model.html#logistic-regression)与后勤方面的正规化相符. glmnet将正则化置于惩罚之上.
>选择正则化优势来尝试 – glmnet默认为100 lambda来尝试. scikit LogisticRegressionCV默认为10.由于scikit求解方程,范围介于1e-4和1e4之间(http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegressionCV.html#sklearn.linear_model.LogisticRegressionCV).
>宽容是不同的.在我遇到的一些问题中,收紧公差显着改变了系数.
> glmnet默认阈值为1e-7
> LogisticRegressionCV默认值为1e-4
>即使在使它们相同之后,它们也可能无法衡量同样的事情.我不知道什么是liblinear措施. glmnet – “每个内部坐标下降循环一直持续到任何系数更新后物镜的最大变化小于零偏差的阈值.”
您可能想要尝试打印正则化路径以查看它们是否非常相似,只是停止在不同的强度上.然后你可以研究为什么.
即使改变了你可以改变的东西,但不是以上所有,你可能得不到相同的系数或结果.虽然您在不同的软件中解决了同样的问题,但软件如何解决问题可能会有所不同.我们看到不同的尺度,不同的方程,不同的默认值,不同的求解器等.
内容总结
以上是互联网集市为您收集整理的使用Iris数据集重现LASSO / Logistic回归导致R与Python全部内容,希望文章能够帮你解决使用Iris数据集重现LASSO / Logistic回归导致R与Python所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。