机器学习-基于PipeLine模型的电动汽车价格预测
2020-05-29 本文已影响0人
Nick是老外
说明:本赛题及数据来源于-全国首届研究生工业与金融大数据建模与计算比赛
本文做的是题目中的C题:电动汽车价格预测
某品牌电动汽车给出了不同规格的电动车属性与价格数据(见 train.xlsx),另有一批未 知价格的电动车属性数据(见 test.xlsx),请通过挖掘属性与价格之间的关系给出这批未知价 格电动车的价格预测。 附: 1、属性的具体含义请见:tag.xlsx 2、价格已分档,为 0-3 之间的一个整数,请将最后的预测也以分档的形式给出。
一.问题分析: image.png
由字段说明可知电动车特征变量为20维变量,目标为价格分档,由0,1,2,3四档价格。且train.xlsx中的1500组数据的价格等级已给出,可以通过该数据集训练好的模型来预测test.xlsx中的500个未知数据。针对该问题,我们先对数据进行可视化分析,通过进行相关系数矩阵和散点矩阵对数据进行分析。然后构建包含有数据标准归一化、主成分分析和MLP多层感知机的PipeLine模型,将训练集按照4:1再分为训练集和测试集,并根据多个评价指标对模型进行调参改进,得到最终的训练模型对预测数据进行分类预测。
二、数据分析
1.数据可视化--分析各个变量维度分布
import pandas as pd
df = pd.read_excel('E:\\PycharmFiles\\Price_Data\\train.xlsx')#读取Excel时路径中用\\
df=df.drop(['id'],axis=1) #删除第一列‘id’
print('rows,columns:',df.shape) #多少行和列
df.head() #显示前五行
import matplotlib.pyplot as plt # 可视化
X=df.iloc[:,:20].values #t样本特征
y=df.iloc[:,20].values #样本结果
def draw(df):#函数绘制各维特征的分布直方图。
df.hist(figsize=(16,14),color='g',bins=80, normed=False)
#plt.title('各个特征的分布直方图') # 设置x轴标题
plt.savefig("Plots.jpg",dpi=300, pad_inches = 0)
plt.show()
draw(df.iloc[:,0:20])
各变量分布直方图.png
2.相关性分析--利用热力图可以看数据表里多个特征两两的相似度,相似度由皮尔逊相关系数度量
from seaborn import heatmap
import seaborn as sns
#两个变量之间的皮尔逊相关系数定义为两个变量之间的协方差和标准差的商
def draw_heatmap(df):
ylabels = df.columns.values.tolist()
ss = StandardScaler() # 归一化
data = ss.fit_transform(df)
dff = pd.DataFrame(data)
dfData = dff.corr()
plt.subplots(figsize=(16, 16)) # 设置画面大小
sns.heatmap(dfData, annot=True, vmax=1, square=True,yticklabels=ylabels,xticklabels=ylabels, cmap="Greens")
#plt.savefig('../img/thermodynamicDiagram.jpg')
plt.show()
draw_heatmap(df.iloc[:,0:20])
皮尔逊相关系数.png
3.散点图矩阵--看具有相关性的变量之间的联系,散点图表示因变量随自变量而变化的大致趋势
sns.pairplot(data=df.iloc[:,4:20], palette='gnuplot_r',markers="o",vars=['feat5','feat11','feat12','feat13','feat15','feat16','feat18','feat6']
,plot_kws=dict(s=50, edgecolor="y", size=5,linewidth=1))
plt.title('散点图矩阵')
plt.xlabel(xlabel=None,fontsize=5)
plt.show()
散点图矩阵.png
三、模型建立
1.模型训练(数据标准化、PCA降维、MLP神经网络)
from sklearn.preprocessing import StandardScaler # 用于进行数据标准化
from sklearn.decomposition import PCA # 用于进行特征降维,PCA主成分降维
from sklearn.model_selection import train_test_split
#主成分分析经常用于减少数据集的维数,同时保持数据集中的对方差贡献最大的特征
from sklearn.linear_model import LogisticRegression # 逻辑回归分类器用于模型预测
from sklearn.neural_network import MLPClassifier # 神经网络模型
from sklearn.pipeline import Pipeline #管道
import numpy as np
from sklearn.preprocessing import label_binarize
X=df.iloc[:,:20].values #t样本特征(标签)
y=df.iloc[:,20].values #样本分类结果结果
price_types = df['price'].unique()#返回一个无重复值的数组
n_class = price_types.size #标签类别
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.20,random_state=1)#训练集50%,测试集占20%
y_one_hot = label_binarize(y_test, np.arange(n_class)) #转换成类似二进制的编码
pipe_lr = Pipeline([('scl', StandardScaler()), ('pca', PCA(n_components=18)), ('clf',
MLPClassifier(solver='sgd', # ‘lbfgs’, ‘sgd’, ‘adam’ 优化权重
activation='logistic', # ‘identity’, ‘logistic’, ‘tanh’, ‘relu’ 激活函数
alpha=1e-4, # 正则化参数
hidden_layer_sizes=(50, 50),
random_state=1,
max_iter=100, #最大迭代次数 max_iter=400 次
verbose=False, # 是否打印过程?
# learining_rate="adaptive", # ‘constant’,’invscaling’, ‘adaptive’ 学习率
learning_rate_init=.1
)
)])
pipe_lr.fit(X_train,y_train) #将 pipeline 对象 pipe_lr 在训练集上进行拟合
y_pred = pipe_lr.predict(X_test) #对验证集集进行预测
#用评价函数在训练集上对模型进行评分
print('Train Accuracy:%.3f' % pipe_lr.score(X_train,y_train))
#用评价函数在测试集上对模型进行评分
print('Test Accuracy:%.3f' % pipe_lr.score(X_test,y_test))
print('测试集y_pred:' , y_pred) #输出模型对验证集的预测
print('测试集y_preds size:' ,y_pred.size)
输出.png
2.模型评估(分类报告和混淆矩阵,ROC曲线和AUC值)
#输出验证集分类报告和混淆矩阵
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
import seaborn as sns
#输出分类报告
print('验证集分类报告:\n',classification_report(y_test,y_pred))#“The support is the number of
occurrences of each class in y_true.”
confusion_mc = confusion_matrix(y_test,y_pred)#混淆矩阵
df_cm = pd.DataFrame(confusion_mc)
plt.figure(figsize = (10,7))
sns.heatmap(df_cm, annot=True, cmap="BuPu",linewidths=1.0,fmt="d")
plt.title('PipeLine accuracy:{0:.3f}'.format(accuracy_score(y_test,y_pred)),fontsize=20)
plt.ylabel('True label',fontsize=20)
plt.xlabel('Predicted label',fontsize=20)
分类报告.png
混淆矩阵.png
#模型评价:ROC曲线和AUC值
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import average_precision_score
from sklearn.metrics import roc_curve
from sklearn import metrics
import matplotlib as mpl
# 计算属于各个类别的概率,返回值的shape = [n_samples, n_classes]
y_score = pipe_lr.predict_proba(X_test)
# 1、调用函数计算验证集的AUC
print ('调用函数auc:', metrics.roc_auc_score(y_one_hot, y_score, average='micro'))
# 2、手动计算验证集的AUC
#首先将矩阵y_one_hot和y_score展开,然后计算假正例率FPR和真正例率TPR
fpr, tpr, thresholds = metrics.roc_curve(y_one_hot.ravel(),y_score.ravel())
auc = metrics.auc(fpr, tpr)
print('手动计算auc:', auc)
#绘图
mpl.rcParams['font.sans-serif'] = u'SimHei'
mpl.rcParams['axes.unicode_minus'] = False
#FPR就是横坐标,TPR就是纵坐标
plt.figure(figsize = (10,7))
plt.plot(fpr, tpr, c = 'r', lw = 2, alpha = 0.7, label = u'AUC=%.3f' % auc)
plt.plot((0, 1), (0, 1), c = '#808080', lw = 1, ls = '--', alpha = 0.7)
plt.xlim((-0.01, 1.02))
plt.ylim((-0.01, 1.02))
plt.xticks(np.arange(0, 1.1, 0.1))
plt.yticks(np.arange(0, 1.1, 0.1))
plt.xlabel('False Positive Rate', fontsize=16)
plt.ylabel('True Positive Rate', fontsize=16)
plt.grid(b=True, ls=':')
plt.legend(loc='lower right', fancybox=True, framealpha=0.8, fontsize=12)
plt.title('300个验证集分类后的ROC和AUC', fontsize=18)
plt.show()
AUC&ROC曲线.png
绘制不同激活函数学习曲线得到样本数与准确率的关系
activation='logistic', ‘identity’, ‘logistic’, ‘tanh’, ‘relu’ 激活函数
import matplotlib.pyplot as plt
from sklearn.model_selection import learning_curve
#train_sizes=np.linspace(0.1, 1.0, 10),将训练集大小划分为10个相等的区间,在0.1和1之间线性的取10个值
#learning_curve默认使用分层k折交叉验证计算交叉验证的准确率,我们通过cv设置k,cv=10,10折
train_sizes,train_scores,test_scores = learning_curve(estimator=pipe_lr,
X=X_train,
y=y_train,
train_sizes=np.linspace(0.1, 1.0, 10), #在0.1和1间线性的取10个值
cv=10,
n_jobs=1)
train_mean = np.mean(train_scores,axis=1)#训练集均值
train_std = np.std(train_scores,axis=1)#训练集标准差
test_mean = np.mean(test_scores,axis=1)#验证集均值
test_std = np.std(test_scores,axis=1)#验证集标准差
plt.plot(train_sizes, train_mean,
color='blue', marker='o',
markersize=5, label='train accuracy')#学习曲线
plt.fill_between(train_sizes,
train_mean + train_std,
train_mean - train_std,
alpha=0.15, color='blue')
plt.plot(train_sizes, test_mean,
color='green', linestyle='--',
marker='s', markersize=5,
label='validation accuracy') #验证曲线
plt.fill_between(train_sizes,
test_mean + test_std,
test_mean - test_std,
alpha=0.15, color='green')
plt.grid(c='y')
plt.xlabel('Number of training samples')
plt.ylabel('Accuracy')
plt.title('logistic activation')
plt.legend(loc='lower right')
plt.ylim([0.6, 1.0])
plt.tight_layout()
plt.show()
激活函数.png
identity.png | logistic.png |
---|---|
relu.png | tanh.png |
:- | :- |
image.png
三、模型保存和加载
1.保存模型
import os
from sklearn.externals import joblib
#创建文件目录 os.makedirs('d:\\books\\book')
dirs = ' E:\\PycharmFiles\\Price_Data\\testModel'
if not os.path.exists(dirs):
os.makedirs(dirs)
joblib.dump(pipe_lr , dirs+'/pipe_lr.pkl')
2.加载模型
pipe_lr = joblib.load(dirs+'/pipe_lr.pkl')#读取模型
dff = pd.read_excel('E:\\PycharmFiles\\Price_Data\\test.xlsx')#读取数据
print('rows,columns:',dff.shape)
dff = dff.drop(['id'],axis=1) #删除第一列‘id’
#dff.head() #前五行
X=dff.iloc[:,:20].values #输入样本特征
y_pred = pipe_lr.predict(X)
print('y_pred :',y_pred)
print('y_preds size:' ,y_pred.size)
模型对测试集的预测.png
代码说明:所有分块代码均在Jupyter Notebook上运行,读者运行代码时需要改变其中的路径
参考文章1:用 Pipeline 将训练集参数重复应用到测试集
参考文章2:模型介绍、评估和参数调优(附代码)
参考文章3:机器学习系统模型调优实战--所有调优技术都附相应的scikit-learn实现
特别说明:参考或转发本文需注明本文链接,有问题请联系:2210432548@qq.com