``写在前面:因工作需要最近学习sklearn中的非线性回归预测,虽然目前已经有较多的相关指导文献,但在具体实现中仍遇到了不少问题,特开此专题记录学习过程。
因还在学习过程中,很多地方都只是不全面的见解,若有错误后续会进行更正。
数据预处理步骤
主要参考资料
遇到的问题
归一化
归一化 是 缩放单个样本以具有单位范数 的过程。如果你计划使用二次形式(如点积或任何其他核函数)来量化任何样本间的相似度,则此过程将非常有用。
sklearn中文文档中的归一化应该是指对数据的正则化。
标准化
数据集的 标准化 对scikit-learn中实现的大多数机器学习算法来说是 常见的要求 。如果个别特征或多或少看起来不是很像标准正态分布(具有零均值和单位方差),那么它们的表现力可能会较差。
在实际情况中,我们经常忽略特征的分布形状,直接经过去均值来对某个特征进行中心化,再通过除以非常量特征(non-constant features)的标准差进行缩放。
例如,在机器学习算法的目标函数(例如SVM的RBF内核或线性模型的l1和l2正则化),许多学习算法中目标函数的基础都是假设所有的特征都是零均值并且具有同一阶数上的方差。如果某个特征的方差比其他特征大几个数量级,那么它就会在学习算法中占据主导位置,导致学习器并不能像我们说期望的那样,从其他特征中学习。
上述解释从sklearn文档中摘录而来,但通过查阅其他资料发现,标准化和归一化的解释并不相同。
较为认同的解释1
较为认同的解释2
较为认同的解释3
此处的标准化是指采用Minmax标准化方法将特征缩放至指定范围(0,1)。使用这种缩放的目的包括实现特征极小方差的鲁棒性以及在稀疏矩阵中保留零元素。
minmax标准化调用方法
min_max_scaler = preprocessing.MinMaxScaler() # 将缩放器保存,这样方便后面进行标准化还原
std_data = min_max_scaler.fit_transform(ori_data) # 标准化
ori_data = min_max_scaler.inverse_transform(std_data) # 标准化还原
通过采用最大最小标准化处理后,能够将数据的不同特征都缩放到(0,1),能够避免因为不同特征的取值大小的差异导致到模型训练的影响。
标准化时是否需要对y也进行标准化
并未查询到相应的资料。
但从标准化的目的考虑,标准化是为了降低特征间的差异,而与预测值无关,因此进行标准化应该是可以不对因变量(标签)进行的。
正则化的作用与实现方法
正则化作用
归一化和标准化的最大区别在于: 标准化是基于特征的,是对一个特征的所有数据进行处理;而归一化是居于数据点的,是对于每个数据点(sample)做处理使 他们的范数等于 1。(这里的归一化应该就是对数据的正则化)
参考1
因此针对本项目的数据好像没有必要进行正则化?
CSDN粘贴代码方法
注意不能直接从spyder中将代码复制过来,否则会出现卡死,可以先将代码复制到word,再从word粘贴过来即可。
采用这个方法还是不行,粘贴而来的代码会出先如下代码所示,自动添加的很多空行,而且缩进也不对。尚未找到解决办法。
实现代码与注解
代码说明
该代码是用于对非线性回归的数据的预处理。特征有三个,分别为vs, vw,Fn, 预测值为h
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 17 17:32:30 2020
@author: 85845
原始数据处理与可视化,主要包括:
1. 数据的导入
2. 数据的标准化处理
3. 数据的归一化处理
4. 数据的划分
"""
print(__doc__)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import
train_test_split
from sklearn import preprocessing
# 导入txt原始数据
ori_data = np.loadtxt('Total_Data.txt')
# 为数据添加索引
index =
np.reshape(np.arange(len(ori_data))+1,(len(ori_data),1))
index_data = np.concatenate((index,
ori_data),axis=1) #沿着列拼接数组index和ori_data
#
=============================================================================
# 原始数据可视化
def plotOri_data():
plt.figure(num = 'Original Data', figsize = (16,8), edgecolor = 'k', frameon
= True)
p1 = plt.plot(index_data[:,0], index_data[:,4],'-o', color = 'b',
label = 'Original Data',
linewidth = 2)
#设置图例并且设置图例的字体及大小
font1 = {'family':'Time New Roman', 'weight':'normal', 'size':23}
legend = plt.legend(handles=p1, prop=font1)
#设置横纵坐标的名称以及对应字体格式
font2 = {'family' : 'Times New Roman','weight' : 'normal','size' : 23}
plt.xlabel('Number', font2)
plt.ylabel('Material removal depth (μm)', font2)
#设置坐标刻度值的大小
plt.tick_params(labelsize=23)
#
=============================================================================
# 数据标准化处理(线性标准化,不对y进行标准化)
std_data = np.empty([175,5]) # 创建以一个空的数组,注意不是列表
std_data[:,0], std_data[:,4] =
index_data[:,0], index_data[:,4]
min_max_scaler =
preprocessing.MinMaxScaler()
std_data[:,1:4] =
min_max_scaler.fit_transform(ori_data[:,0:3])
#
https://blog.csdn.net/FrankieHello/article/details/79659111
# =============================================================================
# 数据归一化处理(正则化)
nor_data = np.empty([175,5])
# 注意若使用nor_data = ori_data,则会导致nor_data改变ori_data也发生相应的变化,因为是指针传递?
nor_data[:,0] = index[:,0]
nor_data[:,1:4] =
preprocessing.normalize(ori_data[:,0:3], norm = 'l2')
#
=============================================================================
# 数据打乱与划分
def shuffledata(datetype='ori',
test_size=0.3):
'''指定进行数据打乱与划分的原始数据集
ori:原始数据
std:标准化后的数据
nor:归一化后的数据
'''
if datetype =='ori':
X_train, X_test, y_train, y_test = train_test_split(
index_data[:,:4],index_data[:,4],test_size = test_size, random_state =
42)
elif datetype =='std':
X_train, X_test, y_train, y_test =
train_test_split(
std_data[:,:4],std_data[:,4],test_size = test_size, random_state = 42)
elif datetype =='nor':
X_train, X_test, y_train, y_test = train_test_split(
nor_data[:,:4],nor_data[:,4],test_size = test_size, random_state = 42)
index_train, X_train = X_train[:,0], X_train[:,1:4]
index_test, X_test = X_test[:,0], X_test[:,1:4]
return X_train, X_test, y_train, y_test, index_train, index_test