数据的简单处理
学习笔记(六)数据分析的简单处理
数据是金融数据,我们要做的是预测贷款用户是否会逾期,表格中,status是标签:0表示未逾期,1表示逾期。
Misson1 - 构建逻辑回归模型进行预测
Misson2 - 构建SVM和决策树模型进行预测
Misson3 - 构建xgboost和lightgbm模型进行预测
Mission4 - 记录五个模型关于precision,rescore,f1,auc,roc的评分表格,画出auc和roc曲线图
Mission5 - 关于数据类型转换以及缺失值处理(尝试不同的填充看效果)以及你能借鉴的数据探索
特征工程初步的处理
- 数据采集 / 清洗 / 采样
- 特征处理
- 特征选择
1. 数据预览
由于数据特征比较多,因此需要对数据的概况进行预览
1. 包的导入
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.preprocessing import StandardScaler
import seaborn as sns
from scipy.interpolate import lagrange
2.读取文件
# 打开文件
datanew = pd.read_csv('F:/ziliao/data/data2.csv', encoding='gbk')
# 查看所有数据的类型
datanew.info()
这里查看了特征的数据类型:
2. 数据类型的转化
日期格式数据的处理
参考:pandas学习
pd.to_datetime 用于将各种日期字符串转换成标准的 datetime64 类型。日期类型的 Series 都会有一个 dt 属性,从中可以获取到有关日期时间的信息
date_temp = pd.DataFrame()
date_temp['first_transaction_time_year'] = pd.to_datetime(datanew[
'first_transaction_time']).dt.year
date_temp['first_transaction_time_month'] = pd.to_datetime(datanew[
'first_transaction_time']).dt.month
date_temp['first_transaction_time_day'] = pd.to_datetime(datanew[
'first_transaction_time']).dt.day
date_temp['latest_query_time_year'] = pd.to_datetime(datanew[
'latest_query_time']).dt.year
date_temp['latest_query_time_month'] = pd.to_datetime(datanew[
'latest_query_time']).dt.month
date_temp['latest_query_time_day'] = pd.to_datetime(datanew[
'latest_query_time']).dt.day
date_temp['loans_latest_time_year'] = pd.to_datetime(datanew[
'loans_latest_time']).dt.year
date_temp['loans_latest_time_month'] = pd.to_datetime(datanew[
'loans_latest_time']).dt.month
date_temp['loans_latest_time_day'] = pd.to_datetime(datanew[
'loans_latest_time']).dt.day
date_temp.fillna(date_temp.median(), inplace=True) ##直接以中位数来替换NAN值
并删除原本的时间序列特征的列
# 删除日期
datanew.drop(["id_name","first_transaction_time","latest_query_time","loans_latest_time"], axis=1, inplace=True)
无关特征值的查找并删除
删除对结果影响不大的特征
for cl in datanew.columns:
count = datanew[cl].count()
if len(list(datanew[cl].unique())) in [1, count, count-1]:
datanew.drop(cl, axis=1, inplace=True)
数据的离散化
其中reg_preference_for_tra:出现四个值;对reg_preference_for_trad 的处理 【映射】
境外=1 一线=5 二线=2 三线 =3 其他=4
n = set(datanew['reg_preference_for_trad'])
dic = {}
for i, j in enumerate(n):
dic[j] = i
datanew['reg_preference_for_trad'] = datanew['reg_preference_for_trad'].map(dic)
3. 填充缺失值
# “student_feature”只有1 和NA 因此将其NA变为0
datanew['student_feature'] = datanew['student_feature'].fillna(0)
其余NA值选择了两种:
(1)使用中位数进行插值
# 使用中位数进行插值
datanew.fillna(datanew.median(), inplace=True)
(2)使用拉格朗日插值(不知道为什么,效果不好)
%%time
# 使用拉格朗日插值
# 自定义插值函数
def inter_column(s,n,k=5):
y = s[list(range(n-k,n))+list(range(n+1,n+1+k))]
y = y[y.notnull()]
return lagrange(y.index, list(y))(n)
# 逐个元素判断是否需要插值
for j in datanew.columns:
for k in range(len(datanew)):
if (datanew[j].isnull())[k]:
datanew[j][k] = inter_column(datanew[j], k)
# 效果很差
4. 异常值的处理
(一). 异常值的分布图像
举两个例子
- pawns_auctions_trusts_consume_last_1_month列
画图参考:https://www.cnblogs.com/jin-liang/p/9011771.html
sns.stripplot(x='status',y='pawns_auctions_trusts_consume_last_1_month',data=datanew)
- consume_mini_time_last_1_month列
(二) 异常值的处理方法
- 标准差上下三倍绝对中位差之间属于正常点
# 异常值变动方法
def check_outlier(total_data):
# 2.标准差上下三倍绝对中位差之间属于正常点(相对较差)
median = np.median(total_data)
b = 1.4826 #这个值应该是看需求加的,有点类似加大波动范围之类的
mad = b * np.median(np.abs(total_data-median))
lower_limit = median - (3*mad)
upper_limit = median + (3*mad)
total_data[total_data > upper_limit] = upper_limit
total_data[total_data < lower_limit] = lower_limit
return total_data
# 对进行缺失值填充后的数据集进行极端值修正
X_num_cl = pd.DataFrame()
for col in datanew.columns:
X_num_cl[col] = check_outlier(datanew[col])
datanew = X_num_cl
- 平均值上下三倍标准差之间属于正常点
std = np.std(total_data)
mean = np.mean(total_data)
b = 3
lower_limit = mean-b*std
upper_limit = mean+b*std
- 箱型图提供了一个识别异常值的标准,即大于或小于箱型图设定的上下界的数值即为异常值:上四分位我们设为 U,表示的是所有样本中只有1/4的数值大于U 。同理,下四分位我们设为 L,表示的是所有样本中只有1/4的数值小于L我们设上四分位与下四分位的插值为IQR,即:IQR=U-L。那么,上界为 U+1.5IQR ,下界为: L - 1.5IQR。箱型图选取异常值比较客观,在识别异常值方面有一定的优越性。
# 1.上界为 U+1.5IQR ,下界为: L - 1.5IQR(相对以下两种方法较好)
b = 1.5
q25, q75 = total_data.quantile(q=[0.25, 0.75])
iqr = q75 - q25
top = q75 + b * iqr
bottom = q25 - b * iqr
total_data[total_data > top] = top
total_data[total_data < bottom] = bottom
5. 数据合并
将处理后的日期数据和datanew进行合并
datafinal = pd.concat([datanew,date_temp], axis=1)
6. 数据归一化并测试
数据归一化
"""
1.3 数据集的切分
"""
X_train, X_test, y_train, y_test = train_test_split(datafinal, datafinal['status'],test_size=0.3, random_state=666)
X_train.drop(["status"],axis=1,inplace=True)
X_test.drop(["status"],axis=1,inplace=True)
"""
1.4标准化数据,方差为1,均值为零
"""
standardScaler = StandardScaler()
X_train_fit = standardScaler.fit_transform(X_train)
X_test_fit = standardScaler.transform(X_test)
模型测试
之前缺失值处理为0,异常值未处理的结果:之前的代码
缺失值简单处理,异常值简单处理后的结果:
可以看出AUC有那么一点点提升。
存在的问题与不足
问题:
- 以上处理异常值的三种方法对结果影响的差距有点大。原因还待研究。
- 使用拉格朗日插值(不知道为什么,效果不好)
不足:
3. seaborn不熟悉,所以没有在图上进行真正的分析
4. 数据处理和特征工程这一块基本是小白所以搜集到的知识点比较散碎。还有待加强学习