#导入必要的包
import numpy as np import pandas as pd import matplotlib as mpl import matplotlib.pyplot as plt %matplotlib inline
#?先定义联系函数sigmoid函数 def sigmoid(inX): return 1.0/(1+np.exp(-inX))
In [7]:
#自定义一个归一化函数(此函数的前提是我的数据是一个矩阵) def regularize(xMat): inMat = xMat.copy()#创建一个副本,这样对inmat进行操作不会影响到xmat inMeans = np.mean(inMat,axis = 0) #求均值 inVar = np.std(inMat,axis = 0) #求标准差 inMat = (inMat - inMeans)/inVar #归一化 return inMat
#编写批量梯度下降的自定义函数 def logisticReg_0(dataSet,eps=0.01,numIt=50000): xMat = np.mat(dataSet.iloc[:, :-1].values) yMat = np.mat(dataSet.iloc[:, -1].values).T xMat = regularize(xMat) m,n = xMat.shape weights = np.zeros((n,1)) for k in range(numIt): grad = xMat.T * (sigmoid(xMat * weights) - yMat) / m#加入了sigmoid函数 weights = weights - eps * grad return weights
testSet = pd.read_table(‘testSet.txt‘, header=None) testSet.head()#一个二分类数据集
ws = logisticReg_0(testSet, eps=0.01,numIt=500)
ws
#提取Xmat与Ymat xMat = np.mat(testSet.iloc[:, :-1].values) yMat = np.mat(testSet.iloc[:, -1].values).T xMat = regularize(xMat)#对xmat归一化,ymat本身就是o和1 所以不用归一化了
(xMat * ws).A.flatten()#求得方程本身并转换成array再转换成行向量
#进?步乘以sigmoid函数之后得到的是y取得1的概率?? p = sigmoid(xMat * ws).A.flatten() p
#我们可令p>0.5时预测输出值为1,反之为0,得到最终y值预测结果 for i, j in enumerate(p): if j < 0.5: p[i] = 0 else: p[i] = 1
p
testSet[3]=p
testSet
. .
#首先封装一个准确率判断模型 def accuracyCalculation(dataSet): m = dataSet.shape[0] #如果后一列数据=前一列数据,对返回为True的行计数 res = (dataSet.iloc[:, -1] == dataSet.iloc[:, -2]).value_counts() acc = res.loc[True] / m print("Model accuracy is :{}".format(acc) ) return acc
accuracyCalculation(testSet) #准确率%92
train_error = (np.fabs(yMat.A.flatten() - p)).sum() train_error #判断错误个数又8个
train_error_rate = train_error / yMat.shape[0] train_error_rate #相对的 错误率为8
#参数分别为 数据集 模型 学习率 迭代次数 def logisticAcc(dataSet, method, eps=0.01, numIt=50000): weights = method(dataSet,eps=eps,numIt=numIt) p = sigmoid(xMat * ws).A.flatten() for i, j in enumerate(p): if j < 0.5: p[i] = 0 else:p[i] = 1 train_error = (np.fabs(yMat.A.flatten() - p)).sum() trainAcc = 1 - train_error / yMat.shape[0] return trainAcc
import time %time logisticAcc(testSet,logisticReg_0)
def logisticReg_1(dataSet,eps=0.01,numIt=50000): dataSet = dataSet.sample(numIt, replace=True) dataSet.index = range(dataSet.shape[0]) xMat = np.mat(dataSet.iloc[:, :-1].values) yMat = np.mat(dataSet.iloc[:, -1].values).T xMat = regularize(xMat) m,n = xMat.shape weights = np.zeros((n,1)) for i in range(m): grad = xMat[i].T * (sigmoid(xMat[i] * weights) - yMat[i]) weights = weights - eps * grad return weights
logisticReg_1(testSet)
Out[38]:
%time logisticAcc(testSet,logisticReg_1)
from sklearn.linear_model import LogisticRegression clf = LogisticRegression() clf.fit(testSet.iloc[:, :-1], testSet.iloc[:, -1])
Out[40]:
clf.coef_
clf.intercept_
clf.predict(testSet.iloc[:, :-1])
from sklearn.metrics import accuracy_score accuracy_score(testSet.iloc[:, -1], clf.predict(testSet.iloc[:, :-1]))
LogisticRegression, LogisticRegressionCV,其中LogisticRegression和LogisticRegressionCV的主要区别是 LogisticRegressionCV使?了交叉验证来选择正则化系数C。?LogisticRegression需要??每次指定 ?个正则化系数。除了交叉验证,以及选择正则化系数C以外, LogisticRegression和LogisticRegressionCV的使??法基本相同。
为"I1"和"I2".分别对应L1的正则化和L2的正则化,默认是L2的正则化。 在调参时如果我们主要的?的只是为了解决过拟合,?般penalty选择L2正则化就够了。但是如 果选择L2正则化发现还是过拟合,即预测效果差的时候,就可以考虑L1正则化。另外,如果模型 的特征?常多,我们希望?些不重要的特征系数归零,从?让模型系数稀疏化的话,也可以使? L1正则化。 penalty参数的选择会影响我们损失函数优化算法的选择。即参数solver的选择,如果是L2正则 化,那么4种可选的算法{‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’}都可以选择。但是如果penalty是L1 正则化的话,就只能选择‘liblinear’了。这是因为L1正则化的损失函数不是连续可导的,? {‘newton-cg’, ‘lbfgs’,‘sag’}这三种优化算法时都需要损失函数的?阶或者?阶连续导数。 ?‘liblinear’并没有这个依赖。
分别是: liblinear:使?了开源的liblinear库实现,内部使?了坐标轴下降法来迭代优化损失函数。 lbfgs:拟?顿法的?种,利?损失函数?阶导数矩阵即海森矩阵来迭代优化损失函数。 newton-cg:也是?顿法家族的?种,利?损失函数?阶导数矩阵即海森矩阵来迭代优化损失函 数。 sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅? ?部分的样本来计算梯度,适合于样本数据多的时候。 从上?的描述可以看出,newton-cg, lbfgs和sag这三种优化算法时都需要损失函数的?阶或者 ?阶连续导数,因此不能?于没有连续导数的L1正则化,只能?于L2正则化。?liblinear通吃L1 正则化和L2正则化。 同时,sag每次仅仅使?了部分样本进?梯度迭代,所以当样本量少的时候不要选择它,?如果 样本量?常?,?如?于10万,sag是第?选择。但是sag不能?于L1正则化,所以当你有?量 的样本,?需要L1正则化的话就要??做取舍了。要么通过对样本采样来降低样本量,要么回到 L2正则化。 从上?的描述,?家可能觉得,既然newton-cg, lbfgs和sag这么多限制,如果不是?样本,我们 选择liblinear不就?了嘛!错,因为liblinear也有??的弱点!我们知道,逻辑回归有?元逻辑 回归和多元逻辑回归。对于多元逻辑回归常?的有one-vs-rest(OvR)和many-vs-many(MvM)两 种。?MvM?般?OvR分类相对准确?些。郁闷的是liblinear只?持OvR,不?持MvM,这样如 果我们需要相对精确的多元逻辑回归时,就不能选择liblinear了。也意味着如果我们需要相对精 确的多元逻辑回归不能使?L1正则化了。
ovr即前?提到的one-vs-rest(OvR),?multinomial即前?提到的many-vs-many(MvM)。如果 是?元逻辑回归,ovr和multinomial并没有任何区别,区别主要在多元逻辑回归上。 OvR的思想很简单,?论你是多少元逻辑回归,我们都可以看做?元逻辑回归。具体做法是,对 于第K类的分类决策,我们把所有第K类的样本作为正例,除了第K类样本以外的所有样本都作为 负例,然后在上?做?元逻辑回归,得到第K类的分类模型。其他类的分类模型获得以此类推。 ?MvM则相对复杂,这?举MvM的特例one-vs-one(OvO)作讲解。如果模型有T类,我们每次在 所有的T类样本??选择两类样本出来,不妨记为T1类和T2类,把所有的输出为T1和T2的样本放 在?起,把T1作为正例,T2作为负例,进??元逻辑回归,得到模型参数。我们?共需要T(T- 1)/2次分类。 从上?的描述可以看出OvR相对简单,但分类效果相对略差(这?指?多数样本分布情况,某些 样本分布下OvR可能更好)。?MvM分类相对精确,但是分类速度没有OvR快。 如果选择了ovr,则4种损失函数的优化?法liblinear,newton-cg, lbfgs和sag都可以选择。但是 如果选择了multinomial,则只能选择newton-cg, lbfgs和sag了。
可以不输?,即不考虑权重,或者说所 有类型的权重?样。如果选择输?的话,可以选择balanced让类库??计算类型权重,或者我 们??输?各个类型的权重,?如对于0,1的?元模型,我们可以定义class_weight={0:0.9, 1:0.1},这样类型0的权重为90%,?类型1的权重为10%。 如果class_weight选择balanced,那么类库会根据训练样本量来计算权重。某种类型样本量越 多,则权重越低,样本量越少,则权重越?。 那么class_weight有什么作?呢?在分类模型中,我们经常会遇到两类问题: 第?种是误分类的代价很?。?如对合法?户和?法?户进?分类,将?法?户分类为合法?户 的代价很?,我们宁愿将合法?户分类为?法?户,这时可以??再甄别,但是却不愿将?法? 户分类为合法?户。这时,我们可以适当提??法?户的权重。 第?种是样本是?度失衡的,?如我们有合法?户和?法?户的?元样本数据10000条,??合 法?户有9995条,?法?户只有5条,如果我们不考虑权重,则我们可以将所有的测试集都预测 为合法?户,这样预测准确率理论上有99.95%,但是却没有任何意义。这时,我们可以选择 balanced,让类库?动提??法?户样本的权重。 提?了某种分类的权重,相?不考虑权重,会有更多的样本分类划分到?权重的类别,从?可以 解决上?两类问题。
从? 可能导致我们的模型预测能?下降。遇到这种情况,我们可以通过调节样本权重来尝试解决这个 问题。调节样本权重的?法有两种,第?种是在class_weight使?balanced。第?种是在调?fit 函数时,通过sample_weight来??调节每个样本权重。 在scikit-learn做逻辑回归时,如果上 ?两种?法都?到了,那么样本的真正权重是class_weight*sample_weight.
原文:https://www.cnblogs.com/Koi504330/p/11909398.html