(文章底部有完整代码和数据集链接)
逻辑斯谛回归常用于分类问题。
常见于以下应用场景:
- 贷款违约问题(会/不会)(银行可用于判断要不要给一个人放贷)
- 商品推荐(会购买/不会够买)
- 情感分析(正/负)
- 广告点击(点/不点)
- 还有很多其他分类问题……
举例:
这张表格给定X:(年龄、工资、学历)的条件,预测一个人贷款Y:会不会逾期。
因此对于这样的分类问题,我们需要做以下三件事:
- 核心是:学习输入到输出的映射 f :X —> Y。
- 这样的映射关系,我们可以通过条件概率P(Y|X)表达。所以需要定义P(Y|X)
- 假设我们明知道条件概率P(Y|X),怎么做分类呢?
以下将一一解答:
逻辑斯谛回归的一般过程: - 收集数据
- 准备数据
- 分析数据
- 训练算法
- 测试算法
- 使用算法
优点:
实现简单,容易理解和实现;计算代价不高,速度很快。
缺点:
容易欠拟合,分类精度不够高。
机器学习实战代码:
import numpy as np
import matplotlib.pyplot as plt
"""
函数说明:加载数据集
dataMat : 数据
labelMat : 标签
"""
def loadDataSet():
dataMat = []
labelMat = []
fr = open('testSet.txt')
for line in fr.readlines():
line = line.strip().split()
labelMat.append(int(line[-1]))
dataMat.append([1.0,float(line[0]),float(line[1])]) #testSet的前连个值是X1,X2,为了方便计算,所以把x0设为1.0
fr.close()
return dataMat,labelMat
"""
函数说明:绘制数据集
"""
def plotDataSet():
dataMat, labelMat = loadDataSet() #加载数据集
dataArr = np.array(dataMat) #转换成numpy的array数组
n = np.shape(dataMat)[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]) #1为正样本
else:
xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) #0为负样本
fig = plt.figure()
ax = fig.add_subplot(111) #添加subplot
ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本
ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5) #绘制负样本
plt.title('DataSet') #绘制title
plt.xlabel('x'); plt.ylabel('y') #绘制label
plt.show()
"""
函数说明:sigmoid函数
x : 数据
"""
def sigmoid(x):
return 1.0/(1 + np.exp(-x))
"""
函数说明:梯度下降算法,更新w
"""
def gradDescent(dataMat,classLabels):
dataMatrix = np.mat(dataMat) #shape:[100,3]
labelMat = np.mat(classLabels).transpose() #shape:[1,100] label.t:[100,1]
m,n = np.shape(dataMatrix)
alpha = 0.001 #学习率
maxCycles = 500 #迭代次数
weights = np.ones((n,1)) #初始化 w
for k in range(maxCycles):
y_ = sigmoid(dataMatrix * weights)
error = y_ - labelMat
weights = weights - alpha*dataMatrix.transpose()*error
return weights.getA() # 返回求得的权重数组(最优参数)
"""
函数说明:绘制决策边界
"""
def plotBestFit(weights):
dataMat, labelMat = loadDataSet() #加载数据集
dataArr = np.array(dataMat) #转换成numpy的array数组
n = np.shape(dataMat)[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]) #1为正样本
else:
xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) #0为负样本
fig = plt.figure()
ax = fig.add_subplot(111) #添加subplot
ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本
ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5) #绘制负样本
x = np.arange(-3.0, 3.0, 0.1)
y = (-weights[0] - weights[1] * x) / weights[2]
ax.plot(x, y)
plt.title('BestFit') #绘制title
plt.xlabel('X1'); plt.ylabel('X2') #绘制label
plt.show()
if __name__=="__main__":
dataMat,labelMat = loadDataSet()
plotDataSet()
weights = gradDescent(dataMat,labelMat)
plotBestFit(weights)
运行结果:
代码和数据链接:https://github.com/201066/lihang