1. 介绍
logistic回归又称logistic回归分析,是一种广义的线性回归分析模型,常用于数据挖掘,疾病自动诊断,经济预测等领域。例如,探讨引发疾病的危险因素,并根据危险因素预测疾病发生的概率等。
以胃癌病情分析为例,选择两组人群,一组是胃癌组,一组是非胃癌组,两组人群必定具有不同的体征与生活方式等。因此因变量就为是否胃癌,值为“是”或“否”,自变量就可以包括很多了,如年龄、性别、饮食习惯、幽门螺杆菌感染等。自变量既可以是连续的,也可以是分类的。然后通过logistic回归分析,可以得到自变量的权重,从而可以大致了解到底哪些因素是胃癌的危险因素。同时根据该权值可以根据危险因素预测一个人患癌症的可能性。
2. 算法实现
分别采用标准化、Log、Binary 3种预处理,进行下面操作
1、数据预处理;
2、梯度上升法训练参数权重,采用十折交叉验证,选择规格化强度参数;
3、对错误数据分类,计算错误率。
程序中主要实现了如下函数:
函数 | 说明 |
---|---|
def LoadData(file_path): | 加载mat文件 |
def StndTrainData(x, axis): | 标准化训练数据,每列使它们满足零均值和单位方差 |
def StndTestData(test, mean, std): | 标准化测试数据 |
def Log(x): | 使用log(x[i][j] + 0.1)变换特征数据 |
def Binary(x): | 二值化数据 >0为1 否则为0 |
def ChangeWeight(w1, w2): | 计算两次权重改变了多少 |
def GradAscent(x, y, l2, round, step): | 梯度上升算法,采用L2正则化方法 |
def Classify(data, weights): | 对数据进行分类 |
def CaclErrorRate(test_ret, real_ret): | 计算错误率 |
def CrossValidator(data): | 十折交叉验证 |
3. 代码
# -*- coding: utf-8 -*-
import os
import math
import scipy.io as scio
import numpy as np
from sklearn.linear_model import LogisticRegression #加载模块
from sklearn.linear_model import LogisticRegressionCV
def LoadData(file_path):
'''
加载mat文件
:param file_path: 文件路径
:return:
'''
data = scio.loadmat(file_path)
return data
def StndTrainData(x, axis):
'''
标准化训练数据,每列使它们满足零均值和单位方差
:param x: numpy.ndarray类型
:param axis:
:return: 处理后的训练数据,均值,均方差
'''
#不要修改原数据
x = np.array(x) #拷贝
xr = np.rollaxis(x, axis=axis)
mean = np.mean(x, axis=axis)
std = np.std(x, axis=axis)
xr -= mean #减去均值
xr /= std #除以均方差
return xr, mean, std
def StndTestData(test, mean, std):
'''
标准化测试数据
:param test: 测试数据
:param mean: 训练数据的均值
:param std: 训练数据的均方差
:return: 处理后的测试数据
'''
#不要修改原数据
testr = np.array(test)
testr -= mean #减去均值
testr /= std #除以均方差
return testr
def Log(x):
'''
使用log(x[i][j] + 0.1)变换特征数据
:param x: 原数据
:return: 处理后的数据
'''
#不要修改原数据
xr = np.array(x) #copy
xr = np.log(xr + 0.1)
return xr
def Binary(x):
'''
二值化数据 >0为1 否则为0
:param x: 原数据
:return: 处理后的数据
'''
#不要修改原数据
xr = np.array(x) #copy
xr = np.where(xr>0, 1, 0)
return xr
def Sigmod(z):
'''
for i in xrange(np.size(z)):
try:
a = math.exp(-z[i])
except:
pass
'''
return 1.0 / (1.0 + np.exp(-z))
def ChangeWeight(w1, w2):
'''
计算两次权重改变了多少
:param w1:
:param w2:
:return:
'''
return math.sqrt(np.sum(np.square(w1 - w2)) /