今天看了一个视频,发现有很多值得学习的地方,把代码分享给大家。数据清洗部分很值得学习。算法部分最好还是自己找个合适的跑一跑
import pandas as pd;
import os;
from dateutil.parser import parse
import datetime
import numpy as np;
from sklearn.tree import DecisionTreeClassifier;
from sklearn.model_selection import train_test_split
def ReadData():
#获取路径名
LP_Path=os.getcwd()+os.sep+"money_data"+os.sep+"LP.csv"
LC_Path = os.getcwd() + os.sep + "money_data" + os.sep + "LC.csv"
#读入数据
LP=pd.read_csv(LP_Path);
LC=pd.read_csv(LC_Path)
#查看数据格式
#LP.info()
#LC.info()
#print(LP.head(10))
#print(LC.head(10))
#返回数据
return LP,LC;
def AnalysisData(LP,LC):
'''
数据没有打标签,因此我们要自己打标签。
:param LP:
:param LC:
:return:
'''
#分析第一个月和第二个月的数据。假若我们根据前两个月的还款情况,来判断第三个月会不会逾期。
#若果某用户第一个月或者第二个月出现逾期超过30天的情况。那么一般情况下认为该用户在第三个月出
#现逾期的几率比较高,要列为高风险用户。
u12_data=LP[(LP["期数"]==1)|(LP["期数"]==2)]
#查看数据,发现还款日期里面出现了别的字符,在接下来的时候不要忘记处理。
#print(u12_data)#3203145 \N 2017-02-22
#3203156 \N 2017-02-22
#3203157 \N 2017-02-22
#拿到第一期和第二期的以后,要来分析出现还款状态不正常的情况。
#到记录日的当期状态,分为
# 0-‘未还款’,
# 1-‘已正常还款’,
# 2-‘已逾期还款’,
# 3-‘已提前还清该标全部欠款’,
# 4-‘已部分还款’
#我们把状态为0,2,4都作为一种不正常状态来处理。
u12_late=u12_data[(u12_data["还款状态"]==0)|(u12_data["还款状态"]==2)|(u12_data["还款状态"]==4)]
u_late_final=u12_late.copy();
#把还款日期中\N的字符换成2050-01-01
u_late_final["还款日期"]=u_late_final["还款日期"].apply(lambda x:x if x!="\\N" else"2050-01-01")
#计算逾期天数,其中用到了parse包
u_late_final["逾期天数"]=u_late_final["还款日期"].apply(parse)-u_late_final["到期日期"].apply(parse)
#print(u_late_final)
#考虑一些客户可能存在忘记还款的可能,因此,我们可以把逾期日期低于30天的数据去掉。保留逾期超过3天的数据。
u_label=u_late_final[u_late_final["逾期天数"]>datetime.timedelta(30)]
#print(u_label)
id_date=u_label.ListingId.unique();#提取符合条件的用户额ID,并把它去重处理。
# 因为用户逾期一次和逾期两次都作为一种逾期行为。得到一个列表数据。[ 1565761 1590171 1595521 ..., 32819451 32819511 32819531]
#print(id_date)
#给ID数据打上标签。
final_data=pd.DataFrame({"ListingId":id_date,"label":np.ones(id_date.size)})
#把我们得到的数据和LC标的表关联起来。
all_data=pd.merge(LC,final_data,how="outer",on="ListingId")
#print(all_data)
#进行缺失值处理。观察数据,发现只有label标签有缺失值。
#chenull=all_data.isnull().sum(axis=0).sort_values(ascending=False)#/float(len(all_data))
#print(chenull)#label 0.85136
#历史逾期还款期数 0.00000
#借款金额 0.00000
#/float(len(all_data))有无这个的区别。
#label 279717
#历史逾期还款期数 0
#对label进行填充。
all_data["label"].fillna(value=0,inplace=True)
#print(all_data)
#u12_late.info()
#至此,已完成数据的整体分析。接下来进行数据的统计分析。
return all_data;
def DataExplore(all_data):
#print(all_data.describe().T)#可以查看一些数据的统计信息
#建立特征工程
#特征合并
#1.加权利率:还款期数*借款利率
#2.还款期数比:历史正常还款期数/(历史正常还款期数+逾期期数)
#3.未还款比:总待还本金/历史成功借款金额。
all_data["加权利率"]=all_data["借款期限"]*all_data["借款利率"]
all_data["还款期数比"]=all_data["历史正常还款期数"]/(all_data["历史正常还款期数"]+all_data["历史逾期还款期数"])
all_data["未还款比"] = all_data["总待还本金"] / all_data["历史成功借款金额"]
#特征离散化:
#借款金额,借款期限,借款利率,年龄
#有些特征可以进行归一化。但要保证每次样本的最大最小值一样的。
def money(money):
if money<=3000:
return 0;
elif money<=5000:
return 1;
elif money<=7000:
return 2;
elif money<=9000:
return 3;
else:
return 4;
def Day(day):
if day<=6:
return 0;
elif day<=12:
return 1;
else:
return 2;
def intere_rate(rate):
if rate<=13:
return 0;
elif rate<=17:
return 1;
elif rate<=21:
return 2;
else:
return 3;
def age(age):
if age <= 22:
return 0
elif age <= 25:
return 1
elif age <= 30:
return 2
elif age < 40:
return 3
else:
return 4
all_data["借款金额"]=all_data["借款金额"].apply(money)
all_data["借款期限"]=all_data["借款期限"].apply(Day)
all_data["借款利率"]=all_data["借款利率"].apply(intere_rate)
all_data["年龄"]=all_data["年龄"].apply(age)
#特征规范化:
"""
1.归一化
2.小数定标
3.z-score x-mean(x)/std.
"""
trans_col = ['历史成功借款次数', '历史成功借款金额', '总待还本金', '历史正常还款期数',
'历史逾期还款期数', '加权利率', '还款期数比', '未还款比', '总待还本金']
for col in trans_col:
all_data[col] = all_data[col] -all_data[col].mean() / all_data[col].std()
all_data.drop('借款成功日期', axis=1, inplace=True)
#one-hot编码
one_col = ['是否首标', '性别', '手机认证', '户口认证', '视频认证', '学历认证', '征信认证', '淘宝认证'
, '初始评级', '借款类型', '借款金额', '借款期限', '借款利率', '年龄']
after_ones = pd.get_dummies(all_data.loc[:, one_col], columns=one_col)
# 不平衡数据处理
# 去掉原来的一些列
notInAfterOnes = np.setdiff1d(all_data.columns.tolist(), one_col)
final_data = pd.concat([all_data.loc[:, notInAfterOnes], after_ones], axis=1)
final_data.info()
y=final_data["label"]
final_data.drop("label", axis=1, inplace=True)
#print(y)
#print(final_data)
'''
X_col = [ele for ele in final_data.columns.tolist() if ele not in ['label', 'ListingId']]
# print(final_data.loc[:,X_col])
# SMOTE
#在此处进行了样本扩充,
from imblearn.over_sampling import SMOTE
smote = SMOTE(ratio=0.2, k_neighbors=5)
final_data.fillna(0, inplace=True)
X_resample, y_resample = smote.fit_sample(final_data.loc[:, X_col], final_data.loc[:, 'label'])
X_data = pd.DataFrame(X_resample, columns=X_col)
y_data = pd.DataFrame(y_resample, columns=['label'])
new_data = pd.concat([X_data, y_data], axis=1)
#new_data.info()
'''
return final_data,y;
def Makemodel(x,y):
X_tr, X_test, y_tr, y_test = train_test_split(x, y, test_size=0.2, random_state=1)
#from sklearn.tree import DecisionTreeClassifier;
chenull = X_tr.isnull().sum(axis=0).sort_values(ascending=False) # /float(len(all_data))
print(chenull)
clf=DecisionTreeClassifier()
clf.fit(X_tr,y_tr)
print(clf.score(X_tr,y_tr))
print(clf.score(X_test,y_test))
pass;
if __name__ == '__main__':
LP,LC=ReadData();
all_data=AnalysisData(LP,LC)
x,y=DataExplore(all_data)
Makemodel(x,y)