機器學習實戰_1_01_數據清洗、隨機森林模型訓練


 內容簡介:

  利用隨機森林方法訓練數據集,預測泰坦尼克號哪些人可以獲救,主要過程如下:

step1:加載源數據集

step2: 數據清洗

step3:進行特征構建

step4:特征構建(2)基於scikit-learn中的LabelEncoder()

step5:特征選擇

step6:獲取訓練集和測試集

step7:隨機森林算法實現

代碼在jupyter notebook中 實現。

本節學習內容來自:https://space.bilibili.com/474347248/channel/detail?cid=143235,所用數據均來源於該網站。

#加載必要的庫
import sys
import pandas as pd
import numpy as np
import sklearn  #機器學習庫
import random
import time
print(sys.version)  #查看python 版本
3.8.3 (default, Jul  2 2020, 17:28:51) [MSC v.1916 32 bit (Intel)]
from sklearn import ensemble

from sklearn.preprocessing import LabelEncoder
from sklearn import feature_selection
from sklearn import model_selection
from sklearn import metrics

import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns  #基於matplotlib 開發的庫
#在jupyter notebook 中顯示畫的圖
%matplotlib inline  
mpl.style.use("ggplot")  # 設置matplotlib 的繪圖風格

step1:加載源數據集

data_raw = pd.read_csv("train.csv")
data_val = pd.read_csv("test.csv")
#顯示部分數據
data_raw.head()  #默認讀取前5行;可以加參數:data_raw.head(3)   讀取前三行

 

 

 

data_val.head() 

#查看表的信息
data_raw.info()

 

 

 

#列名稱轉換為小寫格式
data_raw.columns = data_raw.columns.str.lower()
data_val.columns = data_val.columns.str.lower()
data_raw.head()

 

 

 

#繪制圖形
sns.countplot(data_raw["survived"])

# 合並兩個數據集,進行統一的清洗
data_all = [data_raw, data_val]

step2: 數據清洗

#查看一下每一列有多少空值
data_raw.isnull().sum()

 

 

 

data_val.isnull().sum()

 

 

 

#對源數據進行描述
data_raw.describe(include='all')

 

 

 

# 對原始數據集(訓練集和驗證集)進行清理
for dataset in data_all:
    #補足空缺值
    dataset['age'].fillna(dataset['age'].median(), inplace=True)  #inplace=True:在原表中補齊,為False則會生成一個新表返回
    dataset['fare'].fillna(dataset['fare'].median(), inplace=True)
    dataset['embarked'].fillna(dataset['embarked'].mode()[0], inplace=True) #mode()返回的出現次數最多的幾個字符串,然后[0]代表取第一個
    #dataset['embarked'].fillna(dataset['embarked'].median(), inplace=True)  這里要注意港口是字符串類型,沒有中值,不能這樣寫
    
#刪除一些字段(cabin 空缺太多,對數據分析沒有太大的意義
drop_columns = ["cabin","passengerid","ticket"]
data_raw.drop(drop_columns, axis = 1, inplace = True)  #asxis = 1代表整列刪除   inplace = True代表在原始數據上操作
data_val.drop(drop_columns, axis = 1, inplace = True)
data_raw.isnull().sum()

 

 

 

data_raw.info()

 

 

 

data_val.isnull().sum()

 

 

 

step3:進行特征構建

for dataset in data_all:
    #1)構建新的字段:family_size 家庭規模 (sibsp和parch相加)
    dataset["family_size" ] = dataset['sibsp'] + dataset['parch'] + 1 #1表示加自己
    
    #2)構建新的字段:single  單身,  1:單身;   0:非單身
    dataset['single'] = 1 #初始化為1
    dataset['single'].loc[dataset['family_size']>1] = 0      #loc[]表格的每一行,判斷家庭規模大於1的為非單身
    
    #3)構建新的字段:身份 title  ,從name字段   ;Braund, Mr. Owen Harris  :以逗號,點號分割
    dataset['title'] = dataset['name'].str.split(', ', expand = True)[1]  #pandas中split默認expand = False返回的是series,expand = True返回dataframe;分割之后拿到第一個字段,也就是上一行的逗號后面的;
    dataset['title'] = dataset['title'].str.split('.', expand = True)[0]  #拿到點號之前的,也就是上面兩行的Mr,  這一行可以和上面一行合並為一行
    #dataset['title'] = dataset['name'].str.split(', ', expand = True)[1].str.split('.', expand = True)[0]
    #上面這一行代碼可以用apply代替
    #dataset['title'] = dataset['name'].apply(lambda x : x.split(',')[1]).apply(lambda x : x.split('.')[0])
    
    #4)構建新的字段:票價 fare_bin  ,從fare字段,(因為票價大小差距太多,可以分組)
    dataset['fare_bin'] = pd.qcut(dataset['fare'], 4)  #根據票價,分成四組,每一組個數相等
    #cut():分組,每一組個數不一定相等,qcut():分組,每一組個數相等
    
    #data_raw['age'].tolist()  #把age這一列拿出來
    
    #5)構建新的字段:age_bin 
    dataset['age_bin'] = pd.cut(dataset['age'].astype(int), 5)   #根據年齡分組。分成5組(每組的元素不一致)
dataset.head()

 

 

#根據不同的title 統計人數
data_raw['title'].value_counts()

 

 

#判斷人數少於10人的再歸為一類
title_names = (data_raw['title'].value_counts()<10)
title_names

 

 

#判斷人數少於10人的再歸為一類:other
data_raw['title'] = data_raw['title'].apply(lambda x : 'other' if title_names[x] else x)  #title_names[x]為TRUE的歸為other,為FALSE的保持不動
data_raw['title'].value_counts()

 

 

data_raw['survived'].groupby(data_raw['title']).mean()  #不同的title 被獲救的概率

 

 

step4:特征構建(2)基於scikit-learn中的LabelEncoder()

data_raw.head()

 

 #像上面embarked等字段是字母,不適合數據分析

label = LabelEncoder()
for dataset in data_all:
    #1)新字段:sex_code
    dataset['sex_code'] = label.fit_transform(dataset['sex']) #male female  重新編碼為0 和1 
    
    #2)新字段:embarked_code
    dataset['embarked_code'] = label.fit_transform(dataset['embarked'])
    
    #3)新字段:title_code
    dataset['title_code'] = label.fit_transform(dataset['title'])
    
    #上面年齡和票價進行了分組,我們也要重新編碼
    #4)新字段:age_bin_code
    dataset['age_bin_code'] = label.fit_transform(dataset['age_bin'])
    
    #5)新字段:fare_bin_code
    dataset['fare_bin_code'] = label.fit_transform(dataset['fare_bin'])
    
data_raw.head()

 

 

#查看所有列的字段
data_raw.columns.tolist()

 

 ###以上字段並不是都適合作為訓練的字段,我們要選擇合適的字段進行訓練

step5:特征選擇

並不是所有的字段都有訓練的意義,我們通常會選擇一些字段進行訓練

方式1:

Target = ['survived']  #定義標簽
data_columns_one = ['sex', 'pclass', 'embarked', 'title', 'sibsp', 'parch', 'age', 'fare', 'family_size', 'single']  #選擇要訓練的字段
columns_one = Target + data_columns_one

 

方式2:

data_columns_two = ['sex_code', 'pclass', 'embarked_code', 'title_code', 'sibsp', 'parch', 'age', 'fare']  #選擇要訓練的字段
columns_two = Target + data_columns_two

 

方式3:

data_columns_three = ['sex_code', 'pclass', 'embarked_code', 'title_code', 'family_size',  'age_bin_code', 'fare_bin_code']  #選擇要訓練的字段
columns_three = Target + data_columns_three
#通過pandas 中的get_dummies()進行編碼(功能類似於LabelEncoder())
data_one_dummy = pd.get_dummies(data_raw[data_columns_one])
data_one_dummy_list = data_one_dummy.columns.tolist()  #以列表形式查看編碼后的字段
data_one_dummy_list

 

 

 

 

step6:獲取訓練集和測試集

對應上面的三種方式

方式1:

x_train_one, x_test_one, y_train_one, y_test_one = model_selection.train_test_split(data_one_dummy[data_one_dummy_list], 
data_raw[Target],
random_state = 0)

# random_state = 0保證每次運行的結果是一樣的
x_train_one.shape  #查看一下
x_test_one.shape

 

方式2:

x_train_two, x_test_two, y_train_two, y_test_two = model_selection.train_test_split(data_raw[data_columns_two], 
data_raw[Target],
random_state
= 0) # random_state = 0保證每次運行的結果是一樣的
x_train_two.shape  #查看一下

x_test_two.shape

方式3:

x_train_three, x_test_three, y_train_three, y_test_three = model_selection.train_test_split(data_raw[data_columns_three], 
                                                                                    data_raw[Target], 
                                                                                    random_state = 0) # random_state = 0保證每次運行的結果是一樣的
x_train_three.shape  #查看一下

 

x_test_three.shape 

step7:隨機森林算法實現

 

from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(max_features='auto',
                            random_state=1, 
                            n_jobs=-1) #n_jobs=-1  多線程
param_gird = {
    'criterion' : ['gini', 'entropy'],   #兩個模型
    'min_samples_leaf' : [1, 5, 10],
    'min_samples_split' : [2, 4, 10, 12, 16],
    'n_estimators' : [50, 100, 400, 700, 1000]
}
gs = GridSearchCV(estimator=rf,
                  param_grid=param_gird,
                  scoring= 'accuracy',
                  cv=3,
                  n_jobs=-1)

接下來對三種訓練集進行訓練

方式1:

gs = gs.fit(x_train_one, y_train_one)  # fit 訓練,可能需要一會兒
print(gs.best_score_)  #准確性

 

 

print(gs.best_params_)#查看訓練選擇的參數

#創建一個對象,用上面的參數繼續訓練
rf2 = RandomForestClassifier(criterion='entropy',
                             min_samples_leaf=5,
                             min_samples_split=12,
                             n_estimators=50,
                             n_jobs=-1,
                             random_state=1)
rf2.fit(x_train_one, y_train_one)

 

 

#根據特征根的重要性排序
pd.concat((pd.DataFrame(x_train_one.iloc[:, 1:].columns, columns=['Varialbe']),
          pd.DataFrame(rf2.feature_importances_, columns=['importance'])),
          axis=1 ).sort_values(by='importance', ascending=False)

 

 

預測是否可以獲救,在test數據

pred = rf2.predict(x_test_one)
pred_df = pd.DataFrame(pred, columns=['survived'])
pred_df.head()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM