LogisticRegression
在给定X的条件下,其被分到 1 类 的概率为:
其中
这样计算有些复杂,化简后为:
Q为权值向量,x为输入样本,比如有5个特征,则Q向量为
这是一个概率值,因为Q值是固定的。我们直接输入x矩阵值就好了,算法会告诉我们 Y 值能取到多少,也就是概率值为多少 ,然后大于y>0.5为1类,y<0.5为0类;
def sigmoid(self,x):
return 1.0/(1+np.exp(-x))
相应的其被分到 0 类的概率为:
但Q值怎么算和为什么这个算法可以这么算?我的理解是这样的,多元回归函数可以表示为:
其实他就是一个概率的问题,可以这么理解:回归预测后得出的值是控制了自变量后得出的概率 ;也就是说预测值Y越高,自变量可能更具有某种特性,从而影响了Y值;线性回归假设了概率与X值呈现出一条直线。(就像你每增长一岁,你被催婚的概率会增大)
但 这个多元函数所带来的一个麻烦就是:概率最大值为1,最小值为0;如果单纯看这个函数的话,Y值总有一刻会>1或<0,这和我们的思维很不和谐,解决这样的问题的一个最好的办法就是:任何>1的值都用1替代,任何<0的值都用0替代;这样就会出现任何>1的值和<0的值都将呈现出一条直线:
这样的做法的确解决了概率大小超出范围的问题,但是它显得太绝对了一点,它把一切>1和<0的值都瞬间变为一条直线,也就是表达了当自变量达到一定值得时候对因变量就没有影响了,这样显然太绝对了,举一个例子:
“Y就像你买一套房子的期望,x1是你的工资,x2是你所在的城市,x3是房子的地段
假如你的工资上涨,或房子地段相对不好,那么你买房子的概率就会上升,反之亦然;当你工资 多到一定程度 的时候,工资即使再涨,对你买房子的概率也不会有很大很大的影响,因为你已经有很多钱了,再往上加工资没有太大意义,但没人会和钱过不去,钱当然是越多越好,你可以买更好的房子或你可以更快买到房子;同样的,当你工资少的可怜的时候,即时再给他降低工资也不会对他产生很大很大的影响,因为他不可能买到房。
而对于中间一部分人来说,加/减 工资 或地段等其他因素带来的影响会很大,但加了工资换了地段你就会买房子么?不一定,因为你还没满足条件,只是说你买房子的概率会上升“
避免这样太过绝对的方法就是当自变量大到一定程度的时候,对因变量的影响相对于中间部分的影响变得很小,刚好有这样的曲线可以很好的达到我们想要的效果:
S形曲线:无限趋于上下限,也就是Logit模型,也就是sigmoid:
但回归不是一条直线么?怎么会变成曲线?可以看下这幅图:
把切线上的斜率取均值,得到一条趋势线,用直线模拟曲线。
但我们很容易发现对于这种线性关系,因变量和自变量的关系在极限段是被高估了的,而在中间段是被低估了的,因变量对自变量的影响是不对的,要么过大,要么过小;我们想要以S形状曲线预测,但是从回归可以看出每一个自变量本身都会对因变量产生影响,但当某个自变量大到足以让Y很接近1的时候,其他自变量就没法工作了,他们就不可以相互作用了,也违背了回归的原则,这样的话直接拿一个因变量检测好了,干嘛还要那么多自变量?解决这个矛盾的方法就是排除上下限,也就是需要把Logit函数做一些转化;
排除上限:
设 x 被 分为 1 类 的概率是:
然后取他们的比作为Y值的概率:
因为与概率不同的是比没有上限,但下限为0;
当概率值
而且比数还有一个作用就是:倍数关系,分子是分母的多少倍,也就是说取到1的概率是取到0的几倍;
排除下限:
为了排除下限,我们就需要当自变量
刚好:取对数可以做到这一点,有能保证自变量>0:
也就是:
到这里为止 上下限被排除,转化也就结束了
然后把S形曲线线性化:
为了更加表达清楚他们是概率的关系:两边取指数
化简后就是:
按理来说,Y被取到1 的概率应该就是这样的,接下来该是做的就是看如何把Q值算出来,对于模型的参数(Q)估计,这里使用极大似然函数
我们用
取对数后化成加法:
整个模型的代价函数化到这里就没办法再化下去了:
根据多元函数求极值法:对代价函数求偏导后得:
然后令其为0:一看就解不出Q,这样的话要求解只能用梯度上升/下降求最优解了:这里希望Y值尽可能取到1的概率增加,所以用梯度上升(不知道说的对不对,没有对的话还请指教,感激!)
先初始化一个权值矩阵Q,在进行迭代:
这里我们也看到了Sigmoid函数,经过反复迭代后得到一个局部最优解,可是如何防止跳过局部最优解还得慢慢试,不知道有没有其他的模型能帮忙解决这个问题。
迭代完后保存权值矩阵,a值可以设为1;
之后把权值矩阵做一个处理就可以看到效果,或者直接把预测结果写入文件在来一次K折交叉看看模型的准确率。
最后附代码片段
class LogisticRegressionClassifier(object):
def __init__(self,alpha,n_iter):
self.alpha = alpha
self.iter = n_iter
def sigmoid(self,x):
return 1.0/(1+np.exp(-x))
def train(self,X,y):
samples,features = np.shape(X)
weights = np.ones((features,1))
error = np.ones((features,1))
for times in range(self.iter):
output = self.sigmoid(X*weights)
error = y-output
weights = weights+self.alpha*X.transpose()*error
return weights
def predict(self,X,weights):
results = self.sigmoid(X*weights)
return results
下一篇: python与机器学习-lesson3
推荐阅读
-
Attribute ‘sklearn.linear_model._logistic.LogisticRegression.multi_class‘ must be explicitly set to
-
关于LogisticRegression及其应用
-
LogisticRegression
-
Coursera-MachineLearning-LogisticRegression
-
sklearn中的LogisticRegression
-
【深度学习学习笔记】3.LogisticRegression之一:实现sigmoid的交叉熵损失函数
-
《封号码罗》数据分析与人工智能之sklearn模型LogisticRegression逻辑斯蒂回归(十三)
-
Attribute ‘sklearn.linear_model._logistic.LogisticRegression.multi_class‘ must be explicitly set to