逻辑回归介绍
逻辑回归是一种广义的线性回归分析模型,但并不是回归的一种,而是分类.多应用与机器学习数据挖掘等方面研究,是一种经典的二分类法
再补充一下应用背景,用更具体案例来说明吧…
1.某高校学生考试,学生的成绩分为语文成绩和数学成绩,并且我们在不知道及格分数线是多少的情况下,需要通过以往学生成绩和是否录取这几个数据来分析该校学生的及格率,这就需要通过逻辑回归来找到及格分数线,并求出及格率了
2.某高校录取学生,虽然高校给了分数线,但这玩意肯定是不能信的,每年录取都会有所变动,现在小明想知道自己是否能被该校录取,我们就要通过以往学生的数据逻辑回归找到一条录取线,并通过录取线找到分类出录取和不录取的人数,进而可以预测出录取率
rigmoid函数
我们假定一个数据集的结果只有0(不是)和1(是),如某高校学生成绩及格人数,那么只有及格和不及格两种
rigmoid函数就是为了便于我们将找到的权重和数据组合后的函数限定在0和1之间,这样可以更好的对数据进行处理和分析
注意:这里的θTx是数据集的向量,如:某高校学生属性成绩为x1,语文成绩为x2,那么θ+θ1x1+θ2x2=y,
损失函数
同线性回归一样,为了找出一条合适的逻辑回归线,我们可以通过给出的数据集,通过其损失函数(二分类)找到权重值
梯度下降法
前面线性回归已经了解到梯度下降法基本原理就是通过求导和设置学习率迭代次数来找到最合适的权重值,那么下图就是线性回归j(θ)的求导公式
预测
现在,通过反向传播(求导),我们已经找到最合适的权重来构建一条合适的逻辑回归线,通过设置阈值来区分,如逻辑回归值在0.5以上的就是1,在0.5一下的就是0
这里解释一下为什么阈值是0.5:通过sigmoid函数图像可发现,y=0.5是一个拐点,在0.5以上的为正数,0.5一下的为负数,这正好和预测出来的线性回归线一样,在线上的数是1在线下的数是0
现在已经可以通过设置阈值来找到有数据集中,有多少数据为1,有多少数据为0,再用这些得到的数据来求正确率,召回率和精度
代码演示
import numpy as np
from matplotlib import pyplot as plt
from sklearn import preprocessing
from sklearn.metrics import classification_report
scale=False
# 导入数据
csv_data = np.loadtxt(r"./LR-testSet.csv", delimiter=",")
x_data = csv_data[:, :-1] # 特征集
y_data = csv_data[:, -1, np.newaxis] # 结果集
# 画散点图
def scatter(x, y):
x0 = []
y0 = []
x1 = []
y1 = []
for i in range(len(x)):
if y[i] == 0:
x0.append(x[i, 0])
y0.append(x[i, 1])
else:
x1.append(x[i, 0])
y1.append(x[i, 1])
plt.scatter(x0, y0, c="b")
plt.scatter(x1, y1, c="r", marker="x")
# scatter(x_data,y_data)
# plt.show()
# 添加偏执值
X_data = np.concatenate((np.ones((len(x_data), 1)), x_data), axis=1)
# print(X_data)
# sigmoid
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# cost
def cost():
pass
# gradeAscent
def gradeAscent(x, y):
if scale==True:
x=preprocessing.scale(x)
# 将输出集和结果集转化为矩阵
xMat = np.mat(x) # (100,3)
yMat = np.mat(y) # (100,1)
# 设置参数
lr = 0.001
epochs = 10000
# 初始化权重(参数)
m, n = xMat.shape # m=100,n=3
wg = np.ones((n, 1)) # (3,1)
for i in range(epochs + 1):
h = sigmoid(xMat * wg)
# 求导
wg_grace = xMat.T * (h - yMat) / m
# 更新
wg = wg - (lr * wg_grace)
return wg
# 训练模型,得到权值
wg = gradeAscent(X_data, y_data)
# 画图
# scatter(x_data,y_data)
# x_test = [[-4], [3]]
# y_test = (-wg[0] - x_test * wg[1]) / wg[2]
# print(wg)
# plt.plot(x_test, y_test, 'k')
# plt.show()
#预测
def predict(x_data, ws):
if scale == True:
x_data = preprocessing.scale(x_data)
xMat = np.mat(x_data)
ws = np.mat(ws)
return [1 if x >= 0.5 else 0 for x in sigmoid(xMat*ws)]
predictions = predict(X_data, wg)
print(classification_report(y_data, predictions))