案例:从疝气病症预测病马的死亡率
准备数据时,数据中的缺失值是个非常棘手的问题。因为有时候数据相当昂贵,扔掉和重新获取都是不可取的,所以必须采用一些方法来解决这个问题。
在预处理阶段需要做两件事:第一,所有的缺失值必须用一个实数值来替换,因为我们使用的NumPy数据类型不允许包含缺失值。这里选择实数0来替换所有缺失值,恰好能适用于Logistic回归。第二,如果在测试数据集中发现了一条数据的类别标签已经缺失,那么我们可以将该条数据丢弃。因为类别标签与特征不同,很难确定采用某个合适的值来替换。
1、测试Logistic回归算法。把测试集上每个特征向量乘以最优化方法得来的回归系数,再将该乘积结果求和,最后输入到Sigmoid函数中。如果对应的Sigmoid值大于0.5就预测类别标签1,否则为0。
########################################
#功能:类别标签分类
#输入变量:inx, weights 特征向量,回归系数
########################################
def classify_vector(inx, weights):
prob = sigmoid(sum(inx * weights))
if prob > 0.5:
return 1.0
else:
return 0.0
2、打开训练集和测试集,并对数据进行格式化处理。数据的最后一列是类别标签,分为“仍存活”和“未能存活”两类。这里选用改进的随机梯度上升算法来计算回归系数向量。
########################################
# 功能:病马死亡率的测试
# 输入变量:空
# 输出变量:错误率
########################################
def colic_test():
fr_train = open('horseColicTraining.txt')
fr_test = open('horseColicTest.txt')
training_set = []
training_labels = []
for line in fr_train.readlines():
curr_line = line.strip().split('\t')
line_arr = []
for i in xrange(21):
line_arr.append(float(curr_line[i]))
training_set.append(line_arr)
training_labels.append(float(curr_line[21]))
train_weights = rand_grad_ascent1(array(training_set), training_labels, 500)
error_count = 0
num_test_vec = 0.0
for line in fr_test.readlines():
num_test_vec += 1.0
curr_line = line.strip().split('\t')
line_arr = []
for i in xrange(21):
line_arr.append(float(curr_line[i]))
if int(classify_vector(array(line_arr), train_weights)) != int(curr_line[21]):
error_count += 1
error_rate = float(error_count)/num_test_vec
print 'the error rate of this test is: %f' % error_rate
return error_rate
########################################
# 功能:求迭代10次后的平均错误率
########################################
def multi_test():
num_tests = 10
error_sum = 0.0
for k in xrange(num_tests):
error_sum += colic_test()
print 'after %d iterations the average error rate is: %f' % (num_tests, error_sum/float(num_tests))
测试代码:
def main():
multi_test()
if __name__ == '__main__':
main()