zoukankan      html  css  js  c++  java
  • 跟我学算法-集成算法

    我们以泰坦尼克号的获救信息为列

    第一步:读取数据

    import  pandas as pd
    import numpy as np
    
    titanic = pd.read_csv('titanic_train.csv')
    
    #输出统计值
    print(titanic.describe())

    第二步:数据准备

    1.对于数字型缺失,我们使用均值来填充缺失值,对于字母型缺失, 我们使用出现概率最大的字母来填充缺失值

    2.为了便于计算我们需要把字母类型,转换为数字类型

    #使用均值填充缺失值
    titanic['Age'] = titanic['Age'].fillna(titanic['Age'].median())
    
    #输出其中的类别
    print(titanic['Sex'].unique())
    
    #.loc取出对应的数据,前面一个参数是索引,后面是对应的属性,将字符串转换为数字类型
    titanic.loc[titanic['Sex']=='male', "Sex"] = 0
    titanic.loc[titanic['Sex']=='female', "Sex"] = 1
    
    
    print(titanic['Embarked'].unique())
    #存在缺失值, 字母的话,用出现次数最多的S补齐
    titanic['Embarked'] = titanic['Embarked'].fillna('S')
    
    #将字母属性转换为数字属性
    titanic.loc[titanic['Embarked']=='S', 'Embarked'] = 0
    titanic.loc[titanic['Embarked']=='C', 'Embarked'] = 1
    titanic.loc[titanic['Embarked']=='Q', 'Embarked'] = 2

    第三步:算法尝试,我们使用了线性回归

    #使用线性回归模型预测结果
    
    from sklearn.linear_model import LinearRegression, LogisticRegression
    
    #导入交叉验证的库
    from sklearn.cross_validation import KFold
    
    #测试样本的属性值
    predictors =  ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']
    
    
    predictions = []
    alg = LinearRegression()
    kf = KFold(titanic.shape[0], n_folds=3, random_state=1)  #进行交叉验证分割,n_folds 表示分割的次数
    
    
    # 做交叉验证
    for train, test in kf:
    
        #建立测试样本参数
        train_predictors = (titanic[predictors].iloc[train, :])
        #建立测试样本的结果
        train_target = titanic['Survived'].iloc[train]
        #建立模型
        alg.fit(train_predictors, train_target)
        #使用分割的验证集进行样本预测,
        test_predictions = alg.predict(titanic[predictors].iloc[test, :])
        #添加预测结果
        predictions.append(test_predictions)
    
    
    
    predictions = np.concatenate(predictions, axis=0)  #在一列上组合结果
    #对predictions 进行分类
    predictions[predictions > 0.5] = 1 
    predictions[predictions < 0.5] = 0
    
    print(np.sum(predictions == titanic["Survived"])/len(titanic))  # 统计布尔值,计算结果


    >>>0.78

    第四步: 使用logistic做尝试,最后的结果与线性回归结果差不多

    from sklearn import cross_validation  
    from sklearn.linear_model import LogisticRegression
    
    #建立logstic模型
    alg = LogisticRegression(random_state=1)
    
    #直接的交叉验证,scores为准确度
    scores = cross_validation.cross_val_score(alg, titanic[predictors], titanic["Survived"], cv=3)
    #对score进行加和平均
    print(scores.mean())


    >>>> 0.78

    第五步: 使用随机森林进行尝试,调整参数后,精度发生了一定的提升,关于随机森林的参数调节可以使用GridSearchCV

    # 使用随机森林
    
    from sklearn import cross_validation
    from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
    
    #得到样本的参数名
    predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]
    
    # 建立树模型
    alg = RandomForestClassifier(random_state=1, n_estimators=10, min_samples_split=2, min_samples_leaf=1)
    
    #交叉验证, 采用cross_validation.cross_val_score 直接获得交叉验证的准确度
    kf = cross_validation.KFold(titanic.shape[0], n_folds=3, random_state=1)  #交叉验证拆分
    scores = cross_validation.cross_val_score(alg, titanic[predictors], titanic["Survived"], cv=kf)
    
    #对准确度求平均
    print(scores.mean())
    
    >>>>0.78
    #这里我们调节了RandomForestClassifier的参数,重新验证 alg = RandomForestClassifier(random_state=1, n_estimators=50, min_samples_split=4, min_samples_leaf=2) predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"] kf = cross_validation.KFold(titanic.shape[0], n_folds=3, random_state=1) #进行了分割 print(kf) score = cross_validation.cross_val_score(alg, titanic[predictors], titanic['Survived'], cv=kf) print(score.mean())

    >>>> 0.8154

     第6步:我们探讨一下样本属性的重要性,以及对样本属性进行挖掘

        1. 变量挖掘

    #我们通过观察重新组合一个属性.
    titanic['FamilySize'] = titanic['SibSp'] + titanic['Parch']
    #对于titanic['Name']使用lambda x:len(x)函数构成Namelength属性
    titanic['Namelength'] = titanic['Name'].apply(lambda x:len(x))
    
    
    # 引入正则表达式
    import re
    
    #从名字中提取一个新的属性
    def get_title(name):
        # Use a regular expression to search for a title.  Titles always consist of capital and lowercase letters, and end with a period.
        title_search = re.search(' ([A-Za-z]+).', name)
        # If the title exists, extract and return it.
        if title_search:
            return title_search.group(1)
        return ""
    
    # 对名字选项使用get_title函数
    titles = titanic["Name"].apply(get_title)  
    print(pd.value_counts(titles))
    #将字母类型转换为数字类型
    title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Dr": 5, "Rev": 6, "Major": 7, "Col": 7, "Mlle": 8, "Mme": 8, "Don": 9, "Lady": 10, "Countess": 10, "Jonkheer": 10, "Sir": 9, "Capt": 7, "Ms": 2}
    #组合了一个关于名字的属性
    for k, v in title_mapping.items():
        titles[titles==k] = v
    #创建一个新的变量
    titanic["Title"] = titles

          2.评估样本属性的重要性

    样本属性的重要性的评估,是通过给单个样本属性添加干扰值,分析前后的分类效果,如果分类效果不变就说明该样本属性不重要,否者就说明该样本是重要的

    import numpy as np
    from sklearn.feature_selection import  SelectKBest, f_classif
    import matplotlib.pyplot as plt
    
    predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked", 'Title', 'Namelength', 'FamilySize']
    selector = SelectKBest(f_classif, k=5)  #f_classif只适用与分类,k=5表示主要功能数量为5个
    selector.fit(titanic[predictors], titanic['Survived'])
    
    score = -np.log(selector.pvalues_) #打印得分
    
    plt.bar(range(len(score)), score) #做柱形图,第一个参数是横坐标,第二个参数是得分高度
    plt.xticks(range(len(predictors)), predictors, rotation='vertical') #rotation 表示摆放位置是竖直的
    plt.show()

    从图中我们可以看出pclass, sex, fare, title, Namelength五个属性的重要性较高,我们使用这四个属性进行再次的分析,我们发现只是提高了一点点的效果,呵呵了

    #重新选择参数
    predictors = ['Pclass', 'Sex', 'Fare', 'Title', 'Namelength']
    
    alg = RandomForestClassifier(random_state=1, n_estimators=50, min_samples_split=4, min_samples_leaf=2)
    
    kf = cross_validation.KFold(titanic.shape[0], n_folds=3, random_state=1) #进行了分割
    
    score = cross_validation.cross_val_score(alg, titanic[predictors], titanic['Survived'], cv=kf)
    
    print(score.mean())

    >>>0.8159

    第7步,只能放大招了,我们这里使用集成算法,我们使用梯度提升树 和 LogisticRegression,提高了一些精度,说明还是有效果的

    from sklearn.ensemble import GradientBoostingClassifier
    import numpy as np
    # 算法集合:梯度提升树分类器 和 LogisticRegression
    algorithms = [
                  [GradientBoostingClassifier(random_state=1, n_estimators=25, max_depth=3), 
                  ["Pclass", "Sex", "Age", "Fare", "Embarked", 'Title', 'FamilySize']],
                  [LogisticRegression(random_state=1), 
                   ["Pclass", "Sex", "Age", "Fare", "Embarked", 'Title', 'FamilySize']]
                  ]
    
    #交叉验证
    kf = KFold(titanic.shape[0], n_folds=3, random_state=1) #进行分割
    
    
    predictions = []
    for train, test in kf: #训练集和测试集的分离
        train_target = titanic['Survived'].iloc[train]  #从原始样本分离train的Survived
        full_test_preditions = []
        for alg, predictors in algorithms:
            alg.fit(titanic[predictors].iloc[train, :], train_target) #模型训练
            # alg.predict_proba转换为概率,astype变为float类型
            test_predictions = alg.predict_proba(titanic[predictors].iloc[test,:].astype(float))[:, 1]
            full_test_preditions.append(test_predictions)
        # test_predictions = (full_test_preditions[0] + full_test_preditions[1])/2
        #增加梯度提升树分类器的权重
        test_predictions = (full_test_preditions[0] * 3 + full_test_preditions[1]) / 4
        # 把概率值转换为数值
        test_predictions[test_predictions <=.5] = 0
        test_predictions[test_predictions > .5] = 1
        predictions.append(test_predictions)
    
    predictions = np.concatenate(predictions, axis=0)  #将(3,291)二维转换为一维数据,(873,1)axis=0维度
    
    print(np.sum(predictions == titanic["Survived"])/len(titanic))  # np.sum统计布尔值,计算结果


    >>>82.5
  • 相关阅读:
    [转载][mysql]mysql字符集干货
    [mysql]修改表段默认值
    微信支付之h5方式(非微信内置浏览器中支付)
    阿里云 ECS 安全组
    Memcached cas 陷阱
    Memcached 分布式集群
    nginx 配置多个主机
    static类型的变量
    全局变量和局部变量
    nginx 负载均衡(默认算法)
  • 原文地址:https://www.cnblogs.com/my-love-is-python/p/9514546.html
Copyright © 2011-2022 走看看