数据建模步骤
文章目录
1. 读取数据
读取时可提前考虑数据分隔符、字段、编码、表头、索引等。
2. 观察数据
-
查看数据基础信息,了解数据含义,查看数据样本标签,确定标签个数,样本均衡度等。
处理样本不均衡:
-
最佳方法:增加较少的样本的数量(实际上是增加真实数据)
-
sample_weight:通过给样本较少的数据更多的权重,和给样本更多的数据更少的权重,是得增加权重过后的样本大致均衡。(机器学习算法会更加关注权重更高的数据,但相应的,这部分数据也有更大的风险发生过拟合)
-
欠采样和过采样:
过采样:通过将少的样本进行随机的复制组合,补充到多的样本的个数,使得总体样本均衡。(重复少的数据 随机重复 算法伪造-有风险)
欠采样:将样本更多的数据进行去除,使得和少的样本个数一致,总体样本均衡。(随机抛弃多的数据) -
摆烂,不处理
-
-
对数据进行EDA(探索性数据分析),可通过绘制简单饼图或柱状图折线图等对数据经进行初步了解。
3. 特征工程
3.1 特征提取 特征选择
-
基于业务需求提取需要的、重要的特征
-
辨别数据的连续值和离散值,观察离散值分布,先处理离散字段的映射,对离散值进行预处理(对特征一个一个处理),哑变量太多会出现维度爆炸的情况。
特别少的 - 直接删除;
类似的特征 - 可以整合;
样本不均衡 - 欠采样/过采样。
3.2 数据清洗/预处理
查看数据的统计学指标 查看1% 99%分位数 (1%分位数和Min作比较,99%分位数和max作比较)
3.2.1 空值检测
# 该方法更容易准确识别
df.isnull().mean()
3.2.2 异常值处理
- 怎么去除异常数据:
step1: 基于业务逻辑去除异常数据 如 满分100分 - 有三个同学考到120分
step2: 做标准正太分布转化, 利用三倍标准差作为异常检测标准
step3:使用离群点的方式进行过滤异常
- 连续型的字段,把99%分位数以上的数据删除,其他数据做正态分布转换
# 异常值过滤 - 过滤掉99分位数以上的数据
p99_gain = np.quantile(df.capital_gain.values, [0.99])[0] # 获取99%分位数值
df = df.loc[df.capital_gain < p99_gain]
- 转换完过后可以继续做3倍标准差的异常剔除
# 思路:借助bool值进行loc条件筛选
condition = (np.abs(df[feature_con])>df[feature_con].std()*3).any(axis=1)
# 异常数据的获取
exp_data = df.loc[condition]
# 从原始数据集中剔除异常数据
df.drop(exp_data.index, inplace=True)
3.3 数据标准化
- 对连续型的数据进行标准正态分布转换
降噪
提升算法效率(迭代优化的过程)
提出异常 3*std
from sklearn.preprocessing import StandardScaler
# col_data必须是二维数组/二维数据
df[col_name] = StandardScaler().fit_transform(col_data)
- 离散型数据字段:离散字段 - 哑编码
pd.get_dummies(df.column)
column1_df = pd.get_dummies(df.column1)
column2_df = pd.get_dummies(df.column2)
.....
# 拼接哑变量数据
part2 = pd.concat([column1_df,column2_df,....,],axis=1).copy()
3.4 数据拼接
拼接离散值数据集和连续值数据集
4. 建模
# 逻辑斯蒂回归
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
# 拆分训练集与测试集合
X_train,X_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=2)
# 1.实例化
lr = LogisticRegression()
# 2.训练模型
lr.fit(X_train, y_train)
# 3.预测模型
lr.predict(X_test)
# 4.看模型评分
lr.score(X_test, y_test)
5. 模型评估
5.1 交叉验证
# 往前推一步 交叉验证(做交叉验证就不需要进行训练集和测试集划分了)
from sklearn.model_selection import cross_val_score
# 获取cv=50折交叉验证的模型评分
result = cross_val_score(lr, X, y, cv=50)
# 获取模型评分的平均值
result.mean()
5.2 网格搜索(参数调优,默认5折)
from sklearn.model_selection import GridSearchCV
# 1.先实例化模型
lr = LogisticRegression()
# 2.设定参数字典
params = {
'penalty':['l1','l2'], # 正则化项
'C':[0.1, 0.5, 0.7, 1.0, 3.0], # 惩罚系数 C越大 对错误的容忍度越高,越容易欠拟合
'max_iter':[50,100,200,500] # 越大容易接近绝对最优解
}
# 3.网格搜索 实例化
gscv = GridSearchCV(lr,param_grid=params)
# 训练
gscv.fit(X,y)
# 泛化能力最强的最优解(获得)
gscv.best_params_ # {'C': 1.0, 'max_iter': 50, 'penalty': 'l2'}
# 直接调用最优参数组合
gscv.best_estimator_.score(X,y)
# 也可以根据最优参数重新建模
good_lr = LogisticRegression(C=1, max_iter=50) # 逻辑斯蒂默认L2正则化项
good_lr.fit(X_train, y_train)
good_lr.score(X_train, y_train),good_lr.score(X_test, y_test)
5.3 ROC曲线绘制
from sklearn.metrics import f1_score
y_ = good_lr.predict(X_test)
f1_score(y_test, y_, pos_label='>50K') # 此处'>50K'是数据集标签,表示‘正样本’
# 绘制ROC曲线
from sklearn.metrics import roc_curve
y_scores = good_lr.predict_proba(X_test) # 正反例概率值
fpr, tpr, threshols = roc_curve(y_test, y_scores[:,:1], pos_label='>50K')
# 绘制ROC曲线
plt.plot(tpr, fpr)
plt.plot(np.linspace(0,1,20),np.linspace(0,1,20),ls='--',color='red')
plt.xlabel('TPR')
plt.ylabel('FPR')