题目:1.预测二元分类
2.比较不同正则化参数得到的结果
一.预测分类
1.1数据集
这里我采用的数据集是sklearn自带的鸢尾花数据集。
#在实际的调试过程中大家可以把每一个矩阵及他们的形状都打印一下,来确认每一个矩阵代表的含义
iris = load_iris()#载入数据
x = iris['data']#特征值
y = iris['target']#目标值 0:第一类 1:第二类 2:第三类
names = iris['target_names']#品种名字
feature_names = iris['feature_names']#特征值名称
这里我们可以打印一下y这个矩阵,结果如下:
这里可以看出,这个数据集是有三类的,我们的作业是一个二元分类,所以我们取前100个,也就是前两个品种来进行预测。这里的特征值有四个,我们取sepal length 和sepal width这两个特征来进行预测。下面是数据处理的代码,以及将数据可视化来更好的展示数据:
x_length_3=np.array(df_x['sepal length (cm)'])#特征是 sepal length 的150个数据
x_width_3=np.array(df_x['sepal width (cm)'])#特征是 sepal width 的150个数据
x_length=x_length_3[:100]#取前一百个数
x_width=x_width_3[:100]#取前一百个数据
#特征值x的矩阵为(1,x1,x2)
one=np.ones(x_length.size)
x=np.column_stack((one,x_length,x_width))
y=target[:100]#取前一百个数 'setosa'是0 'versicolor'是1
#数据集可视化
for target, target_name in enumerate(names):
X_plot =np.column_stack((x_length,x_width))[y == target]
plt.plot(X_plot[:, 0], X_plot[:, 1], linestyle='none', marker='o', label=target_name)
plt.legend()
plt.show()
下图是运行的结果,我们可以看出中间有很分明的界限
1.2模型函数
#线型模型
def h_funtion(x,theta):
theta=np.matrix(theta) #将theta转换为矩阵,矩阵大小为3*1
x=np.matrix(x) #将X转换为矩阵,矩阵大小为100*3
return np.dot(x,theta.T)
#sigmoid函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
把公式写成函数的形式,到时候直接调用即可。
1.2代价函数
逻辑回归的代价函数是交叉熵函数,在理论学习的部分我们已经知道了他的公式,只要将公式用代码来实现就可以啦。让我们来看一下公式:
代码如下:
# 计算损失函数
loss = (-1 / len(x)) * np.sum(y * np.log(y_hat) + (1 - y) * np.log(1 - y_hat))
1.3梯度下降
梯度下降更新参数的公式为:
下面是梯度下降的代码实现:
#梯度下降
def gradient (x,y,theta,lr,time):
y=np.matrix(y) #将y转换为矩阵,矩阵大小为1*100
w=np.matrix(theta)
# w=np.matrix([thera[1],thera[2]])
# print(w)
for i in range(time):
# 计算sigmoid函数的预测值
y_hat=sigmoid(h_funtion(x,theta))
# print(y_hat)
# 计算损失函数
loss = (-1 / len(x)) * np.sum(y * np.log(y_hat) + (1 - y) * np.log(1 - y_hat))
# 计算梯度
dw = (1 / len(x)) * np.dot(x.T, (y_hat - y.T))
# 更新参数
w -= lr * dw.T
#参数矩阵
theta=np.array(w)
# print(theta)
# 每更新100次打印一下此时各个参数
if i % 100 == 0:
print("第%d次更新,此时第一个参数为%f,第二个参数为%f,第三个参数为:%f,损失函数值为:%f"%(i+1,theta[0][0],theta[0][1],theta[0][2],loss))
return theta
1.4预测
当y_hat的值大于0.5时,y_han为1
当y_hat的值小于0.5时,y_han为0
# 预测
def predict(thera, X):
y_hat=sigmoid(h_funtion(x,theta))
y_hat[y_hat >= 0.5] = 1
y_hat[y_hat < 0.5] = 0
return y_hat
1.5画图
最后我们还需要画出这条直线。对于这条直线来说,是关于x1与x2的直线,x1为输入,x2为输出。根据这个我们来编写代码:
t=np.array([-theta[0,0]/theta[0,2],-theta[0,1]/theta[0,2]])
q=np.column_stack([one,x_length.T])
xx2=np.array(np.dot(q,t.T))
plt.plot(x_length,xx2)
让后再加上我们前面数据集的可视化代码,最后运行结果为:
t=np.array([-theta[0,0]/theta[0,2],-theta[0,1]/theta[0,2]])
q=np.column_stack([one,x_length.T])
xx2=np.array(np.dot(q,t.T))
for target, target_name in enumerate(names):
X_plot = np.column_stack((x_length,x_width))[y == target]
plt.plot(X_plot[:, 0], X_plot[:, 1], linestyle='none', marker='o', label=target_name)
plt.legend()
plt.plot(x_length,xx2)
plt.xlabel("sepal length")
plt.ylabel("sepal width")
plt.show()
1.6全部代码及运行结果展示:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.optimize as opt
from sklearn.datasets import load_iris
#线型模型
def h_funtion(x,theta):
theta=np.matrix(theta) #将theta转换为矩阵,矩阵大小为3*1
x=np.matrix(x) #将X转换为矩阵,矩阵大小为100*3
return np.dot(x,theta.T)
#sigmoid函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
#梯度下降
def gradient (x,y,theta,lr,time):
y=np.matrix(y) #将y转换为矩阵,矩阵大小为1*100
w=np.matrix(theta)
# w=np.matrix([thera[1],thera[2]])
# print(w)
for i in range(time):
# 计算sigmoid函数的预测值
y_hat=sigmoid(h_funtion(x,theta))
# print(y_hat)
# 计算损失函数
loss = (-1 / len(x)) * np.sum(y * np.log(y_hat) + (1 - y) * np.log(1 - y_hat))
# 计算梯度
dw = (1 / len(x)) * np.dot(x.T, (y_hat - y.T))
# 更新参数
w -= lr * dw.T
#参数矩阵
theta=np.array(w)
# print(theta)
# 每更新100次打印一下此时各个参数
if i % 100 == 0:
print("第%d次更新,此时第一个参数为%f,第二个参数为%f,第三个参数为:%f,损失函数值为:%f"%(i+1,theta[0][0],theta[0][1],theta[0][2],loss))
return theta
# 预测
def predict(thera, X):
y_hat=sigmoid(h_funtion(x,theta))
y_hat[y_hat >= 0.5] = 1
y_hat[y_hat < 0.5] = 0
return y_hat
if __name__ != '__main__':
pass
else:
#导入数据及处理数据
iris = load_iris()
data = iris['data']#特征值
target = iris['target']#目标值 0:第一类 1:第二类 2:第三类
names = iris['target_names']#品种名字
feature_names = iris['feature_names']#特征值名称
df_x=pd.DataFrame(data,columns=feature_names)#特征值和名称对应
# print(df_x)
x_length_3,x_width_3=np.array(df_x['sepal length (cm)']),np.array(df_x['sepal width (cm)'])#特征是 sepal width 的150个数据#特征是 sepal length 的150个数据
x_length=x_length_3[:100]#取前一百个数
x_width=x_width_3[:100]#取前一百个数据
#特征值x的矩阵为(1,x1,x2)
one=np.ones(x_length.size)
x=np.column_stack((one,x_length,x_width))
y=target[:100]#取前一百个数 'setosa'是0 'versicolor'是1
#初始化参数
theta=np.array([1.0,1.5,-0.7])
#数据集可视化
for target, target_name in enumerate(names):
X_plot = np.column_stack((x_length,x_width))[y == target]
plt.plot(X_plot[:, 0], X_plot[:, 1], linestyle='none', marker='o', label=target_name)
plt.legend()
plt.show()
# print(costFuntion(theta,x,y))
# 梯度下降
theta=gradient(x,y,theta,0.1,2000)
# gradient(x,y,theta,0.08,10000)
# 预测
p=np.array(predict(theta,x))
#打印预测结果
for i in range(100):
print("预测sepal length特征为:%f,sepal width特征为:%f的鸢尾花的品种为:%d,实际品种为:%d"%(x[i,0],x[i,1],p[i],y[i]))
# #画图
t=np.array([-theta[0,0]/theta[0,2],-theta[0,1]/theta[0,2]])
q=np.column_stack([one,x_length.T])
xx2=np.array(np.dot(q,t.T))
for target, target_name in enumerate(names):
X_plot = np.column_stack((x_length,x_width))[y == target]
plt.plot(X_plot[:, 0], X_plot[:, 1], linestyle='none', marker='o', label=target_name)
plt.legend()
plt.plot(x_length,xx2)
plt.xlabel("sepal length")
plt.ylabel("sepal width")
plt.show()
运行结果,输出的图片有两张,一张是数据集,一张是包含我们的线性模型的最终结果:
打印的内容有
参数更新过程:
预测结果: