随机森林部分练习

用随机森林填补缺失值——以泰坦尼克号数据为案例,对比不同类型的填补缺失值对于模型拟合效果的影响

# 导入相关的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import cross_val_score # 交叉验证
from sklearn.ensemble import RandomForestClassifier

path = r'E:\菜菜机器学习\data&code\01 决策树数据及代码\data.csv' 
# 前面加上r表示转义字符,否则无法读取数据
data = pd.read_csv(path)


type(data) # 查看数据是数组还是表格,以此方便粗略查看数据
>>pandas.core.frame.DataFrame


data.info() # 初步发现,可以对年龄进行填补缺失值处理;一种方式为均值填补,一种方式为回归填补

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
 #   Column       Non-Null Count  Dtype  
---  ------       --------------  -----  
 0   PassengerId  891 non-null    int64  
 1   Survived     891 non-null    int64  
 2   Pclass       891 non-null    int64  
 3   Name         891 non-null    object 
 4   Sex          891 non-null    object 
 5   Age          714 non-null    float64
 6   SibSp        891 non-null    int64  
 7   Parch        891 non-null    int64  
 8   Ticket       891 non-null    object 
 9   Fare         891 non-null    float64
 10  Cabin        204 non-null    object 
 11  Embarked     889 non-null    object 
dtypes: float64(2), int64(5), object(5)

data.head() # 查看数据前几行的数据




# 数据预处理部分

# 首先删除无关变量和缺失值过多的变量
data.drop(labels = ['PassengerId','Name','Ticket', 'Cabin'], axis = 1, inplace = True)

首先运用均值对年龄这一行的缺失值进行填补,并用决策树分类,用交叉验证检查模型精度

# 对年龄这个特征变量进行填补
# 因为要进行对比,所以在填补过程中,创建出一个新的矩阵,避免影响到原矩阵
data_copy1 = data.copy()
data_copy1.info() # 查看数据信息


# 首先用均值填补年龄列;年龄适合用均值填补
data_copy1.loc[:,'Age'] = data_copy1.loc[:,'Age'].fillna(data_copy1.loc[:,'Age'].mean())
data_copy1.info() # 查看数据检查是否填补完成


data_copy1.dropna(how = 'any', axis = 0, inplace = True) # 对Embarked列的缺失值进行处理
data_copy1.info() # 查看数据检查是否处理完成

# 对object类型数据进行转化分类
data_copy1.loc[:,'Sex'].unique(),data_copy1.loc[:,'Embarked'].unique() 
# 采用replace的方式进行变化,unique()能够去重处理

>>(array([1, 0], dtype=int64), array([1, 2, 3], dtype=int64))

sex_dic = {'male':1, 'female':0} # 建立replace的字典
embarked_dic = {'S':1,'C':2,'Q':3}


data_copy1.loc[:,'Sex'].replace(sex_dic, inplace = True) # 对object对象编码
data_copy1.loc[:,'Embarked'].replace(embarked_dic, inplace = True)

data_copy1.head() # 查看数据是否编码完成


# 数据预处理完成,划分数据集
target_bymean = data_copy1.loc[:, data_copy1.columns == 'Survived']
feature_bymean = data_copy1.loc[:, data_copy1.columns != 'Survived']


'''
交叉验证查看结果
'''
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(random_state = 0, max_depth = 5)

score = cross_val_score(clf,feature_bymean, target_bymean, cv = 10).mean()
score
>>0.8031920326864148





下面使用随机森林填补缺失值,然后再用分类树进行预测对比,看精确度是否比0.8389高
 

data_copy2 = data.copy() # 复制新的数据,避免影响到原数据
data_copy2.info()


# 运用随机森林填补缺失值时,需要将填补的那一列中,没有缺失值的和有缺失值的分别抽取出来
'''
遇到一个问题:对于Embarked这个特征,有两个缺失值应该如何处理?——做法上为:对原数据复制出一份新的出来,在新的表格数据中用0或者其他数值填补缺失值,再对目标缺失值进行预测,最后将预测得到的结果返回到原数据中
'''


# 本题中,Embarked类型的数据是一个定性类型的数据,可以用众数进行填补
from sklearn.impute import SimpleImputer # 导入填补的包

embarked_ = data_copy2.loc[:, 'Embarked'].values.reshape(-1,1) # 提取出embarked的值,形成数组,并升维
type(embarked_) # 是数组类型
embarked_[:10], embarked_mode.shape # 查看数据

'''
(array([['S'],
        ['C'],
        ['S'],
        ['S'],
        ['S'],
        ['Q'],
        ['S'],
        ['S'],
        ['S'],
        ['C']], dtype=object),
 (891, 1))


'''
embarked_mode = SimpleImputer(strategy = 'most_frequent').fit_transform(embarked_) # 采用众数填补
'''
这儿经常有一个理解误区:进行填补的时候,是否需要将缺失值先提取出来,,等计算得到众数或者均值之后,再对缺失值进行填补
——其实是不用的,SimpleImputer能够对整体的数据进行处理
——在embarked_ 这个数据中,缺失值为:[nan],而其他的数据则为['C'],二者是有着区别的
'''


type(embarked_mode) # 查看数据类型
>>numpy.ndarray

data_copy2.loc[:, 'Embarked'] = embarked_mode # 将填补好以后的值赋值回数据
data_copy2.info() # 检查是否填补完成


sex_dic = {'male':1, 'female':0} # 建立replace时使用的编码字典
embarked_dic = {'S':1,'C':2,'Q':3}

data_copy2.loc[:, 'Sex'].replace(sex_dic, inplace = True)
data_copy2.loc[:, 'Embarked'].replace(embarked_dic, inplace = True)

# 相比于特征编码而言,这种编码方式的缺点体现在,效率比较低,只能一个一个变化,而且需要先创建字典,然后再replace


data_copy2.head()



data_copy2.loc[:, 'Age'].isnull() # 筛选缺失值的方法,可以作为条件,此时返回结果为bool型数据
cond_train = data_copy2.loc[:, 'Age'].notnull() # age列为非空值
cond_test = data_copy2.loc[:, 'Age'].isnull() # age列为空值


# 行筛选条件为:Age列非空,列筛选为:除Age列之外的特征
xtrain = data_copy2.loc[cond_train, data_copy2.columns != 'Age'] 

# 行筛选条件为:Age列非空,列筛选为:Age列
ytrain = data_copy2.loc[cond_train, data_copy2.columns == 'Age'] 


# 行筛选条件为:Age列空值,列筛选为:除Age列之外的特征
xtest = data_copy2.loc[cond_test, data_copy2.columns != 'Age']

type(xtrain),xtrain.shape # 714个数据,说明行筛选是正确的
>>(pandas.core.frame.DataFrame, (714, 7))

xtrain.head() # 没有age列


	Survived	Pclass	Sex	SibSp	Parch	Fare	Embarked
0	0	3	1	1	0	7.2500	1
1	1	1	0	1	0	71.2833	2
2	1	3	0	0	0	7.9250	1
3	1	1	0	1	0	53.1000	1
4	0	3	1	0	0	8.0500	1

xtest.head()
    Survived	Pclass	Sex	SibSp	Parch	Fare	Embarked
5	0	3	1	0	0	8.4583	3
17	1	2	1	0	0	13.0000	1
19	1	3	0	0	0	7.2250	2
26	0	3	1	0	0	7.2250	2
28	1	3	0	0	0	7.8792	3

type(ytrain), ytrain.shape # 检查数据是否有问题
>>(pandas.core.frame.DataFrame, (714, 1))


# 准备工作结束,运用随机森林填补缺失值
from sklearn.ensemble import RandomForestRegressor

rfc = RandomForestRegressor(random_state = 0, n_estimators = 50)
rfc = rfc.fit(xtrain, ytrain)
age_pre = rfc.predict(xtest) # 得到年龄的预测值


type(age_pre), age_pre.shape # 查看数据类型和 维度;177个数据是无误的
>>(numpy.ndarray, (177,))

# 重新赋值回原数据中进行填补
data_copy2.loc[cond_test, data_copy2.columns == 'Age'] = age_pre

data_copy2.info() # 检查数据是否填补完毕

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 8 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   Survived  891 non-null    int64  
 1   Pclass    891 non-null    int64  
 2   Sex       891 non-null    int64  
 3   Age       891 non-null    float64
 4   SibSp     891 non-null    int64  
 5   Parch     891 non-null    int64  
 6   Fare      891 non-null    float64
 7   Embarked  891 non-null    int64  
dtypes: float64(2), int64(6)




# 用决策树进行分类预测,查看拟合效果如何 用交叉验证检验结果

feature_rfc = data_copy2.iloc[:, 1:] # 选择rfc填补的特征
target_rfc = data_copy2.iloc[:, 0] # 选择rfc填补的Survived标签



type(feature_rfc), feature_rfc.shape
>>(pandas.core.frame.DataFrame, (891, 7))


clf = DecisionTreeClassifier(random_state = 0, max_depth = 5)

score = cross_val_score(clf,feature_rfc, target_rfc, cv = 10).mean()
score # 相比之前提高了 2 %
>>0.8227715355805245





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值