教程目录
阅读:
softmax回归算法实践(softmax分类器Python实现)
有了前面的理论储备,我们利用上述实现好的函数,构建 Softmax Regression 分类器。在训练分类器的过程中,我们使用如图 1 所示的多分类数据作为训练数据:

图 1 多分类数据
利用 Softmax Regression 算法对其进行分类的过程中,主要有两个部分:
其中,导入训练数据的 load_data 函数如下所示:
保存 softmax 模型的 save_model 函数的实现为:
通过训练,得到了最终的模型的参数,模型的参数保存在文件 weights 中,其中参数为:
其中,load_weights 函数的具体实现如下所示。
load_data 函数的具体实现代码如下所示:
在本次测试中随机生成了 4 000 个样本,目的是为了能够更好地刻画出分类的边界,最终的分类效果如图 2 所示。

图 2 最终的分类边界
在图 2 中,通过点的不同深浅区分出 4 个类别之间的边界。最终利用 save_result 函数将预测的结果保存到指定的文件中,save_result 函数的具体实现为:

图 1 多分类数据
利用 Softmax Regression 算法对其进行分类的过程中,主要有两个部分:
- 利用训练数据对模型进行训练;
- 对新的数据进行预测;
对Softmax Regression算法的模型进行训练
首先,我们利用训练样本训练模型,为了使得 Python 能够支持中文的注释和利用 numpy,我们需要在训练文件“softmax_regression_train.py”的开始加入:#codeing:UTF-8 import numpy as np模型训练的主函数如下所示:
if __name__ == "__main__": inputfile = "SoftInput.txt" # 1、导入训练数据 print "---------- 1.load data ------------" feature, label, k = load_data(inputfile) # 2、训练Softmax模型 print "---------- 2.training ------------" weights = gradientAscent(feature, label, k, 10000, 0.4) # 3、保存最终的模型 print "---------- 3.save model ------------" save_model("weights", weights)在此主函数中,首先需要导入训练数据,然后便可以利用梯度下降法对模型进行训练。当模型训练结束后,将最终的模型参数保存到文件 weights 中,如程序中所示。
其中,导入训练数据的 load_data 函数如下所示:
def load_data(inputfile): '''导入训练数据 input: inputfile(string)训练样本的位置 output: feature_data(mat)特征 label_data(mat)标签 k(int)类别的个数 ''' f = open(inputfile) # 打开文件 feature_data = [] label_data = [] for line in f.readlines(): feature_tmp = [] feature_tmp.append(1) # 偏置项 lines = line.strip().split(" ") for i in xrange(len(lines) - 1): feature_tmp.append(float(lines[i])) label_data.append(int(lines[-1])) feature_data.append(feature_tmp) f.close() # 关闭文件 return np.mat(feature_data), np.mat(label_data).T, len(set(label_data))函数 load_data 的输入为训练样本的文件名,通过解析输出训练数据的特征 feature_data、标签 label_data 和训练样本的类别个数 k。
保存 softmax 模型的 save_model 函数的实现为:
def save_model(file_name, weights): '''保存最终的模型 input: file_name(string):保存的文件名 weights(mat):softmax模型 ''' f_w = open(file_name, "w") m, n = np.shape(weights) for i in xrange(m): w_tmp = [] for j in xrange(n): w_tmp.append(str(weights[i, j])) f_w.write(" ".join(w_tmp) + " ") f_w.close()函数 save_model 将训练好的 Softmax 模型保存到对应的文件中,其中,save_model 函数的输入是保存的文件名 file_name 和对应的 Softmax 模型 weights。
最终的模型
训练的具体为:
通过训练,得到了最终的模型的参数,模型的参数保存在文件 weights 中,其中参数为:

对新的数据的预测
对于分类算法而言,训练好的模型需要能够对新的数据集进行划分。利用上述步骤,我们训练好 Softmax Regression 模型,并将其保存在“weights”文件中,此时,我们需要利用训练好的 Softmax Regression 模型对新数据进行预测,同样,为了能够使用 numpy 中的函数和对中文注释的支持,在文件“softmax_regression_test.py”文件开始,我们加入:#codeing:UTF-8 import numpy as np测试的主程序如下所示:
if __name__ == "__main__": # 1、导入Softmax模型 print "---------- 1.load model ------------" w, m , n = load_weights("weights") # 2、导入测试数据 print "---------- 2.load data ------------" test_data = load_data(4000, m) # 3、利用训练好的Softmax模型对测试数据进行预测 print "---------- 3.get Prediction ------------" result = predict(test_data, w) # 4、保存最终的预测结果 print "---------- 4.save prediction ------------" save_result("result", result)程序中,首先是导入模型的参数,同时需要导入测试的数据,然后利用训练好的 Softmax 模型对测试数据进行预测,最后得到最终的预测结果,并将其保存到文件 result 中。
其中,load_weights 函数的具体实现如下所示。
def load_weights(weights_path): '''导入训练好的Softmax模型 input: weights_path(string)权重的存储位置 output: weights(mat)将权重存到矩阵中 m(int)权重的行数 n(int)权重的列数 ''' f = open(weights_path) w = [] for line in f.readlines(): w_tmp = [] lines = line.strip().split(" ") for x in lines: w_tmp.append(float(x)) w.append(w_tmp) f.close() weights = np.mat(w) m, n = np.shape(weights) return weights, m, n该程序中,需要导入 random 模块,这个模块的主要功能是为了生成下面的测试数据。在 load_weights 函数中,其输入为模型权重所在文件 weights_path,其输出为权重所在的矩阵,以及权重矩阵的行数 m 和列数 n。
load_data 函数的具体实现代码如下所示:
def load_data(num, m): '''导入测试数据 input: num(int)生成的测试样本的个数 m(int)样本的维数 output: testDataSet(mat)生成测试样本 ''' testDataSet = np.mat(np.ones((num, m))) for i in xrange(num): testDataSet[i, 1] = rd.random() * 6 - 3#随机生成[-3,3]之间的随机数 testDataSet[i, 2] = rd.random() * 15#随机生成[0,15]之间是的随机数 return testDataSet该程序中,load_data 函数用于生成测试样本,其中,函数的输入为样本的个数 num 和样本的维数 m。其输出为生成的测试样本 testDataSet。在生成样本的过程中使用到了 random 模块中的 random()方法,该方法主要是生成(0.0,1.0)之间的随机数。因此,需要在“softmax_regression_test.py”文件中导入 random 模块:
import random as rdpredict 函数的具体实现如下所示:
def predict(test_data, weights): '''利用训练好的Softmax模型对测试数据进行预测 input: test_data(mat)测试数据的特征 weights(mat)模型的权重 output: h.argmax(axis=1)所属的类别 ''' h = test_data * weights return h.argmax(axis=1)#获得所属的类别在程序中,predict 函数对测试数据进行了预测,并将最终的预测结果存到 h 中,predict 函数的输入为测试数据 test_data 和模型的权重 weights,函数的输出是每个测试样本对应的类别。在函数中,得到了每个样本属于每一个类别的概率,最终返回概率值最大的 index 作为最终的类别标签。
在本次测试中随机生成了 4 000 个样本,目的是为了能够更好地刻画出分类的边界,最终的分类效果如图 2 所示。

图 2 最终的分类边界
在图 2 中,通过点的不同深浅区分出 4 个类别之间的边界。最终利用 save_result 函数将预测的结果保存到指定的文件中,save_result 函数的具体实现为:
def save_result(file_name, result): '''保存最终的预测结果 input: file_name(string):保存最终结果的文件名 result(mat):最终的预测结果 ''' f_result = open(file_name, "w") m = np.shape(result)[0] for i in xrange(m): f_result.write(str(result[i, 0]) + " ") f_result.close()此程序中,函数 save_result 将最终的预测结果 result 保存到指定的文件 file_name 中。save_result 函数的输入分别为最终的预测结果 result 和保存的文件名 file_name。