黑马程序员技术交流社区

标题: 【上海校区】随机森林实战教程-Python-Demo [打印本页]

作者: 不二晨    时间: 2018-8-6 10:00
标题: 【上海校区】随机森林实战教程-Python-Demo
本帖最后由 不二晨 于 2018-8-6 10:01 编辑

前言

随机森林Python版本有很可以调用的库,使用随机森林非常方便,主要用到以下的库:
sklearn
pandas
numpy
随机森林入门

我们先通过一段代码来了解Python中如何使用随机森林。

from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
import pandas as pd
import numpy as np

iris = load_iris()   # 这里是sklearn中自带的一部分数据
df = pd.DataFrame(iris.data, columns=iris.feature_names) # 格式化数据
print (df)          #
df['is_train'] = np.random.uniform(0, 1, len(df)) <= .75
df['species'] = pd.Categorical.from_codes(iris.target, iris.target_names)  ## 新接口 数据
df.head()

train, test = df[df['is_train']==True], df[df['is_train']==False]

features = df.columns[:4]
clf = RandomForestClassifier(n_jobs=2)
y, _ = pd.factorize(train['species'])
clf.fit(train[features], y)  # 用train来训练样本

test_pred=clf.predict(test[features])   #用测试数据来做预测
preds = iris.target_names[test_pred]
pd.crosstab(test['species'], preds, rownames=['actual'], colnames=['preds'])

上述是一个利用sklearn的数据做的

kaggle-美国人口普查年收入比赛

现在我们在kaggle上的数据集上做一次实验,这个数据集有训练集和测试集,训练集便于我们训练模型,测试集用来校验我们模型的正确性,这是最简单的。
需要导入的库
import pandas as pd  # load csv's (pd.read_csv)
import numpy as np   # math (lin. algebra)

import sklearn as skl   # machine learning
from sklearn.ensemble import RandomForestClassifier
#from plotnine import *
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
from sklearn_pandas import DataFrameMapper
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report

数据读取
def get_train_data():
#下面两个文件路径替换为你电脑上该文件的路径
    train_path = "D:/workspace/Data/kggal/AmericaIncome/adult.data"
    test_path = 'D:/workspace/Data/kggal/AmericaIncome/adult.test'
    columns = ['Age','Workclass','fnlgwt','Education','EdNum','MaritalStatus','Occupation','Relationship','Race','Sex','CapitalGain','CapitalLoss','HoursPerWeek','Country','Income']
    df_train_set = pd.read_csv(train_path, names=columns)
    #print(df_train_set.head())
    return df_train_set

def get_test_data():
    test_path = 'D:/workspace/Data/kggal/AmericaIncome/adult.test'
    columns = ['Age','Workclass','fnlgwt','Education','EdNum','MaritalStatus','Occupation','Relationship','Race','Sex','CapitalGain','CapitalLoss','HoursPerWeek','Country','Income']
    df_test_set = pd.read_csv(test_path, names=columns)
    #print(df_test_set.head())
    return df_test_set

15
数据预处理
df_train_set=get_train_data()
df_test_set=get_test_data()

df_train_set.drop('fnlgwt', axis=1, inplace=True)
df_test_set.drop('fnlgwt', axis=1, inplace=True)

print(df_train_set.replace(' ?', np.nan).shape)
#(32561, 14)
print(df_train_set.replace(' ?', np.nan).dropna().shape)
# (30162, 15)
print(df_test_set.replace(' ?', np.nan).shape)
#(16282, 14)
print(df_test_set.replace(' ?', np.nan).dropna().shape)
# (15060, 15)

# 删除含有?(缺失行)
train_set = df_train_set.replace(' ?', np.nan).dropna()

test_set = df_test_set.replace(' ?', np.nan).dropna()

# 把测试语料集中的 Income 归一化
test_set['Income'] = test_set.Income.replace({' <=50K.': ' <=50K', ' >50K.': ' >50K'})
print(test_set.Income.unique())
# [' <=50K' ' >50K']
print(df_train_set.Income.unique())
# [' <=50K' ' >50K']

# 因为有 受教育的年数,所以这里不需要教育这一列
train_set.drop(["Education"], axis=1, inplace=True)
test_set.drop(["Education"], axis=1, inplace=True)

将数据中的特征向量化以及得到特征值、预测值分开
combined_set = pd.concat([train_set, test_set], axis=0)
for feature in combined_set.columns:
    if combined_set[feature].dtype == 'object':
        combined_set[feature] = pd.Categorical(combined_set[feature]).codes

train_set = combined_set[:train_set.shape[0]]
test_set = combined_set[test_set.shape[0]:]
print(train_set.Workclass.unique())
print(test_set.Income.unique())

cols = list(train_set.columns)
cols.remove("Income")

x_train, y_train = train_set[cols].values, train_set["Income"].values
#测试集的输入和输出结果分开,用来校验模型的准确率
x_test, y_test = test_set[cols].values, test_set["Income"].values

预测模型
treeClassifier = DecisionTreeClassifier()
treeClassifier.fit(x_train, y_train) # 训练模型
treeClassifier.score(x_test, y_test)
print(treeClassifier.score(x_test, y_test))
# 输出为:0.8700351435581195
y_pred = treeClassifier.predict(x_test)  # 用测试集做预测
print(classification_report(y_test, y_pred)) # 查看模型的预测值与真实值
#输出为
             precision    recall  f1-score   support

          0       0.90      0.93      0.92     22674
          1       0.77      0.67      0.72      7488

avg / total       0.87      0.87      0.87     30162

从上面的输出结果可以看到,最简单的随机森林模型,没有加任何参数优化、交叉验证等等,可以达到的准确率为87%左右,而且这个数据集规模较大,训练集3万多条,测试集1万多条,其结果也较为合理,之后的文章会讲解一下优化方面的内容。

总结

随机森林算法模型的形式化描述如下:
训练入参
n个特征加一个分类结果
特征1 特征2 特征3 特征4 ... 特征n 分类结果
1
预测入参
预测的入参就是n个特征
特征1 特征2 特征3 特征4 ... 特征n
1
本文中不同特征中的数据并没有进行归一化处理,很多特征的量化数值很大,其实都可以归一化处理一下,这样就不会被某一个特征影响掉,后期可以考虑优化一下,然后整个算法的训练模型部分的代码量其实没多少,前期很多代码都是数据集的预处理,将不符合规范的数据集去掉,以及将数据中的字符特征转换为数值特征,这样便于模型训练。其实很多数据都是这样的,必须知道所有的数据情况,这里数据集的唯一好处是告诉你了特征有那些,如果没有告诉你特征,你就必须自己提取特征,在很多比赛中都是要自己思考需要那些特征,建议参考天池大数据的技术圈中,往届比赛大家的分享–>天池新人实战赛o2o优惠券使用预测。
随机森林有以下缺陷:
当我们需要推断超出范围的独立变量或非独立变量,随机森林做得并不好,我们最好使用如 MARS 那样的算法。
随机森林算法在训练和预测时都比较慢。
如果需要区分的类别十分多,随机森林的表现并不会很好。
最后,感谢下面两个博客文章,也是从别人的内容上学。这是简单的实战文章,之后我会去了解一些量化分析、算法优化方面的内容,
作者: 不二晨    时间: 2018-8-9 13:15
奈斯




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2