先前说明:该文档为资料整理文档,仅供参考
一、小技巧
- 获得数据集的行名称和列名称
dfname._stat_axis.values.tolist() # 行名称
dfname.columns.values.tolist() # 列名称
- 水平分布
data['y'].value_counts()
- 查看变量的水平种类
allFeatures=list(data.columns)
allFeatures.remove('y')
for i in allFeatures:
print('变量:{}的不同水平值有{}个'.format(i,len(data[i].unique())))
- 数据表格中的频数
1.df.groupby(['type_dw']).size()# 查看频率数
2.y_train1=pd.Series(y_train)
y_train1.value_counts().iloc[:2]
- 提取某一列的空值
ch[ch[['overdue_sum']].isnull().T.any()]
- 去掉重复 从小到大进行排列
ch.drop_duplicates( 'overdue_sum',inplace=False).sort_values( 'overdue_sum')
- 填写缺失值为0的列
col=[ 'jieqing_state','jieqing_amount', 'yichang_amount',
'yichang_state' , 'count_dw', 'months',
'highest_oa_per_mon', 'max_duration','month_dw', 'last_months', 'amount',
'spl_state', 'spl_amount']
ch[col]=ch[col].fillna(0)
ch
- 删除选取某列含有特殊数值的行
mport pandas as pd
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
df1=pd.DataFrame(a,index=['row0','row1','row2'],columns=list('ABC'))
print(df1)
df2=df1.copy()
#删除/选取某列含有特定数值的行
#df1=df1[df1['A'].isin([1])]
#df1[df1['A'].isin([1])] 选取df1中A列包含数字1的行
df1=df1[~df1['A'].isin([1])]
#通过~取反,选取不包含数字1的行
print(df1)
- 删除/选取某行含有特殊数值的列
#删除/选取某行含有特定数值的列
cols=[x for i,x in enumerate(df2.columns) if df2.iat[0,i]==3]
#利用enumerate对row0进行遍历,将含有数字3的列放入cols中
print(cols)
#df2=df2[cols] 选取含有特定数值的列
df2=df2.drop(cols,axis=1) #利用drop方法将含有特定数值的列删除
print(df2)
import datetime
data = data.loc[:, ['query_date']] # 获取数据集中列名为date和value这两列
# 标准化日期,获取时间的“年、月、日”
def change_date(s):
s = datetime.datetime.strptime(s, "%Y-%m-%d") # 把日期标准化,转化结果如:2015/1/4 => 2015-01-04 00:00:00
s = str(s) # 上一步把date转化为了时间格式,因此要把date转回str格式
return s[:10] # 只获取年月日,即“位置10”之前的字符串
data['query_date'] = data['query_date'].map(change_date) # 用change_date函数处理列表中date这一列,如把“2015/1/4”转化为“2015-01-04”
data = data.sort_values(by='query_date') # 按date这一列进行排序
print(data)
- 并行运行代码
使用Dask并行化训练XGBoost:Dask-XGBoost的使用
二、初始设置与数据筛选
2.1 初始设置的代码
import numpy as np
import pandas as pd
import pickle
import os
import matplotlib.pyplot as plt
from pylab import *
from datetime import datetime
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'#对运行环境进行设置,使其支持中文显示
pd.set_option('display.max_columns', 500)#配置pandas 列数为500,避免对列数进行隐藏
### 工作路径
file_path = 'E:\\mypython\\dissertation2\\data\\'
### EDA模块保存路径
eda_path = 'E:\\\mypython\\dissertation2\\data\\keep2\\'
def missing_values_table(df):
mis_val = df.isnull().sum() # 总缺失值
mis_val_percent = 100 * df.isnull().sum() / len(df) # 缺失值比例
mis_val_table = pd.concat([mis_val, mis_val_percent], axis = 1) # 缺失值制成表格
mis_val_table_ren_columns = mis_val_table.rename(columns = {0:'Missing Values',
1:'% of Total Values'})
mis_val_table_ren_columns = mis_val_table_ren_columns[
mis_val_table_ren_columns.iloc[:,1] != 0].sort_values('% of Total Values',ascending=False).round(1)
# 缺失值比例列由大到小排序
print('Your selected dataframe has {} columns.\nThere are {} columns that have missing values.'.format(df.shape[1], mis_val_table_ren_columns.shape[0]))
# 打印缺失值信息
return mis_val_table_ren_columns
d = pd.read_csv(eda_path + '2basic_train_process.csv',encoding='utf-8')
#sex=pd.DataFrame(d['sex'].groupby(d['report_id']).sum())
ch3.to_csv(eda_path+"2ch_four.csv",encoding="utf-8")
2.2 80%原则:样本起码有30【一共37个变量】
三、缺失值填充
KNN邻居选取
迭代K的可能范围-1到20之间的所有奇数都可以
- 1.使用当前的K值执行插补
- 2.将数据集分为训练和测试子集
- 3.拟合随机森林模型
- 4.预测测试集
- 5.使用RMSE进行评估
KNN是最简单的分类算法之一。通过测量不同特征值之间的距离进行分类。它的的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。K通常是不大于20的整数。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。其算法的描述为:1. 计算测试数据与各个训练数据之间的距离;
KNN填充
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=20)
adf[['edu_level','overdue_sum',
'ln_abnormal',
'remain_payment_cyc',
'credit_limit_sum',
'chaxun',
'card_number',
'card_overdue_amount',
'latest_6month_used_avg_amount',
'used_credit_limit_sum',
'has_fund']] = imputer.fit_transform(adf[['edu_level','overdue_sum',
'ln_abnormal',
'remain_payment_cyc',
'credit_limit_sum',
'chaxun',
'card_number',
'card_overdue_amount',
'latest_6month_used_avg_amount',
'used_credit_limit_sum',
'has_fund']])
四、特征选择【lightgbm】
4.1 目标的水平分布
data=adf.copy()
data['y'].value_counts()
data=adf.copy()
data['y'].value_counts()
4.2查看变量的水平种类
data_copy=data.copy()
#data.drop(labels=['report_id'], axis=1, inplace=True)
allFeatures=list(data.columns)
allFeatures.remove('y')
for i in allFeatures:
print('变量:{}的不同水平值有{}个'.format(i,len(data[i].unique())))
allFeatures=list(data.columns)
allFeatures.remove('y')
for i in allFeatures:
print('变量:{}的不同水平值有{}个'.format(i,len(data[i].unique())))
4.3指定分类变量和连续变量
#list(data)
#分类变量
categorical_var=['is_local',
'edu_level',
'marry_status','has_fund','sex', 'ln_abnormal','y_fraud']
#连续变量
continous_var=[ 'salary',
'card_number',
'card_overdue_amount',
'account_count',
'finance_corp_count',
'remain_payment_cyc',
'jieqing_state',
'jieqing_amount',
'yichang_amount',
'yichang_state',
'latest_6month_used_avg_amount',
'credit_limit_sum',
'used_credit_limit_sum',
'overdue_sum',
'house_loan_count',
'commercial_loan_count',
'other_loan_count',
'loancard_count',
'standard_loancard_count',
'count_dw',
'months',
'highest_oa_per_mon',
'max_duration',
'month_dw',
'last_months',
'amount',
'spl_state',
'spl_amount']
4.3.1 连续变量标准化
from sklearn.preprocessing import StandardScaler
sc=StandardScaler()
data[continous_var]=sc.fit_transform(data[continous_var])
4.3.2数值分类变量转整形
string_var=list(data.select_dtypes(include=["object"]).columns)
col=list(set(categorical_var)-set(string_var))
data[col]=data[col].astype(int)
4.3.3 字符分类变量按照坏样本率进行编码
def Encoder(df, col, target):
encoder = {}
for v in set(df[col]):
if v == v:
subDf = df[df[col] == v]
else:
xList = list(df[col])
nanInd = [i for i in range(len(xList)) if xList[i] != xList[i]]
subDf = df.loc[nanInd]
encoder[v] = sum(subDf[target])*1.0/subDf.shape[0]
newCol = [encoder[i] for i in df[col]]
return newCol
string_var = list(data.select_dtypes(include=["object"]).columns)
col = list(set(categorical_var) & set(string_var))
for i in col:
data[i] = Encoder(data, i, 'target')
4.4.指定整型分类变量作为 LightGBM 的分类特征
col=list(set(categorical_var)-set(string_var))
4.4.1 保存变量和文件
import pickle
f=open('lgb_col.pkl','wb')
pickle.dump(col,f)
f.close()
4.4.2 建模
allFeatures=list(data.columns)
allFeatures.remove('y')
X=data[allFeatures]
y=data['y']
from sklearn.model_selection import train_test_split as sp
X_train,X_test,y_train,y_test=sp(X,y,test_size=0.3,random_state=1)
4.4.3 加载分类变量
f=open('lgb_col.pkl','rb')
col=pickle.load(f)
f.close()
4.4.4 LightGBM建模[调参]
import lightgbm as LGB
params={
'objective':'binary',
'boosting':'gbdt',
'num_leaves':4,
'min_data_in_leaf':20,
'subsample':0.9,
'colsample_bytree':0.8,
'learning_rate':0.09,
'tree_learner':'voting',
'metric':'auc'
}
dtrain=LGB.Dataset(X_train,y_train,categorical_feature=col)
dtest=LGB.Dataset(X_test,y_test,reference=dtrain,categorical_feature=col)
lgb=LGB.train(params,dtrain,valid_sets=[dtrain,dtest],num_boost_round=3000,
early_stopping_rounds=100,verbose_eval=10)
五、变量重要性【图】
1.变量重要性图
importace = list(lgb.feature_importance())
allFeatures=list(lgb.feature_name())
featureImportance = zip(allFeatures, importace)
featureImportanceSorted = sorted(featureImportance, key=lambda k: k[1], reverse=True)
plt.figure(figsize = (5, 10))
sns.barplot(x=[k[1] for k in featureImportanceSorted], y=[k[0] for k in
featureImportanceSorted])
plt.xticks(rotation='vertical')
plt.show()
2.查看实际排序
featureImportanceSorted
3.选择变量
3.1.选择了KNN18的变量
feature_selections_lgb=[k[0] for k in featureImportanceSorted[:18]]
qdata=data_copy.copy()
qdata=qdata[feature_selections_lgb+['y']]
qdata
3.2.选择了KNN11的变量
qfeature_selections_lgb=[k[0] for k in featureImportanceSorted[:11]]
qqdata=data_copy.copy()
qqdata=qdata[qfeature_selections_lgb+['y']]
qqdata
六、将数据集切割为训练集和测试集后,保存为文件
# 导入包
from sklearn import model_selection
from sklearn.metrics import confusion_matrix# 引入混淆矩阵
df = pd.read_csv(eda_path + '2_KNN18.csv',encoding='utf-8')
#Splitting the data into independent and dependent variables
X = df.iloc[:,0:len(df.columns.tolist())-1].values
y = df.iloc[:,len(df.columns.tolist())-1].values
messages_train, messages_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
mess_train = pd.DataFrame(messages_train, columns=['report_id',
'y_fraud',
'salary',
'credit_limit_sum',
'latest_6month_used_avg_amount',
'overdue_sum',
'card_overdue_amount',
'sex',
'used_credit_limit_sum',
'edu_level',
'remain_payment_cyc',
'months',
'max_duration',
'card_number',
'finance_corp_count',
'count_dw',
'is_local',
'other_loan_count',
'loancard_count'])
label_train = pd.DataFrame(y_train, columns=['y'])
mess_test = pd.DataFrame(messages_test, columns=['report_id',
'y_fraud',
'salary',
'credit_limit_sum',
'latest_6month_used_avg_amount',
'overdue_sum',
'card_overdue_amount',
'sex',
'used_credit_limit_sum',
'edu_level',
'remain_payment_cyc',
'months',
'max_duration',
'card_number',
'finance_corp_count',
'count_dw',
'is_local',
'other_loan_count',
'loancard_count',])
label_test = pd.DataFrame(y_test, columns=['y'])
train_data = 'E:\\mypython\\dissertation2\\data\\keep2\\model\\train_data18.csv'
test_data = 'E:\\mypython\\dissertation2\\data\\keep2\\model\\test_data18.csv'
pd.concat([mess_train,label_train], axis=1).to_csv(train_data, index=False, encoding='utf-8')
pd.concat([mess_test,label_test], axis=1).to_csv(test_data, index=False, encoding='utf-8')
# 加载数据,查看条数
df_train = pd.read_csv(train_data, sep=',', encoding='utf-8')
df_test = pd.read_csv(test_data, sep=',', encoding='utf-8')
print('训练集大小',len(df_train),'测试集大小',len(df_test))