合辑传送门 -->> 数据分析-合辑
credit_card数据集(逻辑回归)
数据集中包含284807行31列数据
问题:银行卡信用问题,根据已有的30个的特征及class进行分类,判断为正常或异常情况
数据资源: https://pan.baidu.com/s/1fzqeieHOrBmV5TJ1RfhBbw 提取码: buiu
如果逻辑回归的过程不清楚,可参见数据分析理论【3】之 逻辑回归与 数据分析理论【2】之 梯度下降和学习率
以下程序主要是根据数据分析小练手【2】 之 LogiReg_data数据集(逻辑回归)进行增加修改
目录
模块添加
在上一篇的模块基础上,添加以下模块
- 数据分割模块:按比例分割成训练集和测试集
def Split(data,Training_ratio):
#分割数据
np.random.shuffle(data)
cols = data.shape[1]
rows = data.shape[0]
num = int(rows*Training_ratio)
return data[:num,:],data[num:,:cols-1],data[num:,cols-1:]
- 下采样策略模块:将正反标签的数据量控制在同个数量级
def Downsampling(data):
#下采样策略
#按Class分类
True_label=data[data.Class==True]
False_label=data[data.Class==False]
#数据混乱后抽取等同数据量
Amount=min(True_label.shape[0],False_label.shape[0])
True_label=True_label.sample(n=Amount)
False_label=False_label.sample(n=Amount)
#合并
Data=pd.concat([True_label,False_label],axis=0)
return Data
- 分类模块:根据sigmoids函数返回的概率值进行一定阈值的分类
def Classification(probability,threshold):
if probability>threshold:
return 1
else:
return 0
- 测试模块:测试不同迭代次数的分类效果
def Test_Stop_iter(data_train, X_test , y_test):
#thresh的大小对结果的影响
batchSize=data_train.shape[0]
color=['r','b','y','c','k']
thresh=[5000,20000,50000,100000,200000]
alpha=0.000001
print('#'*50)
print()
for thr,c in zip(thresh,color):
theta, iter_times, costs, grad, cost_time = descent(
data_train, batchSize, 'Stop_iter', thr, alpha)
Correct_quantity = 0
for X, y in zip(X_test, y_test):
if Classification(model(X, theta)[0], 0.5) == y:
Correct_quantity += 1
print('thresh = %3d %3d/%3d %7f cost_time = %3fs'
%(thr,Correct_quantity,len(y_test),Correct_quantity/len(y_test),cost_time))
print()
print('#'*50)
测试不同迭代次数的分类效果
按照训练集:测试集=6:4进行划分,同时由于数据正负标签数量级差异过大,所以进行下采样策略进行数据集的重新构建。
if __name__ == '__main__':
Data = pd.read_csv('creditcard.csv',header=0,low_memory=False)
Data.drop(['Time'],axis=1,inplace=True)
Data.insert(0, 'V0', 1)
Data=Downsampling(Data) #下采样策略
orig_data = Data.as_matrix() # 将列表转化为矩阵
data_train, X_test , y_test=Split(orig_data,0.6)
Test_Stop_iter(data_train, X_test, y_test)
我们能得到以下的结果,随着迭代次数的增加,正确率不断上升,迭代次数至20w,达到0.85的准确率,但对于这份数据而言,这样的迭代数据下这样的准确率并不能满意,所以我们需要从数据上发现问题。
数据预处理
这里我们重新看回数据,我们就会发现其中的‘Amount’列的值明显比其他V1到V28要大得多多,这个时候为了避免出现因为特征值的差距过大导致模型的判断失误,我们需要对数据进行预处理,在大多数情况下,我们进行数据分析前,都需要先进行数据的预处理。
Data['Amount'] = (Data['Amount'] -Data['Amount'].min())/(Data['Amount'].max()-Data['Amount'].min())
我们能看到预测的准确率确实上升了一些,但完全无法达到我们的要求,因为在自己手动写的模型总归是简易版本,还是屈服用sklearn吧。
sklearn版本
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# 使用交叉验证的方法,把数据集分为训练集合测试集
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
def Downsampling(data):
#下采样策略
#按Class分类
True_label=data[data.Class==True]
False_label=data[data.Class==False]
#数据混乱后抽取等同数据量
Amount=min(True_label.shape[0],False_label.shape[0])
True_label=True_label.sample(n=Amount,random_state=11)
False_label=False_label.sample(n=Amount,random_state=11)
#合并
Data=pd.concat([True_label,False_label],axis=0)
return Data
# 加载数据集
def load_data():
Data = pd.read_csv('creditcard.csv', header=0, low_memory=False)
# diabetes = datasets.load_iris()
Data.drop(['Time'], axis=1, inplace=True)
Data['Amount'] = (Data['Amount'] - Data['Amount'].min()) / \
(Data['Amount'].max() - Data['Amount'].min())
Data = Downsampling(Data)
Data = Data.as_matrix()
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
Data[:,:-1], Data[:,-1:], test_size=0.40, random_state=11)
return X_train, X_test, y_train, y_test
# 使用LogisticRegression考察逻辑回归的预测能力
def test_LogisticRegression(X_train, X_test, y_train, y_test):
# 选择模型
cls = LogisticRegression()
# 把数据交给模型训练
cls.fit(X_train, y_train)
# 预测y的值
y_pred = cls.predict(X_test)
# 查看测试结果
print(metrics.confusion_matrix(y_test, y_pred))
print(metrics.classification_report(y_test, y_pred))
if __name__=='__main__':
X_train,X_test,y_train,y_test=load_data() # 产生用于回归问题的数据集
test_LogisticRegression(X_train,X_test,y_train,y_test) # 调用 test_LinearRegression
这次的效果就相对好了一下,accuracy可达到0.94,可基本满意.
模型评估
具体的一些评估方法可以参考数据分析理论【4】之 模型评估