机器学习--预测蛋白质含量实验

前言:此实战为学校机器学习大作业的内容,历时3-4个礼拜,特发此文章以记录做大作业的过程以及遇到的问题。作业中的数据集就不提供了,只是提供我解决这个问题的一个思路。

一、实验介绍

实验给定了300多个样本的近红外光谱数据以及相应的蛋白质含量,要求基于近红外光谱数据自动预测该样本蛋白质含量。本实验将300多个样本分成了训练集和测试集,训练集约283个样本,测试集约95个样本。其中数据集特征即为近红外光谱各个波数所对应的吸光度,波数范围为3997.95~10002.02 /cm,共计有2102个波数,也就是说每个样本会提供2102个特征。实验需要从2102个波数中选择3至20个波数来进行训练并且对测试集进行预测(预测蛋白质含量)。

由此实验介绍可以看出这是一个回归问题,可以去搜索相应的回归模型来解决此问题。常见的回归模型如下:

Linear Regression(线性回归)
Decision Tree Regressor(决策树回归)
SVM Regressor(支持向量机回归)
K Neighbors Regressor(K近邻回归)
Random Forest Regressor(随机森林回归)
Adaboost Regressor(Adaboost 回归)
Gradient Boosting Random Forest Regressor(梯度增强随机森林回归)
bagging Regressor(bagging 回归)
ExtraTree Regressor(ExtraTree 回归)
 

二、数据预处理

数据预处理是实验建模前很关键的一个环节,他决定了后面我们模型的一个质量和预测精度。在进行数据预处理前,在网上搜索了很多关于数据预处理的资料,了解了数据预处理的定义、数据预处理的整个流程以及各个流程对应的多种方法。然后根据数据预处理的整个流程来一步步对我的实验进行数据预处理。

 数据预处理流程

首先,调用csv模块对实验的训练集、测试集进行读取并且打印,来验证是否对训练集和测试集读取成功。

然后,对读取成功的训练集、测试集进行特征与标签的一个划分,接着分别打印这两个数据集划分后的标签和特征来验证是否对这两个数据集划分成功。

之后,观察了训练集和测试集的特征和标签,来检验数据是否存在缺失、异常、重复。发现数据不存在以上情况,就不对数据进行清洗。

最后,为了方便后序的一个计算,对模型进行了标准化。这里的标准化,调用的是机器学习数据预处理的StandardScaler库,标准化其实就是将数据变换为均值为0,标准差为1的分布,并不一定是服从正态分布的。

三、特征选择

同样的,特征选择也是特征工程中很重要的环节。特征选择可以减小训练样本的规模,加快训练速度,同时也可以去除一些无用或者冗余的特征,减小模型的复杂度。同时大作业的要求也是需要筛选3到20个波数来对蛋白质进行预测。在对训练集进行特征选择之前,也相应的搜集了关于特征选择的资料,其中特种选择包括了三种方法:过滤法、包裹法、嵌入法。

3.1 过滤法

过滤法:选择特征时不会考虑使用的模型,只是基于特征的通用表现去选择。所以对于后续使用任何一种模型都是一样的效果,并没有带来很大的帮助,减弱了模型拟合的能力。在机器学习实验中,一开始进行特征选择是调用了selectKbest库,这是过滤法下卡方检验的库,selectKbest是选出与蛋白质含量最相关的特征,但是最后拟合出来的效果并不是很好。

3.2 包裹法

包裹法:是将模型的性能作为选择特征的评价标准,是给模型选择最合适的特征。比过滤法更有针对性,对模型性能更好。在机器学习实验中,使用了包裹法下的基于特征权重的RFE算法特征递归消除法),RFE是使用一个基模型进行多轮训练,每轮训练后,消除若干低权值(例特征权重系数或者特征重要性)的特征,再基于新的特征集进行下一轮训练。RFE使用时,要提前限定最后选择的特征数(n_features_to_select)。同时使用了线性回归模型作为学习器,来筛选特征。

3.3 嵌入法

嵌入法:嵌入法是一种让算法自己决定使用哪些特征的方法,即特征选择和算法训练同时进行。在使用嵌入法时,我们先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据权值系数从大到小选择特征。

四、实验设计

有了前面运行环境、数据预处理、特征选择的铺垫,就开始进行我们模型的设计。本实验采用的是SVR支持向量回归),是SVM支持向量机中用于回归问题的模型。

4.1 SVR介绍

众所周知,SVR是用于解决分类问题的,而SVR是用于解决函数逼近问题,就是真实值与预测值之间的误差最小。在线性回归求解回归问题中,是使预测数据拟合回归线,最小化偏差。采用的是最小二乘法,来确定参数w和b,使得误差最小。而SVR模型是在回归线周围设置了一个阈值ε,ε内的所有数据点都不会因其误差而受到惩罚。对于实验中的大规模的训练集,我们的SVR模型也运用了核技巧将输入空间的x通过映射函数ϕ(x)映射到更高维度的特征空间。本实验对比了三个常用核函数:RBF(高斯径向核函数)、Linear(线性核函数)、Poly(多项式核函数),这三个核函数都有C(惩罚系数),我一开始定了1000(1e3),然后对比了100,再对100以下、1000以上、100到1000进行比较,发现100到1000内的惩罚系数拟合出来的效果比较好。

4.2 划分数据集

在对数据拟合前,本实验将训练集按照0.2的比例划分出验证集,通过上述核函数分别对验证集进行拟合,发现Linear和Poly拟合出来的效果较好,一般情况来讲RBF不会比Linear差,可能是调参的问题。所以,参考了吴恩达对于核函数的一个选择:

A.特征维数很高,往往线性可分(SVM解决非线性分类问题的思路就是将样本映射到更高维的特征空间中),可以采用LR或者线性核的SVM;

B.特征维度较小,如果样本数量很多,由于求解最优化问题的时候,目标函数涉及两两样本计算内积,使用高斯核明显计算量会大于线性核,所以手动添加一些特征,使得线性可分,然后可以用LR或者线性核的SVM;

C.不满足上述两点,即特征维数少,样本数量正常,使用高斯核的SVM。”

最后绘图观察真实值和预测值之间拟合程度,通过R2系数和MSE对模型进行评估。

一开始,没有选对特征选择的方法时,我就去查阅文献相对模型进行优化,参考了文献[1],看到用遗传算法对模型、参数进行优化,于是就想去学习一下遗传算法,但是后来上机器学习课,老师介绍了特征选择的方法时,我有打算重新把每个去试试,发现很大的问题是出现在了特征选择上面。

第五章 实验结果与分析

针对刚才实验设计中将训练集划分出验证集,对验证集进行拟合的效果,用的是Matplotlib来绘图展示拟合的效果,用R2系数(决定系数)和均方差对回归模型进行评估。

绘图时,x轴表示样本数,因为拟合的是验证集,按照0.2的比例分出来的验证集是56个,所以x轴的范围是0到60,y轴表示的是预测的蛋白质含量,观察预测的值,在7到9之间,就将y轴的范围定为5-10。

1)图1-1为真实值和预测值拟合的程度表现。其中y_test3为划分出来的验证集的真实值,y_lin是SVR使用线性核函数对训练集进行预测的预测值。

图1-1

得到的r2系数(决定系数)为0.7512824533020599。决定系数反映了因变量y中有多少可由自变量x来解释,所以模型拟合程度越高,自变量对因变量的解释更高,所占百分比就越大。(决定系数范围在0到1之间)。

得到的RMSE(均方差根误差)为0.32763483347905054。均方差反映了预测数据的变化程度,均方差的值越小,说明预测模型描述实验数据具有更好的精确度。

2)图1-2,y_test3为划分出来的验证集的真实值,y_rbf是SVR使用高斯核函数对训练集进行预测的预测值。

图1-2

得到的r2系数(决定系数)为0.9127537462497639。决定系数反映了因变量y中有多少可由自变量x来解释,所以模型拟合程度越高,自变量对因变量的解释更高,所占百分比就越大。(决定系数范围在0到1之间)。

得到的RMSE(均方根差)为0.1959218551642374。均方差反映了预测数据的变化程度,均方差的值越小,说明预测模型描述实验数据具有更好的精确度。

3)图1-3,y_test3为划分出来的验证集的真实值,y_poly是SVR使用多项式核函数对训练集进行预测的预测值。

图1-3

得到的r2系数(决定系数)为0.6153385965530624。决定系数反映了因变量y中有多少可由自变量x来解释,所以模型拟合程度越高,自变量对因变量的解释更高,所占百分比就越大。(决定系数范围在0到1之间)。

得到的RMSE(均方根误差)为0.4113853258903492。均方差反映了预测数据的变化程度,均方差的值越小,说明预测模型描述实验数据具有更好的精确度。

六、实验代码

# Numerical Computing
import numpy as np
# Numerical Analysis
import pandas as pd
# Visualization
import csv
import matplotlib.pyplot as plt
# 导入数据集,并查看数据集
import os
data1=u"E:\\Maching Learning\\train.csv"
data2=u"E:\\Maching Learning\\test-nolabel.csv"
train=pd.read_csv(data1)
test=pd.read_csv(data2)
# print(train)
# print(test)
x_train=train.iloc[:,2:].values
y_train=train.iloc[:,1].values
x2=test.iloc[:,1:].values
print(y_train)
print(x_train)
print(x2.shape)
# 特征工程
# # 对数据归一化
from sklearn.preprocessing import StandardScaler
scaler=StandardScaler()
x_train=scaler.fit_transform(x_train)
x3=scaler.fit_transform(x2)
print(x_train)
print(x3.shape)
# # 第一种:用selectKbest算法进行筛选特征
# from sklearn.feature_selection import SelectKBest
# from sklearn.feature_selection import mutual_info_regression
# # 对于SelectKBest的两个参数的详解
# # 1、score_func : callable,函数取两个数组X和y,返回一对数组(scores, pvalues)或一个分数的数组。默认函数为f_classif,默认函数只适用于分类函数。
# # 这里选择的f_regression,用于回归任务的。
# # 2、k:int or “all”, optional, default=10。所选择的topK个特征。“all”选项则绕过选择,用于参数搜索。这里我们选了20个波数

# skb=SelectKBest(mutual_info_regression,k=16)
# x1=skb.fit(x_train,y_train)
# x_train2=x1.transform(x_train)
# x_test=x1.transform(x2)
# print(x_train2.shape)
# print(x_test.shape)


# # 按重要性排序,选出最重要的 k 个
# scores=skb.scores_
# indices = np.argsort(scores)[::-1]
# k_best_list=[]
# for i in range(0,16):
#     x_train=pd.DataFrame(x_train)
#     k_best_features = x_train.columns[indices[i]]
#     k_best_list.append(k_best_features)
# print('k best features are: ',k_best_list)

# 用SVR对训练集数据进行回归预测
# 选择SVR的常用核函数进行模型分析,rbf(高斯核函数),linear(线性核函数),poly(polynomial kernel多项式核函数)
from sklearn.svm import SVR

# 第二种用rfe来进行特征筛选
from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
lr=LinearRegression()
selector=RFE(estimator=lr, step=1,n_features_to_select=20)
rfe=selector.fit(x_train,y_train)
x_train2=rfe.transform(x_train)
x_test=rfe.transform(x3)
print(x_test.shape)


# # 在对测试集进行预测前,先从选出的训练样本中分出验证集,对模型进行预测
# from sklearn import model_selection
# x_train3, x_test3, y_train3, y_test3 = model_selection.train_test_split(x_train2, y_train, test_size=0.2, random_state=42)


# 对svr模型的三个模型依次跑了一下,最后选择了linear核函数
# rbf高斯核函数
# svr_rbf = SVR(kernel = 'rbf',C=1e3,gamma=0.1)
# linear线性核函数,对惩罚系数一开始选择了1000和100比较,再对1000以上,100以下,100~1000进行比较,发现100到1000比较好,最后选择了300
svr_lin = SVR(kernel = 'linear',C=300)
# polynomial kernel多项式核函数
# svr_poly = SVR(kernel = 'poly',C=1e3,degree=3)
# y_rbf=svr_rbf.fit(x_train2,y_train).predict(x_test)
y_lin=svr_lin.fit(x_train2,y_train).predict(x_test)
# y_poly=svr_poly.fit(x_train2,y_train).predict(x_test)
print(y_lin)
# 生成csv文件
submission=pd.DataFrame({'protein':y_lin})
submission.to_csv('submission.csv',index=False)

# # 对验证集预测结果通过绘图的方式以及r2系数的形式来查看拟合的效果
# from sklearn.metrics import r2_score,mean_squared_error
# from math import sqrt
# # 绘图展示预测值与真实值之间的拟合
# plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
# plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# plt.plot(y_lin,color="r",label="y_lin") #颜色表示
# plt.plot(y_test3,color=(0,0,0),label="y_test3")
# plt.xlabel("样本数") #x轴命名表示
# plt.ylabel("蛋白质含量") #y轴命名表示
# plt.axis([0,60,5,10])#设定x轴 y轴的范围
# plt.title("实际值与预测值折线图")
# plt.legend()#增加图例
# plt.show() #显示图片
# print(r2_score(y_test3,y_lin))
# print(sqrt(mean_squared_error(y_test3,y_lin)))
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值