代码实现如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def loadDataSet(): #数据的读取,从txt文档中读入
dataMat = []
labelMat = []
fr = open('testSet.txt')
for line in fr.readlines():
lineArr = line.strip().split() #split将一个字符串进行切片,默认分隔符为空字符
if(len(lineArr)==0): #line从文档头开始一行行读取,必须加上判断条件在读到末尾的下一行时跳出,否则会出现列表越界!
break
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #特征值x0,x1,x2,其中x0为偏移量设为1
labelMat.append(int(lineArr[2])) #真实值(标记,分为0和1)
return dataMat, labelMat
def sigmoid(z):
return 1.0/(1+np.exp(-z))
#返回最佳回归系数theta
def gradAscent(dataMatIn, classLabels):
#将得到的列表转换为numpy矩阵类型
dataMatrix = np.mat(dataMatIn)
labelMat = np.mat(classLabels).transpose()
# m->样本数 n->特征数
m= dataMatrix.shape[0]
n=dataMatrix.shape[1]
alpha = 0.001 #步长,学习率
maxCycles = 500 #限制迭代次数
#初始化theta参数,每个维度均为1.0
theta = np.ones((n,1))
for i in range(maxCycles):
h = sigmoid(dataMatrix * theta) #得到h(x)
error = (h-labelMat) #得到h(x)-y
theta = theta - alpha * dataMatrix.transpose() *error
#dataMatrix.transpose()*error是代价函数的偏导,返回得到的特征参数θ0,θ1,θ2
return np.array(theta)
def plotBestFit(theta):
dataMat, labelMat = loadDataSet()
dataArr = np.array(dataMat)
# n->样本数
n = dataArr.shape[0]
#xcord1,ycord1代表正例特征
#xcord2,ycord2代表负例特征
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, s = 30, c = 'r', marker = 'o') #画出各自的散点图
ax.scatter(xcord2, ycord2, s = 30, c = 'b',marker='x')
#设定边界直线x和y的值
x = range(-3,3)
"""
决策边界直线方程式
w0*x0+w1*x1+w2*x2=f(x)
f(x)=0是两个类别的分界处
所以: w0+w1*x+w2*y=0 => y = (-w0-w1*x)/w2
"""
y = (-theta[0] - theta[1] * x) / theta[2]
ax.plot(x, y)
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()
dataMat,labelMat=loadDataSet()
theta=gradAscent(dataMat,labelMat)
print(theta)
theta=theta.tolist()
mytheta=np.array([[theta[0][0]],[theta[1][0]],[theta[2][0]]])
plotBestFit(mytheta)
输出结果: