赞
踩
核心思想:相似的输入必会产生相似的输出。
年龄 | 学历 | 经历 | 性别 | ==> | 薪资 |
---|---|---|---|---|---|
1 | 1 | 1 | 1 | ==> | 6000(低) |
2 | 1 | 3 | 1 | ==> | 10000(中) |
3 | 3 | 4 | 1 | ==> | 50000(高) |
… | … | … | … | ==> | … |
1 | 3 | 2 | 2 | ==> | ? |
样本数量非常庞大 100W个样本
换一种数据结构,来提高检索效率
树形结构
回归 : 均值
分类 : 投票(概率)
为了提高搜索效率,使用树形数据结构处理样本数据:
年
龄
=
1
{
学
历
1
学
历
2
学
历
3
年
龄
=
2
{
学
历
1
学
历
2
学
历
3
年
龄
=
3
{
学
历
1
学
历
2
学
历
3
年龄=1\left\{
首先从训练样本矩阵中选择一个特征进行子表划分,使每个子表中该特征的值全部相同,然后再在每个子表中选择下一个特征按照同样的规则继续划分更小的子表,不断重复直到所有的特征全部使用完为止,此时便得到叶级子表,其中所有样本的特征值全部相同。对于待预测样本,根据其每一个特征的值,选择对应的子表,逐一匹配,直到找到与之完全匹配的叶级子表,用该子表中样本的输出,通过平均(回归)或者投票(分类)为待预测样本提供输出。
首先选择哪一个特征进行子表划分决定了决策树的性能。这么多特征,使用哪个特征先进行子表划分?
原始数据集S,此时树的深度depth=0;
针对集合S,遍历每一个特征的每一个value(遍历数据中的所有离散值 (12个) ),用该value将原数据集S分裂成2个集合:左集合left(<=value的样本)、右集合right(>value的样本),分别计算这2个集合的mse(均方误差),找到使(left_mse+right_mse)最小的那个value,记录下此时的特征名称和value,这个就是最佳分割特征以及最佳分割值;
mse:均方误差
((y1-y1’)^2 + (y2-y2’)^2 + (y3-y3’)^2 + (y4-y4’)^2 ) / 4 = mse
x1 y1 y1’
x2 y2 y2’
x3 y3 y3’
x4 y4 y4’
找到最佳分割特征以及最佳分割value之后,用该value将集合S分裂成2个集合,depth+=1;
针对集合left、right分别重复步骤2,3,直到达到终止条件。
import sklearn.tree as st
# 创建决策树回归器模型 决策树的最大深度为4
model = st.DecisionTreeRegressor(max_depth=4)
# 训练模型
# train_x: 二维数组样本数据
# train_y: 训练集中对应每行样本的结果
model.fit(train_x, train_y)
# 测试模型
pred_test_y = model.predict(test_x)
import sklearn.datasets as sd
import sklearn.utils as su
# 加载波士顿地区房价数据集
boston = sd.load_boston()
print(boston.feature_names)
# |CRIM|ZN|INDUS|CHAS|NOX|RM|AGE|DIS|RAD|TAX|PTRATIO|B|LSTAT|
# 犯罪率|住宅用地比例|商业用地比例|是否靠河|空气质量|房间数|年限|距中心区距离|路网密度|房产税|师生比|黑人比例|低地位人口比例|
# 打乱原始数据集的输入和输出
x, y = su.shuffle(boston.data, boston.target, random_state=7)
# 划分训练集和测试集
train_size = int(len(x) * 0.8)
train_x, test_x, train_y, test_y = \
x[:train_size], x[train_size:], \
y[:train_size], y[train_size:]
import sklearn.tree as st
# 创建决策树回归模型
model = st.DecisionTreeRegressor(max_depth=4)
# 训练模型
model.fit(train_x, train_y)
# 测试模型
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))
"""
0.6773870228226634
"""
import sklearn.tree as st
import sklearn.ensemble as se
# model: 决策树模型(一颗)
model = st.DecisionTreeRegressor(max_depth=4)
# 自适应增强决策树回归模型
# n_estimators:构建400棵不同权重的决策树,训练模型
model = se.AdaBoostRegressor(model, n_estimators=400, random_state=7)
# 训练模型
model.fit(train_x, train_y)
# 测试模型
pred_test_y = model.predict(test_x)
model.fit(train_x, train_y)
fi = model.feature_importances_
import sklearn.tree as st
import sklearn.ensemble as se
# 自适应增强决策树回归模型
# n_estimators:构建400棵不同权重的决策树,训练模型
model = se.GridientBoostingRegressor(
max_depth=10, n_estimators=1000, min_samples_split=2)
"""
创建基于决策树的正向激励回归器模型
model = se.GridientBoostingRegressor(
max_depth=4, n_estimators=400, random_state=7)
"""
# 训练模型
model.fit(train_x, train_y)
# 测试模型
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))
import sklearn.ensemble as se
# 随机森林回归模型 (属于集合算法的一种)
# max_depth:决策树最大深度10
# n_estimators:构建1000棵决策树,训练模型
# min_samples_split: 子表中最小样本数 若小于这个数字,则不再继续向下拆分
model = se.RandomForestRegressor(
max_depth=10, n_estimators=1000, min_samples_split=2)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 加载数据集
import sklearn.datasets as sd
boston = sd.load_boston()
# 把数据存入dataframe
data = pd.DataFrame(boston.data, columns=boston.feature_names) # 数据,特征名称
data['TARGET'] = boston.target
data
import sklearn.model_selection as ms
import sklearn.linear_model as lm
import sklearn.metrics as sm
# 整理输入集输出集,拆分测试集训练集
x, y = data.iloc[:, :-1], data['TARGET'] # 所有行,除了最后一列都要
# random_state: 随机种子 对同一组数据使用相同的随机种子划分数据集,得到的结果是一样的
train_x, test_x, train_y, test_y = ms.train_test_split(x, y, test_size=0.2, random_state=7) # 20%做测试
# 训练一个模型
model = lm.LinearRegression()
model.fit(train_x, train_y)
# 针对测试样本进行测试,评估
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))
"""
0.5785415472763427
"""
# 训练一个模型
# 调整岭回归的参数
params = np.arange(0, 130, 10)
for param in params:
model = lm.Ridge(param)
model.fit(train_x, train_y)
pred_test_y = model.predict(test_x)
# 评估误差
print(param, '->', sm.r2_score(test_y, pred_test_y))
"""
0 -> 0.5785415472763407
10 -> 0.5783802227286681
20 -> 0.5952305907645055
30 -> 0.6088556382989273
40 -> 0.6197079306450874
50 -> 0.6284277390131747
60 -> 0.6355093721368099
70 -> 0.6413175705099186
80 -> 0.6461224027876207
90 -> 0.6501263632540781
100 -> 0.6534834314895364
110 -> 0.6563123089340717
120 -> 0.6587056780309234
"""
model = lm.Ridge()
model.fit(train_x, train_y)
test_x, test_y = train_x.iloc[:30:4], train_y[:30:4]
pred_test_y = model.predict(test_x)
# 评估误差
print(sm.r2_score(test_y, pred_test_y))
"""
0.5703641157344471
"""
import sklearn.pipeline as pl
import sklearn.preprocessing as sp
model = pl.make_pipeline(sp.PolynomialFeatures(2), lm.Ridge())
model.fit(train_x, train_y) # 对train_x做多项式特征扩展,然后训练线性回归模型
pred_test_y = model.predict(test_x)
# 评估
print(sm.r2_score(test_y, pred_test_y))
"""
0.7240028637771994
"""
import sklearn.tree as st
# 训练一个模型
model = st.DecisionTreeRegressor(max_depth=4)
model.fit(train_x, train_y)
# 针对测试样本进行测试,评估
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))
"""
0.6773870228226633
"""
# 获取特征重要性
fi = model.feature_importances_
s = pd.Series(fi, index=train_x.columns)
s.sort_values().plot.barh()
import sklearn.ensemble as se
model = st.DecisionTreeRegressor(max_depth=4)
model = se.AdaBoostRegressor(model, n_estimators=400, random_state=7)
model.fit(train_x, train_y)
# 针对测试样本进行测试,评估
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))
"""
0.8500714067889193
"""
# 获取特征重要性
fi = model.feature_importances_
s = pd.Series(fi, index=train_x.columns)
s.sort_values().plot.barh()
# max_depth: 最大深度
# n_estimators: 弱模型的数量
# min_samples_split: 样本最小拆分数 若叶子节点样本数量小于该值,则不再向下拆分
params_a = [5,6,7,8,9]
params_b = [3,5,7,9]
for a in params_a:
for b in params_b:
model = se.GradientBoostingRegressor(max_depth=a, n_estimators=50, random_state=7, min_samples_split=b)
model.fit(train_x, train_y)
pred_test_y = model.predict(test_x)
print(a,b,'->',sm.r2_score(test_y, pred_test_y))
"""
5 3 -> 0.8444283217637356
5 5 -> 0.8362802986262108
5 7 -> 0.8244591764017146
5 9 -> 0.8298497346662654
6 3 -> 0.8249951883226199
6 5 -> 0.8059360418597886
6 7 -> 0.8141640561570052
6 9 -> 0.8275116414579332
7 3 -> 0.7969013091094028
7 5 -> 0.7812411922035595
7 7 -> 0.8008200242501035
7 9 -> 0.8256894969860424
8 3 -> 0.7585802800753443
8 5 -> 0.7723735710591806
8 7 -> 0.7829110226097211
8 9 -> 0.8085822093658608
9 3 -> 0.7460888650571811
9 5 -> 0.7694016598612741
9 7 -> 0.7860402350340085
9 9 -> 0.8067612861881294
"""
model = se.RandomForestRegressor(max_depth=5, n_estimators=400, min_samples_split=3)
model.fit(train_x, train_y)
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))
"""
0.7973306052068381
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import sklearn.tree as st
import sklearn.ensemble as se
import sklearn.model_selection as ms
import sklearn.metrics as sm
# 加载数据集 整理数据集
data = pd.read_csv('bike_day.csv')
data = data.drop(['instant','dteday','casual','registered'], axis=1)
data
data.pivot_table(index='yr', values=['cnt'])
"""
cnt
yr
0 3405.761644
1 5599.934426
"""
data.pivot_table(index='weekday', values=['cnt'])
"""
cnt
weekday
0 4228.828571
1 4338.123810
2 4510.663462
3 4548.538462
4 4667.259615
5 4690.288462
6 4550.542857
"""
data['windspeed'].plot.hist() # 风速
# 整理数据集 输入集与输出集、训练集与测试集
x, y = data.iloc[:,:-1], data['cnt']
train_x, test_x, train_y, test_y = \
ms.train_test_split(x, y, test_size=0.1, random_state=7)
# 训练模型
model = se.RandomForestRegressor(max_depth=10, n_estimators=1000, min_samples_split=5)
model.fit(train_x, train_y)
# 模型评估
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))
print(sm.mean_absolute_error(test_y, pred_test_y))
"""
0.8763294359170949
472.2823486488968
"""
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。