模型的R2值 0.627060068329868
特征处理后,模型的R2值 0.6272862884031768
模型提升了0.04%
可能有的疑问解答:
OneHotEncoder, MinMaxScaler 操作完以后自动会把pandas对象转化成numpy对象是吗?特征处理前后数据类型不一样对吧?np对象和pandas对象不影响?
有影响,OneHotEncoder, MinMaxScaler 操作完以后自动会把pandas对象转化成numpy对象,pandas对象跟numpy经常转换来转换去的。
scikit-learn要求X是一个特征矩阵,y是一个NumPy向量,pandas构建在NumPy之上。因此,X可以是pandas的DataFrame,y可以是pandas的Series,scikit-learn可以理解这种结构。
只是这个X特征矩阵是numpy.ndarray格式,或者是pandas.core.frame.DataFrame格式,都可以传入进model中去的。
scikit-learn中fit_transform()与transform()到底有什么区别,能不能混用?
fit_transform是fit和transform的组合。
fit(x,y)在新手入门的例子中比较多,但是这里的fit_transform(x)的括号中只有一个参数,这是因为fit(x,y)传两个参数的是有监督学习的算法,fit(x)传一个参数的是无监督学习的算法,比如降维、特征提取、标准化。
为什么出来fit_transform()这个东西?
fit和transform没有任何关系,仅仅是数据处理的两个不同环节,之所以出来这么个函数名,仅仅是为了写代码方便,
所以会发现transform()和fit_transform()的运行结果是一样的。
注意:运行结果一模一样不代表这两个函数可以互相替换,绝对不可以。transform函数是一定可以替换为fit_transform函数的,fit_transform函数不能替换为transform函数!
因为 sklearn里的封装好的各种算法都要fit、然后调用各种API方法,transform只是其中一个API方法,所以当你调用除transform之外的方法,必须要先fit,为了通用的写代码,还是分开写比较好
也就是说,这个fit相对于transform而言是没有任何意义的,但是相对于整个代码而言,fit是为后续的API函数服务的,所以fit_transform不能改写为transform。
fit_transform与transform运行结果一致,但是fit与transform无关,只是数据处理的两个环节,fit是为了程序的后续函数transform的调用而服务的,是个前提条件。
如果把机器学习代码中的fit_transform改为transform,编译器就会报错。
二者的功能都是对数据进行某种统一处理(比如标准化~N(0,1),将数据缩放(映射)到某个固定区间,归一化,正则化等)
fit_transform(partData)对部分数据先拟合fit,找到该part的整体指标,如均值、方差、最大值最小值等等(根据具体转换的目的),然后对该partData进行转换transform,从而实现数据的标准化、归一化等等。。
根据对之前部分fit的整体指标,对剩余的数据(restData)使用同样的均值、方差、最大最小值等指标进行转换transform(restData),从而保证part、rest处理方式相同。
必须先用fit_transform(partData),之后再transform(restData)
如果直接transform(partData),程序会报错
如果fit_transfrom(partData)后,使用fit_transform(restData)而不用transform(restData),虽然也能归一化,但是两个结果不是在同一个“标准”下的,具有明显差异。
使用特征预处理提升糖尿病患病指标预测模型的性能
题目描述:对特征进行预处理,然后预测糖尿病的患病指标,并比较模型的性能
题目要求:
对类别型特征及数值型特征进行预处理
数据文件:
数据源下载地址:https://video.mugglecode.com/diabetes.csv (数据源与之前相同)
diabetes.csv,包含了442个数据样本。
共11列数据
AGE:年龄
SEX: 性别
BMI: 体质指数(Body Mass Index)
BP: 平均血压(Average Blood Pressure)
S1~S6: 一年后的6项疾病级数指标
Y: 一年后患疾病的定量指标,为需要预测的标签
参考代码:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import OneHotEncoder, MinMaxScaler
def LR(X_train, X_test, y_train, y_test):
model = LinearRegression()
model.fit(X_train,y_train)
R2_score = model.score(X_test,y_test)
return R2_score
def attr_proc(X_train, X_test,feat_col_quant,feat_col_quali):
Encoder = OneHotEncoder(sparse= False)
Encoded_X_train_quali = Encoder.fit_transform(X_train[feat_col_quali])
Encoded_X_test_quali = Encoder.transform(X_test[feat_col_quali])
Scaler = MinMaxScaler()
Scaled_X_train_quant = Scaler.fit_transform(X_train[feat_col_quant])
Scaled_X_test_quant = Scaler.transform(X_test[feat_col_quant])
return np.hstack((Encoded_X_train_quali,Scaled_X_train_quant)), np.hstack((Encoded_X_test_quali,Scaled_X_test_quant))
data = pd.read_csv('./data_ai/diabetes.csv')
feat_col_quant = ['AGE','BMI','BP','S1','S2','S3','S4','S5','S6'] #定量量
feat_col_quali = ['SEX'] #定性量
X = data[feat_col_quant + feat_col_quali]
y = data[['Y']] #其实外面多套一层括号,结果还是一样的,不套括号也行,但是对于多列的那种还是要多套括号的
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=1/5,random_state=10)
X_train_proc, X_test_proc = attr_proc(X_train, X_test,feat_col_quant,feat_col_quali)
Non_proc_score = LR(X_train, X_test, y_train, y_test)
Proc_score = LR(X_train_proc, X_test_proc, y_train, y_test)
print(f'处理前R2得分为{Non_proc_score}\n处理后R2得分为{Proc_score}')
print(f'处理后的精确度相比处理前精确度变化了{(Proc_score-Non_proc_score)/Non_proc_score * 100}%')
运行结果: