「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」
数据预处理
# 基本库
import pandas as pd
import numpy as np
# 取数据
csv_df = pd.read_csv('data/abalone.csv')
# 设置列名
csv_df.columns= ['Sex', 'Length', 'Diameter', 'Height', 'Whole weight','Shucked weight', 'Viscera weight', 'Shell weight', 'result']
df = pd.DataFrame(csv_df)
df.head(5)
# 对lable进行硬编码(factorize),对性别变量进行one-hot编码(dummies)
label = pd.DataFrame({'label': pd.factorize(df['result'])[0]}) # 用字典指定列名
dummies = pd.get_dummies(df.drop(columns=['result']))
data = pd.concat([dummies, label], axis=1) # 行拼接
data.head(10)
pandas.factorize可以实现将字符串特征转化为数字特征
为啥数据要进行one-hot编码?🤔
举一个例子,如血型一般分为A、B、O、AB四个类型,为无序多分类变量,通常情况下在录入数据的时候,为了使数据量化,我们常会将其赋值为1、2、3、4。
从数字的角度来看,赋值为1、2、3、4后,它们是具有从小到大一定的顺序关系的,而实际上,四种血型之间并没有这种大小关系存在,它们之间应该是相互平等独立的关系。如果按照1、2、3、4赋值并带入到回归模型中是不合理的,此时我们就需要将其转化为哑变量。
one-hot编码可以将分类变量装换为“哑变量矩阵”(dummy matrix)。如果DataFrame的某一列中含有K个不同的值,则可以派生出一个K列矩阵或者DataFrame(其值全为0和1)。pandas 有一个get_dummies函数可以实现该功能 。在pandas可以指定 columns参数,pd.get_dummies(df,columns=["key","sorce"])指定被编码的列,返回被编码的列和不被编码的列;prefix参数可以给哑变量的名字加上一个前缀。
EDA(exploratory data analysis)
import matplotlib.pyplot as plt
import seaborn as sns
# 描述性统计
data.describe()
# 计算相关系数,展示参数间相关系数的热力图
corr = data.corr()
ax = plt.subplots(figsize=(14, 8))[1]
ax.set_title('Correlation')
sns.heatmap(corr, annot=True, cmap='RdBu')
plt.show()
# 显示变量两两之间关系的散点图
sns.pairplot(data, hue='label')
plt.show()
模型训练及测试
代码
def showClassificationData(X, Y, ifFit=False, overSampling='None'):
"""
showData实现多维二分类任务的数据可视化,函数接受数值型变量,使用PCA可视化。
:param overSampling: 对样本进行重采样
:param ifFit: 画图时是否对数据进行拟合
:param X: 设计矩阵(不含标签)
:param Y: 分类标签
"""
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.decomposition import PCA
from imblearn.over_sampling import SMOTE
from imblearn.combine import SMOTETomek, SMOTEENN
def getSMOTE():
return SMOTE(random_state=10)
def getSMOTETomek():
return SMOTETomek(random_state=10)
def getSMOTEENN():
return SMOTEENN(random_state=10)
switch = {'SMOTE': getSMOTE,
'SMOTETomek': getSMOTETomek,
'SMOTEENN': getSMOTEENN}
if overSampling != 'None':
overSampler = switch.get(overSampling)()
X, Y = overSampler.fit_resample(X, Y)
# PCA提取两个主成分
pca = PCA(n_components=2) #n_components为保留下来的特征个数
print("降维前:",X)
X = pca.fit_transform(X) #X就是降维后的数据
print("降维后:",X)
X = pd.DataFrame(X)
Y = pd.DataFrame(Y)
X = pd.concat([X, Y], ignore_index=True, axis=1)
X.columns = ['firstIngridient', 'secondIngridient', 'label']
sns.lmplot('firstIngridient', 'secondIngridient', X, hue='label', fit_reg=ifFit)
plt.show()
#查看两类数据差距
def showHistogram(Y, ifLog=False):
"""
showHistgoram实现对计数变量的分布可视化
:param ifLog: 是否对数据进行对数变换
:param Y: 响应变量
"""
import matplotlib.pyplot as plt
import seaborn as sns
Y = pd.DataFrame(Y)
sns.set_style('whitegrid')
fig, ax = plt.subplots()
Y.hist(ax=ax, bins=100)
if ifLog:
ax.set_yscale('log')
ax.tick_params(labelsize=14)
ax.set_xlabel('count', fontsize=14)
ax.set_ylabel('Y', fontsize=14)
print("showHistogram:")
plt.show()
def multiClassificationModel(X, Y, testSize=0.3, cv=5, ifSmote=False, ifKFold=False,ifRandomUnderSampler=False):
"""
multiClassificationModel实现朴素贝叶斯、支持向量机、Logistic回归和XGBoost在数据集上的分类性能测试
:param ifSmote: 是否做SMOTE重采样
:param X: 特征矩阵
:param Y: 标签
:param testSize: 测试集大小,默认为0.3
:param cv: k折交叉验证的k值
"""
print("使用不同模型分类的效果:")
from collections import Counter
from sklearn import naive_bayes, svm, linear_model,neighbors,tree
from sklearn.model_selection import train_test_split, cross_val_score,StratifiedKFold
from sklearn.metrics import accuracy_score, f1_score, recall_score, precision_score
import xgboost
from imblearn.over_sampling import SMOTE
def train(model, x_train, y_train):
return model.fit(x_train, y_train)
def printScore(model, x, y):
print('召回率(recall): ', recall_score(y, model.predict(x))) #召回率
print('精确度(Precision): ', precision_score(y, model.predict(x))) #准确率
print('f1: ', f1_score(y, model.predict(x))) #f1值
print('准确率(accuracy): ', accuracy_score(y, model.predict(x)))
def printKFoldScore(model, X, Y, cv):
print('recall: ', cross_val_score(model, X, Y, cv=cv, scoring='recall').mean())
print('precision: ', cross_val_score(model, X, Y, cv=cv, scoring='precision').mean())
print('f1: ', cross_val_score(model, X, Y, cv=cv, scoring='f1').mean())
print('accuracy: ', cross_val_score(model, X, Y, cv=cv, scoring='accuracy').mean())
# 划分数据集
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=testSize, random_state=10)
if ifSmote:
smo = SMOTE(random_state=10)
print("过采样之前的数据:",Counter(y_train))
x_train, y_train = smo.fit_resample(x_train, y_train)
print("过采样之后的数据:",Counter(y_train))
from imblearn.under_sampling import ClusterCentroids
#欠采样
if ifRandomUnderSampler:
cc = ClusterCentroids(random_state=0)
print("欠采样之前的数据:",Counter(y_train))
x_train, y_train = cc.fit_resample(x_train, y_train)
print("欠采样之后的数据:",Counter(y_train))
#感知机
Perceptron = linear_model.Perceptron()
#KNN
KNN = neighbors.KNeighborsClassifier()
#决策树
decision_tree=tree.DecisionTreeClassifier()
# 朴素贝叶斯
NB = naive_bayes.GaussianNB()
# SVM
SVM = svm.SVC()
# logisticRegression
LR = linear_model.LogisticRegression(max_iter=5000)
# xgboost
Xgb = xgboost.XGBClassifier()
model_list = [NB, SVM, LR, Xgb, KNN,decision_tree,Perceptron]
for i in range(len(model_list)):
model_list[i] = train(model_list[i], x_train, y_train)
print('----- train -----')
for model in model_list:
print('#### {} ####'.format(str(model).split('(')[0]))
printScore(model, x_train, y_train)
print()
print('----- test -----')
for model in model_list:
print('#### {} ####'.format(str(model).split('(')[0]))
printScore(model, x_test, y_test)
print()
if ifKFold:
print("********** Stratified k-fold cross validation 分层交叉验证 **********")
for model in model_list:
print('#### {} ####'.format(str(model).split('(')[0]))
strKFold = StratifiedKFold(n_splits=2,shuffle=True,random_state=0)
printKFoldScore(model, X, Y, cv=strKFold)
print()
应用
X = data.drop(columns=["label"]) #删除label列
Y = data["label"] #label列
showHistogram(Y)
multiClassificationModel(X, Y,ifSmote=True,ifRandomUnderSampler=False,ifKFold=True)
使用不同模型训练的效果:
使用不同模型测试的效果:
评价指标
正样本/正例/正类:(二分类)任务中想要查找(识别)出来的类别
精确度(Precision)
表示的是真正例占模型判断出的所有正例的比例。
用途:用于评估检测器在检测成功基础上的正确率
召回率(recall)
表示的是模型正确判断出的正例占数据集中所有正例的比例。
用途:用于评估检测器对所有待检测目标的检测覆盖率。
一般来说,准确率就是检索出来的条目中有多少是准确的,召回率就是所有准确的条目有多少被检索出来了。准确率和召回率区别就是分母不同,一个分母是预测为正的样本数,另一个是原来样本中所有的正样本数。
通过绘制precision-recall 曲线,该曲线下方的面积越大,识别精度也就越高,反之越低。
#准确率
sklearn.metrics.precision_score(y_true, y_pred, labels=None, pos_label=1, average=’binary’, sample_weight=None,zero_division='warn')
#召回率
sklearn.metrics.recall_score(y_true, y_pred, labels=None, pos_label=1, average='binary', sample_weight=None, zero_division='warn')
输入参数:
y_true:真实标签。
y_pred:预测标签。
labels:可选参数,是一个list。二分类时,用不上这个参数。
pos_label:字符串或者int类型,默认值是1。
average:字符串类型,取值为 [None, ‘binary’ (默认), ‘micro’, ‘macro’, ‘samples’, ‘weighted’]。默认为二分类。
sample_weight:样本比重
zero_division:默认为“warn”,表示 0 or 1,设置除法为零(即所有预测和标签均为负)时返回的值。如果设置为“ warn”,则该值为0, 但也会发出警告。
输出:
正样本准确率、召回率,浮点型。
F1值
准确率和召回率指标有时候会出现的矛盾的情况,这样就需要综合考虑他们,最常见的方法就是F1值。F1综合了准确率和召回率的结果,当F1较高时则能说明试验方法比较有效。
准确率(Accuracy)
表示的是模型判断正确的数据(预测对了, 本来是正样本检测为正样本,本来是负样本检测为负样本)占总数据的比例。
通常来说,正确率越高,分类器越好。
K-Fold 交叉验证
在机器学习建模过程中,通常的做法通常是将数据分为训练集和测试集。测试集是与训练独立的数据,完全不参与训练,用于最终模型的评估。在训练过程中,经常会出现过拟合的问题。
过拟合问题就是模型可以很好的匹配训练数据,却不能很好在预测训练集外的数据。
如果此时就使用测试数据来调整模型参数,就相当于在训练时已知部分测试数据的信息,会影响最终评估结果的准确性。通常的做法是在训练数据再中分出一部分做为验证(Validation)数据,用来评估模型的训练效果。
验证数据从训练数据中获取,但不参与训练,这样可以相对客观的评估模型对于训练集之外数据的匹配程度。模型在验证数据中的评估常用的是交叉验证,又称循环验证。
它将原始数据分成K组(K-Fold),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型。这K个模型分别在验证集中评估结果,最后的误差MSE(Mean Squared Error)加和平均就得到交叉验证误差。
何时使用K-Fold🤔?
数据总量较小时,其他方法无法继续提升性能,可以尝试K-Fold。其他情况就不太建议了,例如数据量很大,就没必要更多训练数据,同时训练成本也要扩大K倍(主要指的训练时间)。
sklearn
scikit-learn,又写作sklearn,是一个开源的基于python语言的机器学习工具包。它通过NumPy, SciPy和Matplotlib等python数值计算的库实现高效的算法应用,并且涵盖了几乎所有主流机器学习算法。
sklearn里有什么👀❓
sklearn中常用的模块有分类、回归、聚类、降维、模型选择、预处理。
1️⃣分类:常用的算法有:SVM(支持向量机)、nearest neighbors(最近邻)、random forest(随机森林),常见的应用有:垃圾邮件识别、图像识别。
2️⃣回归:预测与对象相关联的连续值属性,常见的算法有:SVR(支持向量回归机)、 ridge regression(岭回归)、Lasso,常见的应用有:药物反应,预测股价。
3️⃣聚类:将相似对象自动分组,常用的算法有:k-Means、spectral clustering(谱聚类)、mean-shift(均值偏移),常见的应用有:客户细分,分组实验结果。
4️⃣降维:减少要考虑的随机变量的数量,常见的算法有:PCA(主成分分析)、feature selection(特征选择)、non-negative matrix factorization(非负矩阵分解),常见的应用有:可视化,提高效率。
5️⃣模型选择:比较,验证,选择参数和模型,常用的模块有:grid search(网格搜索)、cross validation(交叉验证)、 metrics(度量)。它的目标是通过参数调整提高精度。
6️⃣预处理:特征提取和归一化,常用的模块有:preprocessing,feature extraction,常见的应用有:把输入数据(如文本)转换为机器学习算法可用的数据。
7️⃣sklearn里还有数据集,如我们经常见到的鸢尾花数据集、波士顿房价数据集...
sklearn用起来简单到💥
安装只需要 pip install scikit-learn
引入程序只需要
from sklearn import naive_bayes, svm, linear_model,neighbors,tree
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score, f1_score, recall_score, precision_score
你想要什么算法只要from sklearn import 它,模型算法都在一句话里,你就可以直接调用起飞😋
以上相关代码请戳👉gitee.com/xin-yue-qin…
参考资料
python 数据处理之使用get_dummies进行one-hot编码---yuxj记录学习
# sklearn(三)计算recall:使用metrics.recall_score()计算二分类的召回率--凝眸伏笔