1、一般流程
1)收集数据:采用任意方法收集数据
2)数据准备:由于需要进行距离计算,因此要求数据类型为数据型。
3)分析数据:采用任意方法对数据进行分析
4)训练算法:大部分时间将用于训练,训练的目的是为了找到最佳的分类回归系数。
5)测试算法:一旦训练完成了,分类将会很快
6)使用算法:首先,需要输入一些数据,将其转换为对应的结构化数值;接着,基于训练好的回归系数就可以对这些数值进行简单的回归计算,判定他们属于哪个类别。
2、Logistic回归的优缺点
- 优点:计算代价不高,易于理解和实现
- 缺点:容易欠拟合,分类精度可能不高
- 适用数据类型:数值型和标称型数据
3、梯度上升找到最佳参数
梯度上升法伪代码:
每个回归系数初始化为1
重复N次:计算整个数据集的梯度
使用学习率*梯度(错误X当前样本值)更新回归系数的向量返回回归系数
准备数据和分类器
# 加载数据
def loadDataSet():
dataMat, labelMat = [], []
fr = open(fil)
for line in fr.readlines():
lineArr = line.strip().split()
# 数据前两行分别为x1,x2。 1.0为初始截距项
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
labelMat.append(int(lineArr[2]))
return dataMat, labelMat
# 分类器
def sigmoid(inx):
return 1.0 / (1 + exp(-inx))
梯度上升优化算法
def gradAscent(dataMatIn, classLabels):
# 梯度上升优化算法计算回归系数
dataMatrix = mat(dataMatIn) # 转换成Numpy矩阵类型
labelMat = mat(classLabels).transpose()
m, n = shape(dataMatrix)
alpha = 0.001 # 学习率
maxCycle = 500 # 最大迭代次数
weight = ones((n, 1))
for k in range(maxCycle):
h = sigmoid(dataMatrix * weight)
error = (labelMat - h)
weight += alpha * dataMatrix.transpose() * error
return weight
# 测试
dataArr, labelMat = loadDataSet()
gradAscent(dataArr, labelMat)
分析数据:画出决策边界
def plotBestFit(weights):
import matplotlib.pyplot as plt
plt.style.use('ggplot')
dataMat, labelMat = loadDataSet()
dataArr = array(dataMat)
n = shape(dataArr)[0]
xcord1, ycord1 = [], []
xcord2, ycord2 = [], []
# 将数据根据标签分类
for i in range(n):
if int(labelMat[i]) == 1:
xcord1.append(dataArr[i, 1])
ycord1.append(dataArr[i, 2])
else:
xcord2.append(dataArr[i, 1])
ycord2.append(dataArr[i, 2])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcord1, ycord1, c='red', marker='s')
ax.scatter(xcord2, ycord2, c='green')
x = arange(-3.0, 3.0, 0.1) # -3 到 3 步长 0.1
# 此处设定z = w0x0+w1x1+w2x2 = 0 即sigmoid函数为0.5,即分界处。从而算出 x1与x2的关系 如下
y = (-weights[0] - weights[1] * x) / weights[2]
ax.plot(x, y)
plt.xlabel('x1')
plt.ylabel('x2')
plt.show()
# 测试
weights = gradAscent(dataArr, labelMat)
plotBestFit(weights)
随机梯度上升
随机梯度上升法伪代码:
每个回归系数初始化为1
对数据集每个样本:计算该样本的梯度
使用学习率*梯度(错误X当前样本值)更新回归系数的向量扫描二维码关注公众号,回复: 1442517 查看本文章返回回归系数
def stocGradAscent0(dataMatrix, classLabels):
m, n = shape(dataMatrix)
alpha = 0.01
weights = ones(n)
for i in range(m): # 行 一行为一个样本
h = sigmoid(sum(dataMatrix[i]*weights))
error = classLabels[i] - h
weights += alpha * error * dataMatrix[i]
return weights
# 测试
dataArr, labelMat = loadDataSet()
w = stocGradAscent0(array(dataArr), labelMat)
plotBestFit(w)
随机梯度上升算法与梯度上升算法的区别:
第一,后者的变量h和误差error都是向量,而前者则全是数值
第二,前者没有矩阵的转换过程,所有的变量的数据类型全都是Numpy
改进的随机梯度上升
def stocGradAscent1(dataMatrix, classLabels, numberIter = 150):
m, n = shape(dataMatrix)
weights = ones(n)
# 多次迭代
for j in range(numberIter):
dataIndex = list(range(m))
# 一次梯度上升更新weights
for i in range(m):
alpha = 4/(1.0 + j + i ) + 0.01 #迭代次数越多学习率越接近0.01 为了快速上升
randIndex = int(random.uniform(0, len(dataIndex))) # 随机选取减少周期性波动
h = sigmoid(sum(dataMatrix[randIndex] * weights))
error = classLabels[randIndex] - h
weights += alpha * error * dataMatrix[randIndex]
del(dataIndex[randIndex]) # 防止重复抽样
return weights
# 测试
w = stocGradAscent1(array(dataArr), labelMat, 500)
plotBestFit(w)
4、从疝气病预测病马的死亡率
一般思路
1)收集数据:给定数据集
2)准备数据:用Python解析文本文件并填充缺失值
3)分析数据:可视化并观察数据
4)训练算法:使用优化算法,找到最佳系数
5)测试算法:为了量化回归的效果,需要观察错误率。根据错误率决定是否退回到训练阶段,通过改变迭代次数和步长等参数得到更好的回归系数
6)使用算法:一个简单的命令行收集马的症状并输出预测结果
Logistic回归分类函数
数据做过预处理(用0填补缺失值)
def classifyVector(inX, weights):
# 判断类型
prob = sigmoid(sum(inX*weights))
if prob > 0.5:
return 1.0
else:
return 0.0
def colicTest():
trfil = r'D:\horseColicTraining.txt'
tefil = r'D:\horseColicTest.txt'
frTrain = open(trfil, 'r')
frTest = open(tefil, 'r')
tr_set, tr_labels = [], []
# 生成训练集特征数据及标签数据
for line in frTrain.readlines():
cline = line.strip().split('\t')
lineArr = []
for i in range(21):
lineArr.append(float(cline[i]))
tr_set.append(lineArr)
tr_labels.append(float(cline[21]))
# 梯度上升算的权重
tr_weights = stocGradAscent1(array(tr_set), tr_labels, 500)
errorCount=0; numTestVec = 0.0
# 生成测试集特征数据
for line in frTest.readlines():
numTestVec += 1.0
cline1 = line.strip().split('\t')
lineArr1 = []
for i in range(21):
lineArr1.append(float(cline1[i]))
# 计算错误率
clf = classifyVector(array(lineArr1), tr_weights)
lb = cline1[21]
if int(clf) != int(lb):
errorCount += 1
errorRate = float(errorCount)/numTestVec
print("The error rate of this average rate is: {}".format(errorRate))
return errorRate
10次迭代后的平均错误率为32%左右,该结果不算差,因为有30%的数据缺失。调整梯度上升的迭代次数还可以提高准确率
在最优算法中,最常用的就是梯度上升算法,而梯度上升算法又可以简化为随机梯度上升算法
参考:《机器学习实战》
数据:链接:https://pan.baidu.com/s/1FvyfRQgqQR7zFyGBJ_WtTw 密码:ffzk