机器学习_Logistic回归(机器学习实战)

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当前样本值)更新回归系数的向量

返回回归系数

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值