这里写目录标题
Logistics回归是什么前言Logistics回归公式
Logistics回归实现二分类问题Logistics回归实现病马的分类问题(二分类)处理流程:数据预处理:处理数据集中的缺失值代码实现时的一些注意事项
Logistics回归是什么
前言
回归: 利用直线对数据点进行拟合的过程称为回归 Logistics回归的主要思想: 根据现有的数据对分类边界线建立回归公式,以此进行分类。“回归”一词其实就是表示要找到该分类边界线的最佳参数。 寻找最佳参数的过程采用最优化算法。
逻辑斯谛回归(logistic regression)是统计学习中的经典分类方法,属于对数线性模型,所以也被称为对数几率回归。这里要注意,虽然带有回归的字眼,但是该模型是一种分类算法,逻辑斯谛回归是一种线性分类器,针对的是线性可分问题。利用logistic回归进行分类的主要思想是:根据现有的数据对分类边界线建立回归公式,以此进行分类。这里的“回归”一词源于最佳拟合,表示要找到最佳拟合参数集,因此,logistic训练分类器时的做法就是寻找最佳拟合参数,使用的是最优化方法。
Logistics回归公式
参考链接
L
o
g
i
t
(
X
)
=
w
0
+
w
1
x
1
+
w
2
x
2
+
w
3
x
3
+
.
.
.
+
w
n
x
n
=
X
W
Logit(X) =w_0+w_1x_1+w_2x_2+w_3x_3+...+w_nx_n =XW
Logit(X)=w0+w1x1+w2x2+w3x3+...+wnxn=XW 为了实现二分类,因此在前面加一个sigmoid函数() 当x为0时,sigmoid函数值为0.5。随着x的增大,对应的sigmoid函数的值将逼近于1;而随着x的减小,sigmoid函数的值将逼近于0。而第二幅图中我们能看到在横坐标的刻度足够大是,在x=0处sigmoid函数看起来很像阶跃函数。
Logistics回归实现二分类问题
import matplotlib.pyplot as plt
import numpy as np
from math import exp
from matplotlib.pyplot import MultipleLocator
import random
def loadDataSet():
dataMatrix = []
labelMatrix = []
data = open('./testSet.txt').readlines()
for line in data:
linesplit = line.split()
dataMatrix.append(
[1, float(linesplit[0]), float(linesplit[1])]) # 此处将data的列数增加1,并且赋值为1,其实就是相当于对于回归表达式加了一个常数项C这样计算更加方便
labelMatrix.append(int(linesplit[2]))
return dataMatrix, labelMatrix
def sigmoid(inX):
return 1 / (1 + np.exp(-inX))
def gradAscend(dataMatrix, labels):
'''
梯度上升算法实现最优化。
最优化的是什么?-----距离函数
距离函数是什么之间的距离?------(Logistic回归对输入数据的预测结果,实际结果)
Logistic回归咋算啊?-----z=w1x1+w2x2+...=XW(矩阵乘法,注意这里是X在前W在后)
:param dataMatrix:
:param labels:
:return:
'''
# 1、现将数据都转化为矩阵
dataMatrix = np.mat(dataMatrix)
labelMatrix = np.mat(labels).T # 注意shape
# 2、创建W矩阵为待优化参数,初始化待优化参数为1
m, n = dataMatrix.shape
W = np.ones((n, 1)) # w初始化为1
wHis = [] # 保存W的历史变化
wHis.append(W.tolist())
lr = 0.001
cycleStep = 200
# 3、进行优化
for step in range(cycleStep):
pre = sigmoid(dataMatrix * W)
dis = labelMatrix - pre
W = W + lr * dataMatrix.T * dis # 这里没看懂为啥这么求啊。
wHis.append(W.tolist())
return W, wHis
def plotBestFit(weights):
'''
画出数据集以及决策边界
:param weights:
:return:
'''
import matplotlib.pyplot as plt
dataMat, labels = loadDataSet()
dataArr = np.array(dataMat)
# 将两类数据划分开,分别放置
xclass1 = []
yclass1 = []
xclass2 = []
yclass2 = []
for i in range(dataArr.shape[0]):
if labels[i] == 0:
xclass1.append(dataArr[i, 1])
yclass1.append(dataArr[i, 2])
else:
xclass2.append(dataArr[i, 1])
yclass2.append(dataArr[i, 2])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xclass1, yclass1, s=30, c='red', marker='s')
ax.scatter(xclass2, yclass2, s=30, c='green')
# 绘制类别分割线
x = np.arange(-3.0, 3.0, 0.1)
y = (-weights[0] - weights[1] * x) / weights[2]
print(y)
# y=y.reshape(-1)
ax.plot(x, y)
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()
def weightPlot(weiHis):
# 先进行维度变化
weiArr = np.array(weiHis).squeeze()
weiMat = np.mat(weiArr).T
n, m = weiArr.shape
fig = plt.figure()
ax1 = fig.add_subplot(311)
ax1.plot(range(n), weiMat.getA()[0])
ax2 = fig.add_subplot(312)
ax2.plot(range(n), weiMat.getA()[1])
ax3 = fig.add_subplot(313)
ax3.plot(range(n), weiMat.getA()[2])
x_major_locator = MultipleLocator(1)
plt.show()
def stocGradAscent0(dataMatrix, labels):
m, n = dataMatrix.shape
w = np.ones(n)
wHis = []
wHis.append(w)
lr = 0.01
numIter = 200
for j in range(numIter):
for i in range(m):
pre = sigmoid(np.sum(dataMatrix[i] * w))
dis = labels[i] - pre
w += lr * dis * dataMatrix[i]
wHis.append(w.tolist())
return w, wHis
def stocGradAscent1(dataMatrix, labels):
'''
改进的随机梯度下降算法:
1、设置学习率是逐渐减小的,可以减轻数据的高频波动(震荡)
2、随机选取进行梯度更新的数据,可以防止数据的周期性波动
:param dataMatrix:
:param labels:
:return:
'''
m, n = dataMatrix.shape
w = np.ones(n)
wHis = []
wHis.append(w)
numIter = 200
for j in range(numIter):
for i in range(m):
lr=4/(1+j+i)+0.1
rand=int(random.uniform(0,m))
pre = sigmoid(np.sum(dataMatrix[rand] * w))
dis = labels[rand] - pre
w += lr * dis * dataMatrix[rand]
wHis.append(w.tolist())
return w, wHis
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
data, labels = loadDataSet()
print(data)
print(labels)
# 梯度下降算法
# weights,weightHis = gradAscend(data, labels)
# print(weights)
# plotBestFit(weights.getA())
# print(weightHis)
# weightPlot(weightHis)
# 测试随机梯度下降算法0
weights, weiHis = stocGradAscent0(np.array(data), labels)
print(weiHis)
plotBestFit(weights)
weightPlot(weiHis)
# 测试随机梯度下降算法1
# weights, weiHis = stocGradAscent1(np.array(data), labels)
# print(weiHis)
# plotBestFit(weights)
# weightPlot(weiHis)
Logistics回归实现病马的分类问题(二分类)
处理流程:
读取数据数据预处理使用训练集数据进行模型的训练,得到分类回归线的最优参数根据上述得到的分类回归线,在测试集上进行测试,计算错误率
数据预处理:处理数据集中的缺失值
可以使用所有数据的特征值的均值来填补缺失的特征值也可以使用特殊值来填补缺失的特征值,例如-1,0等直接忽略有特征值缺失的样本使用具有类似特征的样本的特征均值来代替特征缺失值使用其他的机器学习算法预测缺失值
在该任务中,使用0填补缺失的特征值;并且直接删除类别标签缺失的数据。
为什么使用0填充? 1、思考回归线的方程,如果X的取值为0,则对于该条数据的该特征处的w的变化为0,所以,将特征值填充为0不会影响w的变化。 2、对于sigmoid函数,X’为0时,函数值为0.5,也不会对分类结果产生影响。
代码实现时的一些注意事项
RuntimeWarning: overflow encountered in exp return 1 / (1 + np.exp(-inX)) 代码运行时出现warning,之前的sigmoid函数中,exp在计算时出现了出现了上溢。 分析原因: 数据集中可能存在绝对值较大的负数,因此,在计算exp(-X)时出现了结果的上溢。 解决: 代码如下。 参考链接
def sigmoid(inx):
# 对sigmoid函数的优化,避免了出现极大的数据溢出
if inx >= 0:
return 1.0 / (1 + exp(-inx))
else:
return exp(inx) / (1 + exp(inx))
def colicTest():
'''
使用预处理好的马得病的数据进行分类(是否得病)
:return:
'''
# 1、先读取数据
trainData = open('./horseColicTraining.txt').readlines()
testData = open('./horseColicTest.txt').readlines()
trainArr = []
trainLabel = []
testArr = []
testLabel = []
for i in range(len(trainData)):
line = trainData[i].split()
trainArr.append([float(line[k]) for k in range(len(line) - 1)])
trainLabel.append(int(float(line[-1])))
for i in range(len(testData)):
line = testData[i].split()
testArr.append([float(line[k]) for k in range(len(line) - 1)])
testLabel.append(int(float(line[-1])))
# 2、利用训练集数据进行训练分类器
w, wHis = stocGradAscent1(np.array(trainArr), trainLabel)
# 3、在测试集上计算错误率
error = 0
for i in range(len(testArr)):
pre = classifyVector(testArr[i], w)
if pre != int(testLabel[i]):
error += 1
errorRate = float(error) / len(testLabel)
print("错误率是:", errorRate)
return errorRate
def classifyVector(inX, weight):
pre = sigmoid(sum(inX * weight))
return 1 if pre > 0.5 else 0
相关链接
发表评论