基于机器学习的办理银行贷款预测
基于机器学习的办理银⾏贷款预测
该项⽬是补课班⽼师留的作业,⽐较简单,⽤来练⼿,熟悉流程
适合机器学习初学者来实践
#如何判断某些属性和特征与结果是否关联
#⾸先通过相关⼈员进⾏简单筛选,也可以通过画图和求相关系数来发现
#例如,通过画age与最终贷款的柱状图,如果各个年龄下,差别不⼤,证明年龄关系不⼤,可以去掉。
#某个特征如果单独来看,和最终结果关系不⼤,它与其他的特征组合也不会有影响,因此可以不⽤考虑这种情况
#关于one-hot编码,当离散特征的⼤⼩没有做特殊要求时,即做范式平⽅差的时候不会有差异。
#本例中,暂不认为教育之间有差距,所以采⽤one-hot编码映射各个教育程度。
#利⽤one-hot处理后维度会变多,即本来为⼀个housing特征变成housing-yes,housing-no,housing-unknown三个特征。
#注,logistic回归不是利⽤距离计算,所以其实可以采⽤1,2,3数值去表⽰,只是习惯上在不确定的条件下采⽤one-hot编码去做。
#数值之间的⽐例⽆法确定。只能通过业务确定,或者⾃⼰摸索着去调。(其他维度相同,只有待测特征不同,看差距)
#关于连续数据离散化:⼀般情况下,原数据什么样就是什么样,不⽤转化成离散型。
#例如年龄特征⼀般就是连续型,不⽤再多加处理变成离散型;除⾮是有些算法不⽀持连续型(如决策树)。
#导⼊包
#pandas ⼊门教程
import pandas as pd
import numpy as np
from sklearn import preprocessing      #数据预处理
import matplotlib.pyplot as plt        #做图⼯具
from sklearn.linear_model import LogisticRegression  #logisticregression 算法
ss_validation import train_test_split  #交叉验证,随机选取训练集和测试集
# 读⼊数据,做数据分析,CSV格式⽤的最多,⾮常适合存储数据。
#ad_csv,读取CSV(逗号分割)⽂件到DataFrame
#常⽤的函数只有两个,sep(表⽰指定分割符)和header(表⽰数据表头,默认是0)。
#sep : str, default ‘,’;指定分隔符,如果不指定参数,则会尝试使⽤逗号分隔。
#header:指定⾏数⽤来作为列名,数据开始⾏数。如果⽂件中有列名,则默认为0,否则设置为None,表⽰不要把第⼀⾏作为header。data = pd.read_csv('banking.csv', header=0)
# 去掉缺失数据,.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)[source]
#主要看axis和how。#⼀般情况下,先进性填充,再采⽤dropna,否则删除样本过多
#0表⽰删除⾏,1表⽰删除列(⼀般不会,因为会删除掉⼀个属性);
#how默认any,any-有⼀个缺失,则丢掉,all-全部缺失才丢掉。
data = data.dropna()
print(data.shape)
print(lumns))  #输出各个列的名字
# 预览数据,前五⾏;与之对应的是tail(x)函数,预览后x⾏
data.head()
# 探索数据情况,利⽤unique看离散数据有哪些可选值。
data['education'].unique()
# 把所有的 "basic.*" 归结为 "Basic", 离散型的取值越少越好,差距⼩的可以合并。
#result = np.where(cond,xarr,yarr)  当符合条件时是x,不符合是y,常⽤于根据⼀个数组产⽣另⼀个新的数组。
data['education'] = np.where(data['education'] == 'basic.9y', 'Basic', data['education'])
data['education'] = np.where(data['education'] == 'basic.6y', 'Basic', data['education'])
data['education'] = np.where(data['education'] == 'basic.4y', 'Basic', data['education'])
data['education'].unique()
# 看⽬标变量的⽐例
data['y'].value_counts()
# 利⽤groupby可以查看数据的分布情况,先按照参数可能的取值进⾏分类,再进⾏操作。
# 这个的mean表⽰的是取均值操作
# 对分类数据进⾏One-Hot编码,连续型不变,离散型改动
#给编码取名,⼀般为原名字_新名字
#把没改变的连续型的加进去
#疑问:
#1.两个cat_list代码什么意思?执⾏后的效果是什么?
#2,cat_list最后的结果是1000这种编码还是'job_admin‘这种⽂字?
#3.join()函数在这⾥是如何运作的?
#4,我怎么看这个循环⾥每⼀步都发⽣啥了?
#lumns与lumns.values输出的⼀样,有什么区别?  好像对最终结果没影响。  下⾯data_final与
lumns.values处同理。
#get_dummies函数,将分类变量(categorical variable)转换为“哑变量矩阵”(dummy matrix)或“指标矩阵”(indicator matrix)
#即如果DataFrame的某⼀列中含有k个不同的值,则可以派⽣出⼀个k列矩阵或DataFrame(其值全为1和0)
#prefix 给所有的列索引上加个前缀。
#.join()函数  语法:'sep'.join(seq):参数说明--sep:分隔符。可以为空;seq:要连接的元素序列、字符串、元组、字典
#上⾯的语法即:以sep作为分隔符,将seq所有的元素合并成⼀个新的字符串
#返回值:返回⼀个以分隔符sep连接各个元素后⽣成的字符串
#tolist() 将数组或者矩阵转换成列表
cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']
for var in cat_vars:
cat_list='var'+'_'+var
cat_list = pd.get_dummies(data[var], prefix=var)
data1=data.join(cat_list)
data=data1
cat_vars=['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome']
data_list()
to_keep=[i for i in data_vars if i not in cat_vars]
data_final=data[to_keep]
lumns.values
#疑问:
#1,这段代码是⼲啥的?这⾥的x和y是啥?
#答:这段代码是⽤来删除掉属性中的y这⼀列。
data_final_vars=list()
y=['y']
X=[i for i in data_final_vars if i not in y]
# 利⽤Recursive Feature Elimination (RFE)选择最佳特征,即给特征进⾏排序
#
#RFE()两个重要参数,estimator是选择的⼀个模型,这⾥是logisticregression, 18表⽰选取的特征数,默认不填时是总数⼀半
#这⾥留下的特征值的数⽬没有明确的规定,⼀般由相关⼈员去确定,这⾥one-hot扩充之后留下了18个
#这⾥记住rfe的⽤法即可,在上述⽹址的说明中有例⼦
from sklearn import datasets          #sklearn中的数据集
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()
rfe = RFE(logreg, 18)
rfe = rfe.fit(data_final[X], data_final[y] ) #rfe.fit()参数--fit)(X,y);X为训练数据,y为⽬标结果
print(rfe.support_)    #support 中有false和ture分别表⽰这个特征不留与留
print(rfe.ranking_)    #ranking 表⽰重要性,1最⼤
# 整理上⼀步选出来的特征数据
cols=["previous", "euribor3m", "job_blue-collar", "job_retired", "job_services", "job_student", "default_no",
"month_aug", "month_dec", "month_jul", "month_nov", "month_oct", "month_sep", "day_of_week_fri", "day_of_week_wed",      "poutcome_failure", "poutcome_nonexistent", "poutcome_success"]
X=data_final[cols]
y=data_final['y']
# 构建模型,功能是从样本中随机的按⽐例选取train data和testdata
#X_train,X_test, y_train, y_test =train_test_split(train_data,train_target,test_size=0.4, random_state=0)
#train_data:所要划分的样本特征集 train_target:所要划分的样本结果
#test_size:样本占⽐,如果是整数的话就是样本的数量 random_state:是随机数的种⼦。
#随机数种⼦:其实就是该组随机数的编号,在需要重复试验的时候,保证得到⼀组⼀样的随机数。
#⽐如你每次都填1,其他参数⼀样的情况下你得到的随机数组是⼀样的。但填0或不填,每次都会不⼀样。
#调⽤sklearn逻辑回归算法⼗分简单:1.导⼊;2.fit()训练;3.predic()预测
#其中参数设置才是关键,sklearn.linear_model中LogisticRegression类的参数。默认参数如下:
#LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,intercept_scaling=1, max_iter=100,
#multi_class='ovr', n_jobs=1,penalty='l2', random_state=None, solver='liblinear', tol=0.0001,verbose=0, warm_start=False) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
logreg = LogisticRegression()
logreg.fit(X_train, y_train)
# 查看模型性能
#LogisticRegression().score()返回测试数据上的平均正确率。
#format是python新增的⼀个格式化字符串的⽅法。 .xf转化为⼩数点后x位,默认是2位
y_pred = logreg.predict(X_test)
print('Accuracy of logistic regression classifier on test set: {:.2f}'.format(logreg.score(X_test, y_test)))
# cross validation 交叉验证
#    交叉验证的讲解
#交叉验证尽量保证所使⽤的数据不带有偏向性。  KFold只是交叉验证中的⼀种
#本例中acc相差不⼤,若相差较⼤,以交叉认证为主,交叉认证取得是均值。
#n_splits默认为3,最⼩为2,是K折验证的的K值,即将数据分成K份
#random_state表⽰的是随机种⼦
#ss_val_score(estimator, X, y=None, groups=None, scoring=None, cv=None, n_jobs=1,
#                                        verbose=0, fit_params=None, pre_dispatch=‘2*n_jobs’)
#返回值 就是对于每次不同的的划分raw data时,在test data上得到的分类的准确率。
#estimator:是不同的分类器,可以是任何的分类器。⽐如⽀持向量机分类器:estimator = svm.SVC(kernel='linear', C=1)
#cv:代表不同的cross validation的⽅法
#scoring:默认Nnoe,准确率的算法,可以通过score_func参数指定;如果不指定的话,是⽤estimator默认⾃带的准确率算法。
from sklearn import model_selection
del_selection import cross_val_score
kfold = model_selection.KFold(n_splits=10, random_state=7)
modelCV = LogisticRegression()
scoring = 'accuracy'
results = ss_val_score(modelCV, X_train, y_train, cv=kfold, scoring=scoring)
print("10-fold cross validation average accuracy: %.3f" % (an()))
# confusion matrix
#函数confusion_matrix(y_true, y_pred, labels=None, sample_weight=None)
#通过计算混淆矩阵来计算⼀个分类的准确性
ics import confusion_matrix
confusion_matrix = confusion_matrix(y_test, y_pred)
print(confusion_matrix)
#sklearn中的classification_report函数⽤于显⽰主要分类指标的⽂本报告.在报告中显⽰每个类的精确度,召回率,F1值等信息。
#其中列表左边的⼀列为分类的标签名,右边support列为每个标签的出现次数.avg / total⾏为各列的均值(support列为总和).
#precision recall f1-score三列分别为各个类别的精确度/召回率及 F1值.
ics import classification_report
print(classification_report(y_test, y_pred))
#ROC曲线
#roc_auc_score 直接根据真实值(必须是⼆值)、预测值(可以是0/1,也可以是proba值)计算出auc值,中间过程的roc计算省略。#roc_curve 该函数返回这三个变量:fpr,tpr,和阈值thresholds;
#_curve(y_true,y_score, pos_label=None, sample_weight=None, drop_intermediate=True)
#“Score”表⽰每个测试样本属于正样本的概率。
#FPR = FP /(FP + TN) (被预测为正的负样本结果数 /负样本实际数),为横坐标:假正率(False Positive Rate , FPR)
#TPR = TP /(TP + FN)  (正样本预测结果数 / 正样本实际数),为纵坐标:真正率(True Positive Rate , TPR)或灵敏度(sensitivity)
#这⾥理解thresholds:分类器的⼀个重要功能“概率输出”,即表⽰分类器认为某个样本具有多⼤的概率属于正样本(或负样本)
#疑问:
#1。predict和predict_proba是啥意思?
#答:#predict是返回预测标签,predict_proba是返回预测属于某个标签的概率。
#返回你测试集中每个测试样例,分类为每个类的概率;第⼀列为标签为0的概率,第⼆列为标签为1的概率
#2.为什么要[:,1]?银行汽车贷款
#答:取标签为1的那⼀列。那是不是都⼀定是第⼆列,因为score是属于正样本的概率。
#legend显⽰图例,参数loc,设置图例显⽰的位置
ics import roc_auc_score
ics import roc_curve
logit_roc_auc = roc_auc_score(y_test, logreg.predict(X_test))
fpr, tpr, thresholds = roc_curve(y_test, logreg.predict_proba(X_test)[:,1])
plt.figure()
plt.plot(fpr, tpr, label='Logistic Regression (area = %0.2f)' % logit_roc_auc)
plt.plot([0, 1], [0, 1],'r--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
plt.savefig('Log_ROC')    #保存图
plt.show()
#本例⼦中没有做归⼀化,因为lg算法不是基于距离的,所以不需要做归⼀化,但是在不知道的情况下,做归⼀化肯定是没有错的#归⼀化⼀般服从⾼斯分布,⽤均值归⼀化。  在不确定的情况下,不推荐使⽤零均值归⼀化,⽤普通归⼀化。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。