最近在看小象学院的机器学习视频,里面只稍微提了下softmax回归,并没给推导过程和代码,于是就自己尝试了一下。
推导如下:
代码实现使用的是鸢尾花数据集,该数据集有3种鸢尾花,数据集刚开始长下面这个样子:
data=pd.read_csv('iris.data',header=None) #一共有150个样本
对数据进行预处理,首先把3种鸢尾花名称编码成0,1,2,然后还要插入一列,使数据x变成(1,x),方便算theta*(1,x)
sort=data[4] data[4]=pd.Categorical(data[4]).codes #将种类编码成0,1,2
data.insert(0,'常数项',1) #将x扩展成(1,x),以便计算theta*(1,x)
变换完成后,数据变成下面的样子
然后就可以选出训练集和测试集了
x=data.iloc[:,0:5].as_matrix() y=data[4].as_matrix()
x,x_test,y,y_test=train_test_split(x,y,test_size=0.3) #用105个样本训练
theta=softMax(x,y,0.02) #学习因子不能取太大,否则最后计算出的theta无穷大
softmax回归参数训练的程序如下
#采用随机梯度下降法,每次只挑选一个样本做优化 def softMax(x,y,alpha): theta=np.zeros((3,5))
#初始theta矩阵 for i in range(10000): #迭代10000次
k=np.random.randint(0,105) #从105个样本中随机挑选一个做优化 x_=x[k].reshape(5,1)
theta_T_x=np.dot(theta,x_) #计算所有的theta*x
e_theta_T_x=np.exp(theta_T_x) #计算所有指数函数
denominator=e_theta_T_x.sum() #计算分母 numerator=e_theta_T_x #分子
fraction=numerator/denominator #计算所有分数
y_vector=np.where(np.arange(3).reshape(3,1)==y[k],1,0) #计算y向量
gradient=(fraction-y_vector)*x[k] theta-=alpha*gradient #更新theta矩阵
return theta
训练完theta后,就可以在测试集上验证了
predict=np.dot(theta,x_test.T) predict_sort=predict.argmax(axis=0)
num_of_wrong=(predict_sort!=y_test).sum() print("预测错误的个数: ",num_of_wrong)
print("正确率为: {0}%".format((45-num_of_wrong)/45*100))
结果如下:
预测错误的个数: 1 正确率为: 97.77777777777777%
完整的代码实现如下所示:
import numpy as np import pandas as pd from sklearn.model_selection import
train_test_split #采用随机梯度下降法,每次只挑选一个样本做优化 def softMax(x,y,alpha):
theta=np.zeros((3,5)) #初始theta矩阵 for i in range(10000): #迭代10000次
k=np.random.randint(0,105) #从105个样本中随机挑选一个做优化 x_=x[k].reshape(5,1)
theta_T_x=np.dot(theta,x_) #计算所有的theta*x
e_theta_T_x=np.exp(theta_T_x) #计算所有指数函数
denominator=e_theta_T_x.sum() #计算分母 numerator=e_theta_T_x #分子
fraction=numerator/denominator #计算所有分数
y_vector=np.where(np.arange(3).reshape(3,1)==y[k],1,0) #计算y向量
gradient=(fraction-y_vector)*x[k] theta-=alpha*gradient #更新theta矩阵
return theta if
__name__=="__main__": data=pd.read_csv('iris.data',header=None)
#一共有150个样本 sort=data[4] data[4]=pd.Categorical(data[4]).codes
#将种类编码成0,1,2 data.insert(0,'常数项',1) #将x扩展成(1,x),以便计算theta*x
x=data.iloc[:,0:5].as_matrix() y=data[4].as_matrix()
x,x_test,y,y_test=train_test_split(x,y,test_size=0.3) #用105个样本训练
theta=softMax(x,y,0.01) #学习因子不能取太大,否则最后计算出的theta无穷大
predict=np.dot(theta,x_test.T) predict_sort=predict.argmax(axis=0)
num_of_wrong=(predict_sort!=y_test).sum() print("预测错误的个数:
",num_of_wrong) print("正确率为: {0}%".format((45-num_of_wrong)/45*100))
热门工具 换一换