数据了解
1.数据读取
open(), pd.read_csv(), datasets.load_iris()
注:原始数据的行、列标题;分隔符;其中使用datasets时运用load的话需要所需数据本来就存在其中
2.数据详情
df.head(), df.tail(), df.columns, df.info(), df.shape(), df.columns.tolist()
主要在于了解数据长什么样,有哪些字段,每个字段都是什么类型,针对不同类型的特征进行不同的数据转换,进而得到可以用于建模的特征
4.数据标注
df1['label'] = 1, df2['label'] = 0
标注正负样本,便于后期进行数据划分后进行数据检验
数据清洗
1.饱和度统计
df['feature'].drop_duplicates().count()/df.shape(0)
主要在于查看每个特征的缺失情况,选择合适的方法进行数据填充,这里需要搞清楚当特征缺失占比达到百分之多少的时候是不饱和的
2.缺失值处理
define function
针对不同的数据类型,通过自定义函数的方式,选择不同的方法进行填充
a. 数值型
填充方法:0、均值、中位数、众数、上下条记录、插值法、knn填充
b.布尔型
填充方法:缺失部分直接填充成False
c.有序离散型/连续型
填充方法:先数量化,再用数值填充
d.无序离散型
填充方法:转换成布尔型,再用False填充
注:如果缺失值较多(可能70%以上都是缺失的),则可考虑去除特征(前提是通过计算特征重要性后发现这个特征不重要)或者追究数据源
3.异常值处理
import seaborn as sns
sns.boxplot(df[['feature']])
通过绘制每一个特征的箱线图来判断对应特征的数据是否存在异常值
这里同样的只需要绘制重要特征的箱线图
首先需要确认数据是属于噪声还是异常值还是离群点,通常噪声是测量过程中产生的随机误差、异常值一组测定值中与平均值的偏差超过两倍标准差的测定值、离群点是一组数据中原理一般水平的极大值或极小值
针对噪声,可不必进行任何处理;针对异常值,可采用分箱的方式,每厢建立一个模型;离群点可以直接去掉
4.数据转换
-
结构化数据
结构化数据可以看作关系型数据库的一张表,包含数值型和类别两种基本类型;每一行数据表示一个样本的信息
可进行哑变量处理、序号编码(Ordinal Encoding) -
非结构化数据
非结构化数据主要是文本、图像、音频和视频数据,其包含的信息无法用一个简单的数值表示,也没有清晰的定义,数据大小互不相同
可采取one-hot编码进行处理 -
特征工程中的数据类型
数值型(可直接建模)
枚举(one-hot)
日期型(day)
无序离散型(比如手机品牌, bool)
有序离散型(比如早中晚, one-hot)
有序连续型(比如年龄段, on-hot)
针对数值较大的样本,可进行相关函数转换,比如:log
5.数据失衡
-
特征量级倾斜
扩充数据量
重采样 -
正负样本失衡
人工生成数据样本
假设正样本10w个,负样本90w个,则可进行以下两种方式进行处理过采样:相当于把90w个负样本划分成9组,分别和相同的10w个正样本进行建模,最后综合9个模型来判断模型的好坏
欠采样:相当于从90w个负样本中随机抽样10w个和正样本建模
**但是无论是过抽样还是欠抽样,均可能会产生过拟合的情况,故在建模过程中需要加上正则化,比如:LR、RF、XGB
数据分析
1.对比分析
sns.distplot(df[['feature']])
a.针对已知的正负样本绘制特征的概率密度图,查看数据分布情况
正常情况而言,主观上的显著性特征在正负样本上所呈现出来的数据规律是完全相反的,可以很明显就区分两个样本
b.正负样本聚合观察
假设正样本概率密度图呈现正态分布图样式,负样本则呈现相反的正态分布图样式,则把正负样本融合之后,得到的数据图会不会比较平缓?
虽然后期同样要进行正负样本合并,便于划分数据集,但是这里相当于要每个特征绘制三个概率密度图,后期会得到什么结论?对后期特征处理会有什么正向影响?
2.描述性统计分析
df.describe()
会得到每个特征对应的常见统计值
3.相关性分析(?相当于多重共线性)
sns.heatmap()
sns.pairplot()
绘制特征间的相关系数热力图,但是对于特征少的情况更适合画图,特征多的话可以直接计算相关系数矩阵
特征之间有强关系的话,需要剔除么?
特征变换
1.特征降维
-
connection
正常情况下针对特征很多的情况,会选择使用PCA、LPA等方法选择能解释更多信息的特征来代替其他特征,但是这样的效率会比较慢,同时也会导致数据信息丢失,所以考虑多个特征结合的方式进行降维
-
derivative
由于多个特征聚合在一起,便会产生新的衍生特征,比如手机型号、价格等可统一成一个phone_info特征
2.onehot编码
from sklearn.preprocessing import OneHotEncoder
one_hot_encoder = OneHotEncoder(sparse=False, categories = 'auto')
one_hot_feas = pd.DataFrame(one_hot_encoder.fit_transform(data))
原因:
通常情况下计算特征之间相似性,需要计算彼此间的距离,如果非数值型不好计算,所以需要进行onehotencoder编码;如果本来就是离散型数值型变量,则直接计算彼此之间的距离就好了,或者直接进行归一化处理
原理:
分类变量作为二进制向量的表示,首先将分类值映射到整数值,然后每个整数值表示为二进制向量
应用:
离散无序的分类特征,通常用于xgb、gbdt;用在lr里面效果不好,因为lr要求特征之间相互独立;如果需要onehot的特征较多会造成非奇异矩阵的解不唯一
注意:需要在切分数据之后
3.特征挑选
- 基模型
现根据数据展现出来的特性选择合适的模型、利用默认参数建立一个基模型,需要计算对应的score
- 计算特征重要性
这个是在建立基模型之后么?这里可以挑选出优质的特征,然后再进行建模?
数据建模
1.数据划分
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(df, label, test_size=0.3, random_state=number)
使用训练集训练基模型和优化模型,在只有训练集和测试集的情况下,比例为7:3,在还有验证集的情况下,比例为6:2:2
参数解释:random_state为任意整数时,每次进行建模的数据都是一样的,random_state为0时,每次进行建模的数据都不一样
2.模型选择
-
确定模型
根据基模型的效果、数据量、特征个数、数据质量选择合适的模型
a.二分类
LR:可解决多重共线性问题、计算量小
不适合高维度数据、易欠拟合、非线性特征需要进行线性变换
b.多分类
KNN(x):可用于非线性分类、准确度高
不适用于样本不平衡问题、计算量大
DT/RF(x):适合处理有缺失数据的样本、运行速度快
易产生过拟合
SVM(x):适用于小样本、可解决高维度样本
很难处理非线性问题、对缺失值敏感、核函数(线性核、多项式核、RBF以及sigmoid核)难选择
XGB:精度高、计算过程中考虑了正则项、可进行缺失值处理
GBDT: 模型调用
sklearn.svm.SVC #需要加上核函数kernel='linear'/('poly', degree=3)
sklearn.LogisticRegression
sklearn.neighbors.KNeighborsClassifier
sklearn.Linear_model.LinearRegression
sklearn.cluster.KMeans(n_clusters=3)
sklearn.decomposition.PCA()
3.参数调整
-
GridSearchCV()
网格搜索和交叉验证
网格搜索:搜索的是参数,即在指定的参数范围内,按步长依次调整参数,利用调整的参数训练学习器,从所有的参数中找到在验证集上精度最高的参数,这其实是一个循环和比较的过程
GridSearchCV可以保证在指定的参数范围内找到精度最高的参数,但是这也是网格搜索的缺陷所在,它要求遍历所有可能参数的组合,在面对大数据集和多参数的情况下,非常耗时 -
RandomizedSearchCV()
RandomizedSearchCV的使用方法其实是和GridSearchCV一致的,但它以随机在参数空间中采样的方式代替了GridSearchCV对于参数的网格搜索,在对于有连续变量的参数时,RandomizedSearchCV会将其当作一个分布进行采样这是网格搜索做不到的,它的搜索能力取决于设定的n_iter参数
参数说明:
clf:学习器,比如:clf = svm.SVC(kernel = 'linear')
param_dist:参数搜索范围
param_dist = {
'n_estimators':range(80,200,4),
'max_depth':range(2,15,1),
'learning_rate':np.linspace(0.01,2,20),
'subsample':np.linspace(0.7,0.9,20),
'colsample_bytree':np.linspace(0.5,0.98,10),
'min_child_weight':range(1,9,1)
}
scoring:精度评价方式
n_tier:训练次数(数值越大,获得的参数精度越大,但是搜索时间越长)
n_jobs:cpu选择,通常默认为1,表示使用1个cpu
grid = RandomizedSearchCV(clf, param_dist, cv = 3, scoring = 'neg_log_loss', n_iter=300, n_jobs = -1)
grid.fit(x_train, y_train)
best_estimator = grid.best_estimator_ # 返回最优的训练器
print(grid.best_estimator) # 输出最优训练器的精度
print(grid.best_scores_)
模型检验
混淆矩阵
相关,正类 | 无关,负类 | |
---|---|---|
被检索到 | TP | FP |
无关,负类 | FN | TN |
- 伪正类率(False positive rate,FPR,FPR=FP/(FP+TN)):预测为正但实际为负的样本占所有负例样本的比例;
- 真正类率(True positive rate,TPR,TPR=TP/(TP+FN)):预测为正且实际为正的样本占所有正例样本的比例。
1.accuracy
- 准确率
metrics.accuracy_score()
预测正确的占比
accuracy = (TP + TN) / (TP +FP + FN + TN)
2.precision
- 精确率
precision_score()
实际为正占预测为正的占比
precision = TP / (TP + FP)
3.recall
- 召回率
recall_score()
正确预测为正占实际为正的占比
recall = TP / (TP + FN)
4.f1-score
- H-mean值
f1_score()
算数平均数除以几何平均数
f1 = 2TP / (2TP + FP + FN)
5.AUC-ROC
-
ROC曲线
接收者操作特征曲线,是反映敏感性和特异性连续变量的综合指标,ROC曲线上每个点反映着对同一信号刺激的感受性
横轴:FPR
纵轴:TPR
真正的理想情况,TPR应接近1,FPR接近0,ROC曲线越靠拢(0,1)点,越偏离45度对角线越好 -
AUC
ROC曲线下的面积,显然这个面积的数值不会大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围一般在0.5和1之间
模型优化
- 基于基模型的检验指标,找到影响过拟合/欠拟合的原因,更新模型/参数,得到优化后的模型
- 调整参数【迭代次数30/50/80,学习率0.2,深度3/5/8】