orange实现逻辑回归_从零开始实现逻辑回归模型

本文介绍了逻辑回归模型,它在工业界广泛应用,如CTR预测,具有简单、解释性好、计算速度快等优点。与线性回归不同,逻辑回归用于分类任务,特别是二元分类。文中通过Python的sklearn和numpy库展示了逻辑回归的实现,并提供了数据预处理、模型训练和预测的完整代码示例。
摘要由CSDN通过智能技术生成

声明:版权所有,转载请联系作者并注明出处: 风雪夜归子 - CSDN博客

由于知乎不支持markdown格式,所以有公式的地方都使用了截图,若影响阅读效果,可移步我的Blog:风雪夜归子 - CSDN博客,文章会同步更新!

逻辑回归

上一篇文章介绍了线性回归、岭回归、lasso回归和多项式回归模型。这些模型都是广义线性回归模型的具体形式,广义线性回归是一种灵活的框架,比普通线性回归要求更少的假设。这一章,我们讨论广义线性回归模型的具体形式的另一种形式,逻辑回归(logistic regression)。

逻辑回归模型在工业界是工程师用的非常多的模型了,比如在CTR预测等项目中被大量使用,之所以用的非常普遍,是因为逻辑回归拥有简单、解释性好、计算速度快等优点。

和前面讨论的模型不同,逻辑回归是用来做分类任务的。分类任务的目标是找一个函数,把观测值匹配到相关的类和标签上。学习算法必须用成对的特征向量和对应的标签来估计匹配函数的参数,从而实现更好的分类效果。在二元分类(binary classification)中,分类算法必须把一个实例分为两个类别。二元分类案例包括,预测患者是否患有某种疾病,音频中是否含有人声,杜克大学男子篮球队在NCAA比赛中第一场的输赢。

普通的线性回归假设响应变量呈正态分布,也称为高斯分布(Gaussian distribution )或钟形曲线(bell curve)。正态分布数据是对称的,且均值,中位数和众数(mode)是一样的。很多自然现象都服从正态分布。比如,人类的身高就服从正态分布,姚明那样的高度极少,在99%之外了。

在某些问题里,响应变量不是正态分布的。比如,掷一个硬币获取正反两面的概率分布是伯努力分布(Bernoulli distribution),又称两点分布或者0-1分布。表示一个事件发生的概率是P,不发生的概率1−P,概率在[0, 1]之间。线性回归假设自变量(解释变量)值的变化会引起因变量(响应变量)值的变化,如果响应变量的值是概率,这条假设就不满足了。广义线性回归去掉了这条假设,用一个联连函数(link function)来描述解释变量与响应变量的关系。实际上,在线性回归模型里面,我们已经用了联连函数。普通线性回归作为广义线性回归的特例使用的是恒等联连函数(identity link function),将解释变量的通过线性组合的方式来联接服从正态分布的响应变量。如果响应变量不服从正态分布,就要用另外一种联连函数了。

from __future__ import print_function, division

import sys

import os

import math

from sklearn import datasets

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

def shuffle_data(X, y, seed=None):

if seed:

np.random.seed(seed)

idx = np.arange(X.shape[0])

np.random.shuffle(idx)

return X[idx], y[idx]

# 正规化数据集 X

def normalize(X, axis=-1, p=2):

lp_norm = np.atleast_1d(np.linalg.norm(X, p, axis))

lp_norm[lp_norm == 0] = 1

return X / np.expand_dims(lp_norm, axis)

# 标准化数据集 X

def standardize(X):

X_std = np.zeros(X.shape)

mean = X.mean(axis=0)

std = X.std(axis=0)

# 做除法运算时请永远记住分母不能等于0的情形

# X_std = (X - X.mean(axis=0)) / X.std(axis=0)

for col in range(np.shape(X)[1]):

if std[col]:

X_std[:, col] = (X_std[:, col] - mean[col]) / std[col]

return X_std

# 划分数据集为训练集和测试集

def train_test_split(X, y, test_size=0.2, shuffle=True, seed=None):

if shuffle:

X, y = shuffle_data(X, y, seed)

n_train_samples = int(X.shape[0] * (1-test_size))

x_train, x_test = X[:n_train_samples], X[n_train_samples:]

y_train, y_test = y[:n_train_samples], y[n_train_samples:]

return x_train, x_test, y_train, y_test

# 将一个向量转换成对角阵,其中对角阵上的元素就是向量中元素

def vec2diagonal(vec):

vec_length = len(vec)

diagonal = np.zeros((vec_length, vec_length))

for i in range(vec_length):

diagonal[i][i] = vec[i]

return diagonal

def accuracy(y, y_pred):

y = y.reshape(y.shape[0], -1)

y_pred = y_pred.reshape(y_pred.shape[0], -1)

return np.sum(y == y_pred)/len(y)

class Sigmoid:

def function(self, x):

return 1/(1 + np.exp(-x))

def derivative(self, x):

return self.function(x) * (1 - self.function(x))

class LogisticRegression():

"""逻辑回归分类模型.Parameters:-----------learning_rate: float学习率."""

def __init__(self, learning_rate=.1):

self.w = None

self.learning_rate = learning_rate

self.sigmoid = Sigmoid()

def fit(self, X, y, n_iterations=4000):

# 在第一列添加偏置列,全部初始化为1

X = np.insert(X, 0, 1, axis=1)

X = X.reshape(X.shape[0], -1)

y = y.reshape(y.shape[0], -1)

n_samples, n_features = np.shape(X)

# 参数初始化 [-1/n_features, 1/n_features]

limit = 1 / math.sqrt(n_features)

self.w = np.random.uniform(-limit, limit, (n_features, 1))

for i in range(n_iterations):

# 通过初始化的参数w计算预测值

y_pred = self.sigmoid.function(X.dot(self.w))

# 梯度下降更新参数w.

self.w -= self.learning_rate * X.T.dot(-(y - y_pred) *

self.sigmoid.function(X.dot(self.w)) *

(1 - self.sigmoid.function(X.dot(self.w))))

def predict(self, X):

# 训练模型的时候我们添加了偏置,预测的时候也需要添加偏置

X = X.reshape(X.shape[0], -1)

X = np.insert(X, 0, 1, axis=1)

# 预测

y_pred = np.round(self.sigmoid.function(X.dot(self.w))).astype(int)

return y_pred

def main():

# Load dataset

data = datasets.load_iris()

X = normalize(data.data[data.target != 0])

y = data.target[data.target != 0]

y[y == 1] = 0

y[y == 2] = 1

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, seed=1)

clf = LogisticRegression()

clf.fit(X_train, y_train)

y_pred = clf.predict(X_test)

accu = accuracy(y_test, y_pred)

print ("Accuracy:", accu)

plt.figure(figsize=(12, 8))

plt.scatter(X[y==0][:,0], X[y==0][:,1])

plt.scatter(X[y==1][:,0], X[y==1][:,1])

plt.show()

if __name__ == "__main__":

main()

Accuracy: 0.939393939394

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值