马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
目次
一、案例文件
二、过采样流程
1、流程图示
2、详细流程先容
1)数据切分
2)数据增强
3)创建大数据集
4)数据集切分
5)k折交织验证
6)模子训练
7)模子测试
8)最优概率阈值
三、完备代码实现
其打印结果如下:
1)过采样后的数据布局
2)肴杂矩阵可视化
3)结果的打印
四、总结
一、案例文件
同样使用上节课的银行贷款案例,其文件内容大抵如下:(共28万多条,31列)
现在要继承接着上节课的内容对模子举行优化
二、过采样流程
1、流程图示
2、详细流程先容
1)数据切分
将原始数据切分为70%的训练集和30%的测试集。
- from sklearn.model_selection import train_test_split
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
复制代码
2)数据增强
对训练会集的class=1的数据举行人工拟合,扩充为与class=0的数据量相称。
- # 假设augmented_data是在class=1的数据上进行增强得到的新数据
- # 假设class_0_data是class=0的数据
- # 将class=1的数据量扩充为class=0的数据量
- augmented_data = generate_augmented_data(class_1_data, len(class_0_data))
- # 人工拟合后,得到与class=0数据量相等的augmented_data
复制代码
3)创建大数据集
将数据增强后的训练集与原测试聚集并,得到一个新的大数据集。
- # 将增强后的训练集与原测试集合并
- X_train_augmented = np.concatenate((X_train, augmented_data))
- y_train_augmented = np.concatenate((y_train, np.ones(len(augmented_data))))
复制代码
4)数据集切分
将新的大数据集切分为训练集和测试集。
- X_train_big, X_test_big, y_train_big, y_test_big = train_test_split(X_train_augmented, y_train_augmented, test_size=0.3, random_state=0)
复制代码
5)k折交织验证
对训练集举行k折交织验证,用于模子训练的选择和调优。
- from sklearn.model_selection import KFold
- kf = KFold(n_splits=5, shuffle=True, random_state=0)
- for train_index, val_index in kf.split(X_train_big):
- X_train_fold, X_val_fold = X_train_big[train_index], X_train_big[val_index]
- y_train_fold, y_val_fold = y_train_big[train_index], y_train_big[val_index]
-
- # 在每个fold上进行模型训练和选择
- model = LogisticRegression()
- model.fit(X_train_fold, y_train_fold)
- # 在验证集上进行模型选择和调优
复制代码
6)模子训练
创建模子并对大数据集的训练集举行训练,得到训练完成的模子。
- model = LogisticRegression()
- model.fit(X_train_big, y_train_big)
复制代码
7)模子测试
使用之前切分出来的测试集和大数据集本身作为测试集,导入模子举行测试。
8)最优概率阈值
根据测试结果,调解阈值以得到最优的推测概率。
- from sklearn.metrics import precision_score, recall_score
- # 假设y_pred_prob是模型预测的概率值
- threshold = 0.5 # 初始阈值
- best_threshold = threshold
- best_f1_score = 0
- for threshold in np.arange(0.1, 1.0, 0.1):
- y_pred_test_threshold = (y_pred_prob > threshold).astype(int)
- f1_score_test = f1_score(y_test_big, y_pred_test_threshold)
-
- if f1_score_test > best_f1_score:
- best_f1_score = f1_score_test
- best_threshold = threshold
- print("Best threshold:", best_threshold)
复制代码
三、完备代码实现
- import time
- import pandas as pd
- import numpy as np
- import matplotlib.pyplot as plt
- from pylab import mpl
- # 可视化混淆矩阵,网上都是包装好的,可以直接复制使用
- def cm_plot(y, yp):
- from sklearn.metrics import confusion_matrix
- import matplotlib.pyplot as plt
- cm = confusion_matrix(y, yp)
- plt.matshow(cm, cmap=plt.cm.Blues)
- plt.colorbar()
- for x in range(len(cm)):
- for y in range(len(cm)):
- plt.annotate(cm[x, y], xy=(y, x), horizontalalignment='center',verticalalignment='center')
- plt.ylabel('True label')
- plt.xlabel('Predicted label')
- return plt
- data = pd.read_csv(r'./creditcard.csv')
- data.head() # 默认输出前5行,这里用来提示防止忘记代码了
- # 设置字体,用来显示中文
- mpl.rcParams['font.sans-serif'] = ['Microsoft YaHei']
- mpl.rcParams['axes.unicode_minus'] = False
- # 同级class列中每个类型的数据个数,(这里的样本极度不均衡)
- labels_count = pd.value_counts(data['Class'])
- # 可视化上述分类数据的个数
- # plt.title("正负例样本数")
- # plt.xlabel('类别')
- # plt.ylabel('频数')
- # labels_count.plot(kind='bar')
- # plt.show()
- # 将Amount列的数据进行Z标准化,因为其余列的值有负值,所以不能使用0-1归一化
- # 导入库的用法
- from sklearn.preprocessing import StandardScaler
- # z标准化
- scaler = StandardScaler() # 这是一个类,专门用来处理z标准化,适合处理大量数据的类,还有一种叫scale,适合对小部分数据进行z标准化
- data['Amount'] = scaler.fit_transform(data[['Amount']]) # 对Amount整列数据进行z标准化后将其传入原data内,覆盖原来的列
- data.head()
- # 删除无用的列,Time列,axis=1表示列,axis=0表示行,然后再传入data文件
- data = data.drop(['Time'],axis=1)
- from sklearn.model_selection import train_test_split
- x_whole = data.drop('Class',axis=1) # 取出原始数据集特征值和标签
- y_whole = data.Class
- x_train,x_test,y_train,y_test = train_test_split(x_whole,y_whole,test_size=0.2,random_state=0) # 对随机取出百分之20当做测试集
- from imblearn.over_sampling import SMOTE # 导入过采样方法
- oversampler = SMOTE(random_state=0) # 保证数据闭合效果,随机种子
- os_x_train,os_y_train = oversampler.fit_resample(x_train,y_train) # 对上述取出的百分之80原始数据的训练集进行过采样
- labels_count = pd.value_counts(os_y_train) # 计算过采样后的数据中各类别的数目
- plt.title("正负例样本数")
- plt.xlabel('类别')
- plt.ylabel('频数')
- labels_count.plot(kind='bar')
- plt.show()
- os_x_train_w,os_x_test_w,os_y_train_w,os_y_test_w = ( # 对过采样的数随机取出20%当做测试集,80%当做训练集
- train_test_split(os_x_train,os_y_train,test_size=0.2,random_state=0))
- from sklearn.linear_model import LogisticRegression # 导入逻辑回归模型
- from sklearn.model_selection import cross_val_score # k折交叉验证
- scores = [] # 定义一个空列表,用来存放后面更改正则化强度后的每个C值计算结果对应的score值
- c_param_range = [0.01,0.1,1,10,100] # 循环更改的C值
- z = 1
- for i in c_param_range:
- start_time = time.time() # 开始时间
- lr = LogisticRegression(C=i,penalty='l2',solver='lbfgs',max_iter=1000) # 循环遍历C值
- score = cross_val_score(lr,os_x_train_w,os_y_train_w,cv=5,scoring='recall') # k折运算
- score_mean = sum(score)/len(score)
- scores.append(score_mean)
- end_time = time.time() # 结束时间
- print("第{}次。。。".format(z))
- print("time spend:{:.2f}".format(end_time-start_time))
- print("recall:{}".format(score_mean))
- z+=1
- # print(score_mean)
- best_c = c_param_range[np.argmax(scores)] # 最优C值
- lr = LogisticRegression(C=best_c,penalty='l2',max_iter=1000)
- lr.fit(os_x_train_w,os_y_train_w) # 对过采样随机取出的训练集数据进行训练
- from sklearn import metrics # 打印分类报告
- train_predict_big = lr.predict(os_x_train_w) # 将训练集自己导入模型进行测试
- print(metrics.classification_report(os_y_train_w,train_predict_big))
- test_predict_big = lr.predict(os_x_test_w) # 对测试集进行测试
- print(metrics.classification_report(os_y_test_w,test_predict_big))
- train_predict = lr.predict(x_train) # 对原始数据训练集进行测试
- print(metrics.classification_report(y_train,train_predict))
- cm_plot(y_train,train_predict).show()
- test_predict = lr.predict(x_test) # 对原始数据测试集进行测试
- print(metrics.classification_report(y_test,test_predict))
- cm_plot(y_test,test_predict).show()
- thresholds = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9] # 此处同样更改阈值
- recalls = []
- for i in thresholds:
- y_predict_proba = lr.predict_proba(x_test)
- y_predict_proba = pd.DataFrame(y_predict_proba)
- y_predict_proba = y_predict_proba.drop([0],axis=1)
- y_predict_proba[y_predict_proba[[1]] > i] = 1
- y_predict_proba[y_predict_proba[[1]] <= i] =0
- recall = metrics.recall_score(y_test,y_predict_proba[1])
- recalls.append(recall)
- print("{}Recall metric in the testing dataset:{:.3f}".format(i,recall))
复制代码 其打印结果如下:
1)过采样后的数据布局
2)肴杂矩阵可视化
3)结果的打印
四、总结
大批量数据的过采样是一种数据预处置处罚技能,用于办理数据不均衡标题。在数据会集,某些种别的样本数目显着少于其他种别,这会导致模子在训练时对少数种别的推测本领较差。过采样的目标是通过增长少数种别的样本数目,使得各个种别之间的样本数目更加均衡。
大批量数据的过采样可以通过以下步调实现:
- 选择过采样方法:常见的过采样方法包罗随机复制、SMOTE(合成少数类过采样技能)、ADASYN(自顺应合成过采样技能)等。每种方法有差异的原理和实用场景,选择恰当标题标方法是关键。
- 实行过采样:根据选择的过采样方法,对少数种别的样本举行复制或天生新样本。复制样本可以直接复制原始样本,天生样本则是根据少数种别样本的特性合成新样本。
- 调解过采样比例:过采样大概会导致样本数目过多,导致模子训练时间增长大概太过拟合。可以通过控制过采样比例来均衡样本数目,确保各个种别之间的样本数目靠近而不外于失衡。
|