精华内容
下载资源
问答
  • 近年来,国内的电信诈骗案件呈愈演愈烈之势,本文以某省电信公司简化版本的防诈骗模型案例,利用python机器学习工具,使用随机森林算法,从数据处理、特征工程、到反诈骗模型模型的构建及评估等完整流程进行一个...

    近年来,国内的电信诈骗案件呈愈演愈烈之势,本文以某省电信公司简化版本的防诈骗模型为案例,利用python机器学习工具,使用随机森林算法,从数据处理、特征工程、到反诈骗模型的模型的构建及评估等完整流程进行一个简单的记录和介绍。

    流程图
    在这里插入图片描述

    环境设置、模块加载

    # coding: utf-8
    import os
    import numpy as np
    import pandas as pd
    from sklearn.ensemble import IsolationForest
    from sklearn.model_selection import train_test_split
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.metrics import confusion_matrix
    from sklearn.externals import joblib
    from sklearn import metrics
    from scipy import stats
    import time
    from datetime import datetime
    
    import warnings
    warnings.filterwarnings("ignore")
    
    os.chdir('home//zj//python//python3.6.9//bin//python3')
    

    数据加载

    自定义工作目录,并加载样本数据

    def read_file(filepath): 
        os.chdir(os.path.dirname(filepath))  
        return pd.read_csv(os.path.basename(filepath),encoding='utf-8')
    
    file_pos = "E:\\工作文件\\***\\防诈骗识别\\data_train.csv"
    data_pos = read_file(file_pos)  
    

    特征重命名

    data_pos.columns = ['BIL_ACCS_NBR','ASSET_ROW_ID','CCUST_ROW_ID','LATN_ID','TOTAL_CNT',
    'TOTAL_DURATION','ZJ_CNT','ZJ_TOTAL_DURATION','TOTAL_ROAM_CNT','ZJ_ROAM_CNT','ZJ_LOCAL_CNT','ZJ_ROAM_DURATION','ZJ_LOCAL_DURATION','ZJ_LONG_CNT','BJ_LOCAL_CNT','WORK_TIME_TH_TT_CNT','FREE_TIME_TH_TT_CNT','NIGHT_TIME_TH_TT_CNT','DURATION_TP_1','DURATION_TP_2','DURATION_TP_3','DURATION_TP_4','DURATION_TP_5','DURATION_TP_6','DURATION_TP_7','DURATION_TP_8',
    'DURATION_TP_9','TOTAL_DIS_BJ_NUM','DIS_BJ_NUM','DIS_OPP_HOME_NUM','OPP_HOME_NUM','MSC_NUM','DIS_MSC_NUM','ZJ_AVG_DURATION','TOTAL_ROAM_CNT_RATE','ZJ_DURATION_RATE','ZJ_CNT_RATE','ZJ_ROAM_DURATION_RATE','ZJ_ROAM_CNT_RATE','DURATION_RATIO_0_15','DURATION_RATIO_15_30',
    'DURATION_RATIO_30_45','DURATION_RATIO_45_60','DURATION_RATIO_60_300','DUR_30_CNT_RATE',
    'DUR_60_CNT_RATE','DUR_90_CNT_RATE','DUR_120_CNT_RATE','DUR_180_CNT_RATE','DUR_BIGGER_180_CNT_RATE','DIS_BJ_NUM_RATE','TOTAL_DIS_BJ_NUM_RATE','CALLING_REGION_DISTRI_LEVEL','ACT_DAY','ACT_DAY_RATE','WEEK_DIS_BJ_NUM','YY_WORK_DAY_OIDD_23_NUM','IS_GJMY','ZJ_DURATION_0_15_CNT','ZJ_DURATION_15_30_CNT','ZJ_DURATION_30_60_CNT','ZJ_DURATION_RATIO_0_15','ZJ_DURATION_RATIO_15_30','ZJ_DURATION_RATIO_30_60','H_MAX_CNT','H_MAX_CIRCLE','INNER_MONTH','MIX_CDSC_FLG','CPRD_NAME','AMT','CUST_ASSET_CNT','CUST_TELE_CNT','CUST_C_CNT','ALL_LL_USE',
    'MY_LL_USE','MY_LL_ZB','ALL_LL_DUR','MY_LL_DUR','MY_DUR_ZB','AGE','GENDER','CUST_TYPE_GRADE_NAME','ISP','TERM_PRICE','SALES_CHANNEL_LVL2_NAME','CORP_USER_NAME','TOTOL_7_CNT',
    'TOTOL_7_DUR','TOTOL_7_ZJ_DUR','TOTOL_7_ZJ_CNT','TOTOL_7_ZJ_D_CNT','TOTOL_7_BJ_D_DUR',
    'TOTOL_7_JZGS_CNT','WEEK_CNT','WEEK_DUR','ZB_WS','COUPLE_NUMBER','TIME_COUPLE_NUMBER','ZJ_0912','HB_0912','ZJ_1417','HB_1417','CHG_CELLS','ZHANBI','ETL_DT','IS_HARASS']
    

    数据查看

    数据表行/列

    data_pos.shape
    

    在这里插入图片描述

    可以看出,正样本数据只有3436,负样本较多,属于极度不平衡样本数据

    数据预处理

    无意义字段删除

    data_pos_1 = data_pos.drop([
        'BIL_ACCS_NBR',
        'ASSET_ROW_ID',
        'CCUST_ROW_ID',
        'LATN_ID',
        'CPRD_NAME',
        'ISP',
        'AGE',
        'CUST_TYPE_GRADE_NAME',
        'ETL_DT',
        'WEEK_DIS_BJ_NUM',
        'TOTOL_7_ZJ_D_CNT',
        'TOTOL_7_JZGS_CNT',
        'INNER_MONTH'
    ],axis = 1)
    

    正负样本规模

    data_pos.IS_HARASS.value_counts()
    

    在这里插入图片描述

    TERM_PRICE 进行分箱处理

    
    data_pos_1['TERM_PRICE'] = data_pos_1['TERM_PRICE'].apply(lambda x: np.where(x > 5000, '>5000',
                                                                                 np.where(x>3000, '(3000,5000]',
                                                                                          np.where(x>2000, '(2000,3000]',
                                                                                                   np.where(x>1000, '(1000,2000]',
                                                                                                            np.where(x>0, '(0,1000]', '未识别'))))))
    

    字段填充及转化
    将类别型变量空值及极小规模类别做替换

    data_pos_1.TERM_PRICE.value_counts()
    data_pos_1.MIX_CDSC_FLG.value_counts()
    data_pos_1.CORP_USER_NAME.value_counts()
    data_pos_1.SALES_CHANNEL_LVL2_NAME.value_counts()
    
    #依次处理TERM_PRICE、MIX_CDSC_FLG、CORP_USER_NAME、SALES_CHANNEL_LVL2_NAME
    def CHANGE_SALES_CHANNEL_LVL2_NAME(data):
        if data  in ['社会渠道','实体渠道','电子渠道','直销渠道']:
            return data
        else:
            return '未识别'
            
    data_pos_1['SALES_CHANNEL_LVL2_NAME'] = data_pos_1.SALES_CHANNEL_LVL2_NAME.apply(CHANGE_SALES_CHANNEL_LVL2_NAME)
    

    缺失值处理

    ##缺失值统计
    def na_count(data):
        data_count = data.count()
        na_count = len(data) - data_count
        na_rate = na_count/len(data)
        na_result = pd.concat([data_count,na_count,na_rate],axis = 1)
        return na_result
    
    na_count = na_count(data_pos_1)
    na_count
    

    在这里插入图片描述
    拆分字段
    字段按照连续、类别拆分

    def category_continuous_resolution(data,variable_category):
        for key in list(data.columns):
            if key not in variable_category:
                variable_continuous.append(key)
            else:
                continue
        return variable_continuous
    
    
    #字段按照类型拆分
    variable_category = ['MIX_CDSC_FLG','GENDER','TERM_PRICE','SALES_CHANNEL_LVL2_NAME','CORP_USER_NAME']
    variable_continuous = []
    
    variable_continuous = category_continuous_resolution(data_pos_1,variable_category)
    

    字段类型转化

    def feture_type_change(data,variable_category):
        '''
        字段类型转化
        '''
        for col_key in list(data.columns):
            if col_key in variable_category:
                data[col_key] = data[col_key].astype(eval('object'), copy=False)
            else:
                data[col_key] = data[col_key].astype(eval('float'), copy=False)
        return data
    
    data_pos_2 = feture_type_change(data_pos_1,variable_category)
    

    缺失值填充

    def na_fill(data,col_name_1,col_name_2):
        '''
        缺失值填充
        '''
        for col_key in list(data.columns):
            if col_key in col_name_1:
                data[col_key] = data[col_key].fillna(value = '未识别')
            elif col_key in col_name_2:
                data[col_key] = data[col_key].fillna(data[col_key].mean())
            else:
                data[col_key] = data[col_key].fillna(value = 0)
        return data
    
    #缺失值填充
    col_name_1 = variable_category
    col_name_2 = []
    data_pos_3 = na_fill(data_pos_2,col_name_1,col_name_2)
    

    类别变量one_hot处理

    ##one_hot
    def data_deliver(data,variable_category):
        '''
        ont_hot衍生
        '''
        for col_key in list(data.columns):
            if col_key in variable_category:
                temp_one_hot_code = pd.get_dummies(data[col_key],prefix = col_key)
                data = pd.concat([data,temp_one_hot_code],axis = 1)
                del data[col_key]
            else:
                continue
        return data
    
    data_pos_4 = data_deliver(data_pos_3,variable_category)
    

    特征工程

    相关性分析

    def max_corr_feture_droped(train_data,variable_continuous,k):
        '''
        相关性分析
        '''
        table_col = train_data.columns
        table_col_list = table_col.values.tolist()          
        all_lines = len(train_data)
        train_data_number = train_data[variable_continuous]
        ###连续型变量的处理过程:数据的标准化
        from numpy import array
        from sklearn import preprocessing
        def normalization(data,method,feature_range=(0,1)):
            if method=='MaxMin':
                train_data_scale=data.apply(lambda x: (x - np.min(x)) / (np.max(x) - np.min(x))) 
                return train_data_scale
            if method=='z_score':
                train_data_scale=data.apply(lambda x: (x - np.mean(x)) / (np.std(x))) 
            return train_data_scale
        train_data_scale = normalization(train_data_number,method=scale_method)
        # 输出各个变量之间的相关性报告
        def data_corr_analysis(raw_data, sigmod = k):
            corr_data = raw_data.corr()
            for i in range(len(corr_data)):
                for j in range(len(corr_data)):
                    if j == i:
                        corr_data.iloc[i, j] = 0
            x, y, corr_xishu = [], [], []
            for i in list(corr_data.index):
                for j in list(corr_data.columns):        
                    if abs(corr_data.loc[i, j]) > sigmod: # 保留相关性系数绝对值大于阈值的属性
                        x.append(i)
                        y.append(j)
                        corr_xishu.append(corr_data.loc[i, j])
            z = [[x[i], y[i], corr_xishu[i]] for i in range(len(x))]
            high_corr = pd.DataFrame(z, columns=['VAR1','VAR2','CORR_XISHU'])
            return high_corr
        high_corr_data = data_corr_analysis(train_data_number, sigmod=k)
        def data_corr_choice(data,train_data_scale,high_corr_data):
            high_corr_data_1=[]
            target_var=pd.DataFrame(data.loc[:,target_col])
            for i in range(high_corr_data.shape[0]):
                for  j in range(high_corr_data.shape[1]-1):
                    d1=pd.DataFrame(train_data_scale.loc[:,high_corr_data.iloc[i,j]])
                    data1=pd.concat([d1, data.loc[:,target_col]], axis=1, join='inner')
                    corr_data = data1.corr()
                    high_corr_data_1.append(corr_data.iloc[0,-1]) #输出的为各个变量与目标变量之间的相关关系
            high_corr_data_2=np.array(high_corr_data_1).reshape(high_corr_data.shape[0],high_corr_data.shape[1]-1)
            high_corr_data_2=pd.DataFrame(high_corr_data_2,columns=high_corr_data.columns[:-1])
            del_var_cor=[]
            for  i in range(high_corr_data_2.shape[0]):
                if abs(high_corr_data_2.iloc[i,0])>=abs(high_corr_data_2.iloc[i,1]):
                    del_var_cor.append(high_corr_data.iloc[i,1])
                else:
                    del_var_cor.append(high_corr_data.iloc[i,0]) 
            train_data_number_2.drop(del_var_cor,axis=1,inplace = True) #将强相关的变量直接剔除      
            return  set(high_corr_data_1),set(del_var_cor),train_data_number_2
        train_data_number_2 = pd.concat([train_data[variable_continuous],train_data[target_col]],axis=1)
        high_corr_data_1,del_var_cor,train_data_scale = data_corr_choice(train_data_number_2,train_data_scale,high_corr_data)  
        train_data2 = train_data[:]
        train_data2.drop(set(del_var_cor),axis=1,inplace = True)
        return train_data2,del_var_cor
    
    
    #相关性分析,去除高相关变量
    scale_method = 'MaxMin'
    target_col = 'IS_HARASS'
    data_pos_5,del_var_cor = max_corr_feture_droped(data_pos_4,variable_continuous,k=0.8)
    del_var_cor  #删除的variable查看
    

    特征重要性分析

    def data_sample(data, target_col, smp):
        '''
        数据平衡
        '''
        data_1 = data[data[target_col] == 1].sample(frac=1)
        data_0 = data[data[target_col] == 0].sample(n=len(data_1)*smp)
        # data_1 = data_1.sample(len(data_2)*smp)
        data = pd.concat([data_1, data_0]).reset_index()
        return data
    
    def train_test_spl(data):
        '''
        训练数据、测试数据切分
        '''
        X_train, X_test, y_train, y_test = train_test_split(
            data[ipt_col], data[target_col], test_size=0.2, random_state=42)
        return X_train, X_test, y_train, y_test
    

    定义特征重要性分析函数,并循环遍历获取最佳抽样比例

    def feture_extracted(train_data, alpha):
        '''
        维度重要性判断
        '''
        global ipt_col
        ipt_col= list(train_data.columns)
        ipt_col.remove(target_col)
        sample_present = [1,5]   # 定义抽样比例
        f1_score_list = []
        model_dict = {}
        for i in sample_present:
            try:
                train_data = data_sample(train_data, target_col, smp=i)
            except ValueError:
                break
            X_train, X_test, y_train, y_test = train_test_spl(train_data)   
        # 开始RF选取特征
            model = RandomForestClassifier()
            model = model.fit(X_train, y_train)
            model_pred = model.predict(X_test)
            f1_score = metrics.f1_score(y_test, model_pred)
            f1_score_list.append(f1_score)
            model_dict[i] = model
        max_f1_index = f1_score_list.index(max(f1_score_list))
        print('最优的抽样比例是:1:',sample_present[max_f1_index])
        d = dict(zip(ipt_col, [float('%.3f' %i) for i in model_dict[sample_present[max_f1_index]].feature_importances_]))
        f = zip(d.values(), d.keys())
        importance_df = pd.DataFrame(sorted(f, reverse=True), columns=['importance', 'feture_name'])
        list_imp = np.cumsum(importance_df['importance']).tolist()
        for i, j in enumerate(list_imp):
            if j >= alpha:
                break
        print('大于alpha的特征及重要性如下:\n',importance_df.iloc[0:i+1, :])
        print('其特征如下:')
        feture_selected = importance_df.iloc[0:i+1, 1].tolist()
        print(feture_selected)
        return feture_selected
    
    #重要性检验,选择重要变量
    data_pos_5_feture = feture_extracted(data_pos_5, alpha = 0.9)
    

    在这里插入图片描述

    模型训练

    数据平衡

    data_pos_6 = data_sample(data_pos_5, target_col, smp = 3)
    

    正负样本拆分

    def model_select(data, rf_feture, target_col ,test_size):
        '''
        正负样本拆分
        '''
        X_train, X_test, y_train, y_test = train_test_split(
            data[rf_feture], data[target_col], test_size=test_size, random_state=42)
        return X_train, X_test, y_train, y_test
    
    #拆分比例7:3
    X_train, X_test, y_train, y_test = model_select(data_pos_6,data_pos_5_feture,target_col,test_size=0.3)
    

    定义模型函数

    RF两个主要参数说明:

    • min_samples_split:当对一个内部结点划分时,要求该结点上的最小样本数,默认为2;
    • min_samples_leaf:设置叶子结点上的最小样本数,默认为1。当尝试划分一个结点时,只有划分后其左右分支上的样本个数不小于该参数指定的值时,才考虑将该结点划分,换句话说,当叶子结点上的样本数小于该参数指定的值时,则该叶子节点及其兄弟节点将被剪枝。在样本数据量较大时,可以考虑增大该值,提前结束树的生长。
    def model_train(x_train, y_train, model):
        '''
        算法模型,默认为RF
        '''
        if model == 'RF':
            res_model = RandomForestClassifier(min_samples_split = 50,min_samples_leaf = 50)
            res_model = res_model.fit(x_train, y_train)
            feature_importances = res_model.feature_importances_[1]
        if model == 'LR':
            res_model = LogisticRegression()
            res_model = res_model.fit(x_train, y_train)
            list_feature_importances = [x for x in res_model.coef_[0]]
            list_index = list(x_train.columns)
            feature_importances = pd.DataFrame(list_feature_importances, list_index)
        else:
            pass
        return res_model, feature_importances
    
    
    #训练模型
    rf_model, feature_importances = model_train(X_train, y_train, model='RF')  #也可以选择使用LR
    

    模型验证

    def model_predict(res_model, input_data, alpha ):
        # 模型预测
        # input_data: 输入新的无目标变量的数据
        data_proba = pd.DataFrame(res_model.predict_proba(input_data).round(4))
        data_proba.columns = ['neg', 'pos']
        data_proba['res'] = data_proba['pos'].apply(lambda x: np.where(x >= alpha, 1, 0))  #将>0.5输出为正调整为1
        return data_proba
    
    def model_evaluate(y_true, y_pred):
        y_true = np.array(y_true) 
        y_true.shape = (len(y_true),)
        y_pred = np.array(y_pred) 
        y_pred.shape = (len(y_pred),)
        print(metrics.classification_report(y_true, y_pred))
    
    data_pos_6 = data_sample(data_pos_5, target_col, smp = 50)
    X_train, X_test, y_train, y_test = model_select(data_pos_6,data_pos_5_feture,target_col,test_size=0.5)
    
    
    Precision = []
    Recall = []
    for alpha in np.arange(0, 1, 0.1):
        y_pred_rf = model_predict(rf_model, X_test, alpha = alpha)
        cnf_matrix = confusion_matrix(y_test, y_pred_rf['res'])
        Precision.append((cnf_matrix[1,1]/(cnf_matrix[0,1] + cnf_matrix[1,1])).round(4))
        Recall.append((cnf_matrix[1,1]/(cnf_matrix[1,0] + cnf_matrix[1,1])).round(4))
    
    
    score = pd.DataFrame(np.arange(0, 1, 0.1),columns = ['score'])
    Precision = pd.DataFrame(Precision,columns = ['Precision'])
    Recall = pd.DataFrame(Recall,columns = ['Recall'])
    Precision_Recall_F1 = pd.concat([score, Precision, Recall],axis = 1)
    Precision_Recall_F1['F1'] = (2 * Precision_Recall_F1['Precision'] * Precision_Recall_F1['Recall'] / (Precision_Recall_F1['Precision'] + Precision_Recall_F1['Recall'])).round(2)
    Precision_Recall_F1
    

    在这里插入图片描述

    模型封装保存

    start = datetime.now()
    joblib.dump(rf_model, 'model.dmp', compress=3)
    print("模型保存所用时间: %s 秒" %(datetime.now() - start).seconds)
    

    上述案例比较简单,没有过多涉及数据清洗及预处理,包括RF算法也只定义了两个参数,且没有参数的优化过程,感兴趣的可以在此基础上深入一下。

    展开全文
  • 如果我们对所有这些模型的结果进行平均,我们有时可以从它们的组合中找到比任何单个部分更好的模型。这就是整体模型的工作方式,他们培养了许多不同的模型,并让他们的结果在整个团队中得到平均或投票。 我们现在很...

    原文链接:http://tecdat.cn/?p=4281

    原文出处:拓端数据部落公众号

    如果我们对所有这些模型的结果进行平均,我们有时可以从它们的组合中找到比任何单个部分更好的模型。这就是集成模型的工作方式。

    让我们构建一个由三个简单决策树组成的非常小的集合来说明:

    这些树中的每一个都根据不同的变量做出分类决策。

    随机森林模型比上面的决策树更深地生长树木,实际上默认是尽可能地将每棵树生长出来。随机森林以两种方式做到这一点。

    第一个技巧是使用套袋。Bagging会对您的训练集中的行进行随机抽样。使用样本函数很容易在R中进行模拟。假设我们想在10行的训练集上进行装袋。

    > sample(1:10, replace = TRUE)
    
    [1] 3 1 9 1 7 10 10 2 2 9

    在此模拟中,如果再次运行此命令,则每次都会获得不同的行样本。平均而言,大约37%的行将被排除在自举样本之外。通过这些重复和省略的行,每个使用装袋生长的决策树将略有不同。

    第二个随机来源超越了这个限制。随机森林不是查看整个可用变量池,而是仅采用它们的一部分,通常是可用数量的平方根。在我们的例子中,我们有10个变量,因此使用三个变量的子集是合理的。

    通过这两个随机性来源,整体包含一系列完全独特的树木,这些树木的分类都不同。与我们的简单示例一样,每个树都被调用以对给定乘客进行分类,对投票进行统计(可能有数百或数千棵树)并且选择多数决策。

    R的随机森林算法对我们的决策树没有一些限制。我们必须清理数据集中的缺失值。rpart它有一个很大的优点,它可以在遇到一个NA值时使用替代变量。在我们的数据集中,缺少很多年龄值。如果我们的任何决策树按年龄分割,那么树将搜索另一个以与年龄相似的方式分割的变量,并使用它们代替。随机森林无法做到这一点,因此我们需要找到一种手动替换这些值的方法。

    看一下合并后的数据框的年龄变量:

    > summary(combi$Age)
    
    Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
    
    0.17 21.00 28.00 29.88 39.00 80.00 263

    1309个中有263个值丢失了,这个数字高达20%!此子集是否缺少值。我们现在也想使用method="anova"决策树的版本,因为我们不是要再预测某个类别,而是连续变量。因此,让我们使用可用的年龄值在数据子集上生成一个树,然后替换缺少的那些样本:

    > combi$Age[is.na(combi$Age)] <- predict(Agefit, combi[is.na(combi$Age),])
    
    

    您可以继续检查摘要,所有这些NA值都消失了。

    现在让我们看看整个数据集的摘要,看看是否还有其他我们以前没有注意到的问题变量:

    > summary(combi)

    > summary(combi$Embarked)
    
    C Q S
    
    2 270 123 914

    两名乘客的空白。首先,我们需要找出他们是谁!我们可以which用于此:

    > which(combi$Embarked == '')
    
    [1] 62 830

    然后我们简单地替换这两个,并将其编码为一个因素:

    > combi$Embarked <- factor(combi$Embarked)
    
    

    另一个变量是Fare,让我们来看看:

    > summary(combi$Fare)
    
    Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
    
    0.000 7.896 14.450 33.300 31.280 512.300 1

    它只有一个乘客NA,所以让我们找出它是哪一个并用中位数票价取而代之:

    > which(is.na(combi$Fare))
    
    [1] 1044

    好的。我们的数据框现已被清理。现在进入第二个限制:R中的随机森林只能消化多达32个等级的因子。我们的FamilyID变量几乎翻了一倍。我们可以在这里采用两条路径,或者将这些级别更改为它们的基础整数(使用unclass()函数)并让树将它们视为连续变量,或者手动减少级别数以使其保持在阈值之下。

    我们采取第二种方法。然后我们将它转​​换回一个因素:

    > combi$FamilyID2 <- combi$FamilyID
    
    > combi$FamilyID2 <- factor(combi$FamilyID2)

    我们已经降到了22级,所以我们很好地将测试和训练集分开,安装并加载包

    randomForest:
    
    > install.packages('randomForest')

    设置随机种子。

    > set.seed(415)

    内部数字并不重要,您只需确保每次使用相同的种子编号,以便在随机森林函数内生成相同的随机数。

    现在我们准备运行我们的模型了。语法类似于决策树。

    > fit <- randomForest( )

    我们强制模型通过暂时将目标变量更改为仅使用两个级别的因子来预测我们的分类,而不是method="class"像使用那样指定。

    如果您正在使用更大的数据集,您可能希望减少树的数量,至少在初始探索时,使用限制每个树的复杂性nodesize以及减少采样的行数sampsize

    那么让我们来看看哪些变量很重要:

    > varImpPlot(fit)

    我们的Title变量在这两个指标中都处于领先地位。我们应该非常高兴地看到剩下的工程变量也做得非常好。

    预测函数与决策树的工作方式类似,我们可以完全相同的方式构建提交文件。

    > Prediction <- predict(fit, test)
    
    > write.csv(submit, file = "firstforest.csv", row.names = FALSE)

    让我们尝试一下条件推理树的森林。

    所以继续安装并加载party包。

    > install.packages('party')
    
    > library(party)

    以与我们的随机森林类似的方式构建模型:

    > set.seed(415)
    
    > fit <- cforest( )

    条件推理树能够处理比Random Forests更多级别的因子。让我们做另一个预测:

    > Prediction <- predict(fit, test, OOB=TRUE, type = "response")
    
    

    有问题欢迎下方留言!


    最受欢迎的见解

    1.从决策树模型看员工为什么离职

    2.R语言基于树的方法:决策树,随机森林

    3.python中使用scikit-learn和pandas决策树

    4.机器学习:在SAS中运行随机森林数据分析报告

    5.R语言用随机森林和文本挖掘提高航空公司客户满意度

    6.机器学习助推快时尚精准销售时间序列

    7.用机器学习识别不断变化的股市状况——隐马尔可夫模型的应用

    8.python机器学习:推荐系统实现(以矩阵分解来协同过滤)

    9.python中用pytorch机器学习分类预测银行客户流失

    展开全文
  • 案例背景 某天,小C的表妹小Q来找小C,说他遇到一点...),于是想让小C帮忙做一个决策,作为优秀的大数据分析师的小C,小C思忖良久,发现此事并不简单,还需要用到python,还需要搭建模型,于是小C一下子想到了决策

    我们都知道爱情不仅要有爱你之心,还有柴米油盐,最好的爱情不是风花雪月,而是雪中送炭,如果有一天爱情你都不相信了。不知道你接下来的日子该往哪里走,一定要相信你身边那个数据分析师的朋友,他会用数据告诉你的爱情之路怎么走?

    1.案例背景

    案例背景
    

    某天,小C的表妹小Q来找小C,说他遇到一点困扰----小Q的同事给她介绍了一个对象Mr.Z,这个人现年37岁,在某省机关做文员工作,但是小Q的择偶标准是需要对方月薪在5w以上,不要说小Q拜金,只因世人都知软饭香,但是现在刚认识没多久,也就不好意思直接问Mr.z,所以拿不动主意要不要和Mr.z深入交往,(说白了就是不知道Mr.z到底有多少钱?),于是想让小C帮忙做一个决策,作为优秀的大数据分析师的小C,小C思忖良久,发现此事并不简单,还需要用到python,还需要搭建模型,于是小C一下子想到了决策树算法,通过联想,又想到了随机森林,灵光乍现,突然想起来一个好主意,于是他就开始了。。。。

    数据集的准备

    大家都知道一个著名的数据集-成年人数据集,包括千万条样本数据,样本数据中一般包括年龄,工作性质,统计权重,学历,受教育时长,婚姻状况,职业,家庭教育,种族,性别,资产所得,资产损失,每周工作时长,原籍,收入等,这个数据集应该有用,于是先下载看看。
    下载链接:
    源数据点击下载
    在这里插入图片描述
    下载完直接重命名为adult.csv,本来后缀是data,直接删掉,强行改为csv格式文档。
    在这里插入图片描述

    3.读取数据

    import pandas as pd
    data = pd.read_csv('D:\\Python\\adult.csv',header = None,index_col = False,
                      names = ['年龄','单位性质','权重','学历','受教育时长','婚姻状况','职业',
                               '家庭教育','种族','性别',
                               '资产所得','资产损失','周工作时长','原籍','收入'])
    data_lite = data[['年龄','单位性质','学历','性别','周工作时长','职业','收入']]
    data_lite.head()
    

    运行结果展示:
    在这里插入图片描述

    4.用get_dummies处理数据

    因为在数据集中,我们可以看到单位性质,学历,职业,性别还有收入都不不是整型数据,而是字符串,就是利用get_dummies将现有的数据集上添加虚拟变量,让数据集变成可以用的格式。虚拟变量,也叫哑变量和离散特征编码,可用来表示分类变量、非数量因素可能产生的影响。

    data_dummies = pd.get_dummies(data_lite)
    print('样本原始特征:\n',list(data_lite.columns),'\n')
    print('虚拟变量特征:\n',list(data_dummies.columns))
    

    运行结果展示:
    在这里插入图片描述
    接下来我们可以看一下处理后的数据:

    data_dummies.head()
    

    运行代码结果:
    在这里插入图片描述

    5.划分特征变量

    各列数据分配给特征向量X和分类标签y,输入代码如下:

    features = data_dummies.loc[:,'年龄':'职业_ Transport-moving']
    X = features.values
    y = data_dummies['收入_ >50K'].values #将收入大于50k的作为预测目标
    print("代码运行结果:")
    print('特征形态:{} 标签形态:{}'.format(X.shape,y.shape))
    

    代码运行结果展示:
    在这里插入图片描述

    6.搭建数据模型

    我们本次就用决策树搭建模型,我们有32561条样本数据,有44个特征向量。
    1,将数据拆分成训练集和测试集

    from sklearn.model_selection import train_test_split
    X_train,X_test,y_train,y_test = train_test_split(X,y,random_state = 0)
    

    2.用最大深度为5的随机森林拟合数据

    from sklearn import tree
    go_dating_tree = tree.DecisionTreeClassifier(max_depth = 5)
    go_dating_tree.fit(X_train,y_train)
    print('模型得分:{:.2f}'.format(go_dating_tree.score(X_test,y_test)))
    
    

    运行结果:
    在这里插入图片描述
    通过上面随机森林模型预测我们可以看出来,模型在测试集中得到了0.8分,可以说是很不错的,也就是这个模型预测准确度准确率在80%,相信这个模型给小Q的爱情中提供足够的参考。

    7.爱情预测

    预测就是按照小Q提供的情况,通过前面随机森林搭建的模型,对他的收入进行预测,看看是否能达到小Q的高于50w收入的要求。
    下面是小Q提供的基本情况:
    Mr.Z年龄37岁,在省机关工作,学历是硕士,性别男,每周工作40小时,职业文员,然后我们将其对应数据输入,通过模型进行预测,输入代码如下:

    Mr_z = [[37,40,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0]]
    dating_dec = go_dating_tree.predict(Mr_z)
    print("代码运行结果:")
    print("=================================\n")
    if dating_dec ==1:
        print("大胆去追求真爱吧,这哥们牛批!")
    else:
        print("不用去了,不满足你的要求!")
    

    运行结果:
    在这里插入图片描述

    8.结果分析

    通过数据模型预测,显示结果如下,是的,机器冷冰冰告诉小Q一个残酷的事实,Mr.Z并不符合他的要求,当然出于常识,也知道文职工作人员收入也不会超过5W,都明白我们中国是不存在贪污受贿的。

    9.参考文献

    1.深入浅出python机器学习 段小手著。

    展开全文
  • 随机森林 在自助聚合的基础上, 每次构建决策树模型时, 不仅随机选择部分样本, 而且还随机选择部分特征(树的高度不同), 这样的集合算法, 不仅规避了强势样本对预测结果的影响, 而且也削弱了强势特征的影响, 是模型...
    自助聚合

    每次从总样本矩阵中以有放回抽样的方式,随机抽取部分样本构建决策树, 这样形成多颗包含不同训练本的决策树. 以削弱某些强势样本对模型预测结果的影响. 提高模型的泛化特性.

    随机森林

    在自助聚合的基础上, 每次构建决策树模型时, 不仅随机选择部分样本, 而且还随机选择部分特征(树的高度不同), 这样的集合算法, 不仅规避了强势样本对预测结果的影响, 而且也削弱了强势特征的影响, 是模型的预测能力更加泛化.

    随机森林相关API:

    import sklearn.ensemble as se
    # 构建随机森林回归器模型
    model = se.RandomForestRegressor(
        max_depth=4, 		# 最大深度
        n_estimators=1000, 	# 构建1000棵决策树
        # 子表中最小样本数 若<=这个数字则不再继续划分
    	min_samples_slit=2  
    )
    

    案例: 分析共享单车的需求, 从而判断如何投放.

    """
    demo02_bike.py  共享单车案例   随机森林
    """
    import numpy as np
    import sklearn.utils as su
    import sklearn.ensemble as se
    import sklearn.metrics as sm
    import matplotlib.pyplot as mp
    
    data = np.loadtxt('../ml_data/bike_day.csv', 
    	delimiter=',', unpack=False, 
    	dtype='U20')
    # 获取输入集与输出集
    header = data[0, 2:13]
    x = np.array(data[1:, 2:13], dtype=float)
    y = np.array(data[1:, -1], dtype=float)
    # 打乱数据集
    x, y = su.shuffle(x, y, random_state=7)
    # 拆分训练集,测试集
    train_size = int(len(x)*0.9)
    train_x, test_x, train_y, test_y = \
    	x[:train_size], x[train_size:], \
    	y[:train_size], y[train_size:]
    # 随机森林模型训练
    model=se.RandomForestRegressor(max_depth=10, 
    	n_estimators=1000, min_samples_split=2)
    model.fit(train_x, train_y)
    pred_test_y = model.predict(test_x)
    # 使用r2得分验证预测结果
    print(sm.r2_score(test_y, pred_test_y))
    # 输出特征重要性
    fi_day = model.feature_importances_
    print(fi_day)
    print(header)
    
    # 绘制特征重要性柱状图
    mp.figure('Bike', facecolor='lightgray')
    mp.subplot(211)
    mp.title('Day', fontsize=16)
    mp.ylabel('Importances', fontsize=12)
    mp.tick_params(labelsize=8)
    mp.grid(linestyle=':')
    pos = np.arange(fi_day.size)
    sorted_i = fi_day.argsort()[::-1]
    mp.xticks(pos, header[sorted_i])
    mp.bar(pos, fi_day[sorted_i], 
    	   color='dodgerblue', label='Bike_Day')
    mp.legend()
    
    
    data = np.loadtxt('../ml_data/bike_hour.csv', 
    	delimiter=',', unpack=False, 
    	dtype='U20')
    # 获取输入集与输出集
    header = data[0, 2:14]
    x = np.array(data[1:, 2:14], dtype=float)
    y = np.array(data[1:, -1], dtype=float)
    # 打乱数据集
    x, y = su.shuffle(x, y, random_state=7)
    # 拆分训练集,测试集
    train_size = int(len(x)*0.9)
    train_x, test_x, train_y, test_y = \
    	x[:train_size], x[train_size:], \
    	y[:train_size], y[train_size:]
    # 随机森林模型训练
    model=se.RandomForestRegressor(max_depth=10, 
    	n_estimators=1000, min_samples_split=2)
    model.fit(train_x, train_y)
    pred_test_y = model.predict(test_x)
    # 使用r2得分验证预测结果
    print(sm.r2_score(test_y, pred_test_y))
    # 输出特征重要性
    fi_hour = model.feature_importances_
    print(fi_hour)
    print(header)
    
    mp.subplot(212)
    mp.title('Hour', fontsize=16)
    mp.ylabel('Importances', fontsize=12)
    mp.tick_params(labelsize=8)
    mp.grid(linestyle=':')
    pos = np.arange(fi_hour.size)
    sorted_i = fi_hour.argsort()[::-1]
    mp.xticks(pos, header[sorted_i])
    mp.bar(pos, fi_hour[sorted_i], 
    	   color='orangered', label='Bike Hour')
    mp.legend()
    mp.show()
    
    0.8926334392300549
    [0.06638183 0.28997887 0.02826374 0.00304802 0.01460011 0.00411691
     0.01753458 0.33964001 0.14297167 0.06249903 0.03096522]
    ['season' 'yr' 'mnth' 'holiday' 'weekday' 'workingday' 'weathersit' 'temp'
     'atemp' 'hum' 'windspeed']
    0.9186105067675527
    [0.02229112 0.08663297 0.00830193 0.64513701 0.00145209 0.00705756
     0.06023155 0.01646287 0.12005369 0.01383168 0.01587423 0.0026733 ]
    ['season' 'yr' 'mnth' 'hr' 'holiday' 'weekday' 'workingday' 'weathersit'
     'temp' 'atemp' 'hum' 'windspeed']
    

    在这里插入图片描述

    展开全文
  • 竞赛时写的一个python小程序,得了0.93分,思路如下,1读取训练集、2数据预处理、3上模型、4将模型应用到预测及、5生成预测结果
  • 随机森林模型解释_随机森林解释

    千次阅读 2020-10-12 11:16:33
    随机森林模型解释In this post, we will explain what a Random Forest model is, see its strengths, how it is built, and what it can be used for.在这篇文章中,我们将解释什么是随机森林模型,了解其优势,...
  • 定义:随机森林指的是利用多棵决策树对样本进行训练并预测的一种分类器。可回归可分类。所以随机森林是基于多颗决策树的一种集成学习算法,常见的决策树算法主要有以下几种:1. ID3:使用信息增益g(D,A)进行特征选择...
  • python分类分析--随机森林原理及案例

    千次阅读 2020-02-24 17:35:43
    随机森林 1、什么是集成学习方法 集成学习通过建立几个板型组合的来解决单一预测问题,它的工作原理是生成多个分类器/模型,各独立地学习和作出预测。这些预测最后结合成组合预测,因此优于任何一个单分类的做出预测...
  • 这周开始了对随机森林算法的学习,kaggle网站上有一个关于泰坦尼克号幸存预测的案例很适合用随机森林算法来预测,所以我们本周的算法就以这个数据集开始讲解。 定义问题 本研究是利用泰坦尼克号乘客数据集,运用...
  • 能够理解基本原理并将代码用于实际的业务案例是本文的目标,本文将详细介绍如何利用Python实现集成学习中随机森林这个经典的方法来预测宽带客户的流失,主要将分为两个部分: 详细原理介绍 Python代码实战 ...
  • Python+随机森林

    2018-11-28 20:16:20
    随机森林 随机森林定义 随机森林(Random Forest,简称RF),是在以决策树为基础学习器构建Bagging集成的基础上引入了随机属性选择。即由许多决策树随机构成,其中每棵决策树之间没有关联。当新样本输入时,由森林中的...
  • 使用python中的包对决策树与随机森林进行案例实现,文档中包括对于该部分知识自己的理解,欢迎指出错误
  • # 随机森林回归模型 (属于集合算法的一种) # max_depth:决策树最大深度10 # n_estimators:构建1000棵决策树,训练模型 # min_samples_split: 子表中最小样本数 若小于这个数字,则不再继续向下拆分 model = se....
  • Python实现随机森林算法,深度学习拥有高方差使得决策树(secision tress)在处理特定训练数据集时其结果显得相对脆弱。bagging(bootstrap aggregating 的缩写)算法从训练数据的样本中建立复合模型,可以有效...
  • 本文是Python商业数据挖掘实战的第3篇1 - 基于不平衡数据的反欺诈模型实战2 - Apriori算法实现智能推荐3- 随机森林预测宽带客户离网前言 组合算法也叫集成学习,在金融行...
  • python中实现随机森林Random forest is a highly versatile machine learning method with numerous applications ranging from marketing to healthcare and insurance. It can be used to model the impact of ...
  • 拥有高方差使得决策树(secision tress)在处理特定训练数据集时其结果显得相对脆弱。bagging(bootstrap ...随机森林算法(Random forest algorithm)是对 bagging 算法的扩展。除了仍然根据从训练数据样本建立复...
  • 梯度提升回归 ensemble.IsolationForest—> 隔离森林 ensemble.RandomForestClassifier —> 随机森林分类 ensemble.RandomForestRegressor —> 随机森林回归 ensemble.RandomTreesEmbedding—> 完全随机树的集成 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,626
精华内容 1,450
关键字:

python随机森林模型案例

python 订阅