阿尔及利亚森林火灾数据集

0.导入包

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.tree import DecisionTreeClassifier,plot_tree
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV

1.数据分析及处理

1.1数据加载和分析

data = pd.read_csv('Algerian_forest_fires_dataset_UPDATE.csv')
data

 


 

.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}

</style>


 

DAY

MONTH

YEAR

TEMPERATURE

RH

WS

RAIN

FFMC

DMC

DC

ISI

BUI

FWI

CLASSES

0

1

6

2012

29

57

18

0

65.7

3.4

7.6

1.3

3.4

0.5

not fire

1

2

6

2012

29

61

13

1.3

64.4

4.1

7.6

1

3.9

0.4

not fire

2

3

6

2012

26

82

22

13.1

47.1

2.5

7.1

0.3

2.7

0.1

not fire

3

4

6

2012

25

89

13

2.5

28.6

1.3

6.9

0

1.7

0

not fire

4

5

6

2012

27

77

16

0

64.8

3

14.2

1.2

3.9

0.5

not fire

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

242

26

9

2012

30

65

14

0

85.4

16

44.5

4.5

16.9

6.5

fire

243

27

9

2012

28

87

15

4.4

41.1

6.5

8

0.1

6.2

0

not fire

244

28

9

2012

27

87

29

0.5

45.9

3.5

7.9

0.4

3.4

0.2

not fire

245

29

9

2012

24

54

18

0.1

79.7

4.3

15.2

1.7

5.1

0.7

not fire

246

30

9

2012

24

64

15

0.2

67.3

3.8

16.5

1.2

4.8

0.5

not fire

247 rows × 14 columns

</div>

 

阿尔及利亚森林火灾数据集包括 244 个实例,这些实例对阿尔及利亚两个区域的数据进行了重新分组,即位于阿尔及利亚东北部的 Bejaia 区域和位于阿尔及利亚西北部的 Sidi Bel-abbes 区域。每个区域 122 个。数据集有以下特征:1.day - 日,2.month - 月 ("六月" 到 '九月' ), 3.year - 年(2012)4.Temperature - 温度: 温度中午 (最高温度) 以摄氏度为单位:22至425.RH - 相对湿度 :21 至 90 6.Ws - 风速 以公里/小时为单位:6至29 7.Rain - 雨: 总天毫米:0至16.8 8.FWI系统的精细燃油水分代码(FFMC)指数:28.6至92.59.FWI系统的达夫水分代码(DMC)指数:1.1至65.910.FWI系统的干旱代码(DC)指数:7至220.411.FWI系统的初始点差指数(ISI):0至18.512.FWI系统的累积指数(BUI)指数:1.1至6813.火灾天气指数(FWI)指数:0至31.1

目标列为是否有火(Classes)。

1.2数据预处理

为确保数据的完整性、一致性、准确性,需要进行数据预处理。

(1)整理数据集

 

#  数据集成:由于数据集分为两个地区,因此我们把两个地区的数据集合并为一个来分析,这样可以使分析的数据样本较多,可信度较高。
#因此去掉数据中的两个地区行和一个空白行
data1 = data.iloc[0:122,:]  #第一个数据集
data1
data2 = data.iloc[125:247,:]  #第二个数据集
data2
data = pd.concat([data1,data2])  #合并为一个
#data为整理好的数据集
data

 


 

.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}

</style>


 

DAY

MONTH

YEAR

TEMPERATURE

RH

WS

RAIN

FFMC

DMC

DC

ISI

BUI

FWI

CLASSES

0

1

6

2012

29

57

18

0

65.7

3.4

7.6

1.3

3.4

0.5

not fire

1

2

6

2012

29

61

13

1.3

64.4

4.1

7.6

1

3.9

0.4

not fire

2

3

6

2012

26

82

22

13.1

47.1

2.5

7.1

0.3

2.7

0.1

not fire

3

4

6

2012

25

89

13

2.5

28.6

1.3

6.9

0

1.7

0

not fire

4

5

6

2012

27

77

16

0

64.8

3

14.2

1.2

3.9

0.5

not fire

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

242

26

9

2012

30

65

14

0

85.4

16

44.5

4.5

16.9

6.5

fire

243

27

9

2012

28

87

15

4.4

41.1

6.5

8

0.1

6.2

0

not fire

244

28

9

2012

27

87

29

0.5

45.9

3.5

7.9

0.4

3.4

0.2

not fire

245

29

9

2012

24

54

18

0.1

79.7

4.3

15.2

1.7

5.1

0.7

not fire

246

30

9

2012

24

64

15

0.2

67.3

3.8

16.5

1.2

4.8

0.5

not fire

244 rows × 14 columns

</div>

 

#由于每个样本的年份都一样,对整个数据集没有太大的影响,因此可以将年份那一列删掉
del data['year']
data

print(data.isnull())  #没有找到缺失值,无需处理
day  month  Temperature     RH     Ws  Rain    FFMC    DMC     DC  \
0    False  False        False  False  False  False  False  False  False   
1    False  False        False  False  False  False  False  False  False   
2    False  False        False  False  False  False  False  False  False   
3    False  False        False  False  False  False  False  False  False   
4    False  False        False  False  False  False  False  False  False   
..     ...    ...          ...    ...    ...    ...    ...    ...    ...   
242  False  False        False  False  False  False  False  False  False   
243  False  False        False  False  False  False  False  False  False   
244  False  False        False  False  False  False  False  False  False   
245  False  False        False  False  False  False  False  False  False   
246  False  False        False  False  False  False  False  False  False   

       ISI    BUI    FWI  Classes    
0    False  False  False      False  
1    False  False  False      False  
2    False  False  False      False  
3    False  False  False      False  
4    False  False  False      False  
..     ...    ...    ...        ...  
242  False  False  False      False  
243  False  False  False      False  
244  False  False  False      False  
245  False  False  False      False  
246  False  False  False      False  

[244 rows x 13 columns]

(2)分离出仅含特征列的部分作为 X 和仅含目标列的部分作为 Y

X = data.iloc[:,0:12]
Y = data.iloc[:,-1]
#整理目标列:
s=Y.values
for i in range(len(s)):
    s[i] = s[i].replace(' ','')
print(s)
['notfire' 'notfire' 'notfire' 'notfire' 'notfire' 'fire' 'fire' 'fire'
 'notfire' 'notfire' 'fire' 'fire' 'notfire' 'notfire' 'notfire' 'notfire'
 'notfire' 'notfire' 'notfire' 'notfire' 'fire' 'notfire' 'fire' 'fire'
 'fire' 'fire' 'fire' 'fire' 'notfire' 'fire' 'notfire' 'notfire'
 'notfire' 'notfire' 'fire' 'fire' 'notfire' 'fire' 'notfire' 'notfire'
 'notfire' 'notfire' 'notfire' 'notfire' 'notfire' 'notfire' 'fire' 'fire'
 'fire' 'fire' 'fire' 'notfire' 'notfire' 'notfire' 'fire' 'fire' 'fire'
 'fire' 'fire' 'fire' 'fire' 'notfire' 'notfire' 'notfire' 'fire' 'fire'
 'fire' 'fire' 'notfire' 'fire' 'fire' 'fire' 'notfire' 'fire' 'fire'
 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire'
 'fire' 'fire' 'fire' 'fire' 'fire' 'notfire' 'notfire' 'notfire'
 'notfire' 'notfire' 'notfire' 'fire' 'notfire' 'notfire' 'notfire'
 'notfire' 'notfire' 'notfire' 'notfire' 'notfire' 'notfire' 'notfire'
 'notfire' 'fire' 'fire' 'fire' 'fire' 'fire' 'notfire' 'notfire'
 'notfire' 'notfire' 'notfire' 'fire' 'notfire' 'notfire' 'notfire'
 'notfire' 'notfire' 'notfire' 'notfire' 'notfire' 'fire' 'fire' 'notfire'
 'notfire' 'fire' 'fire' 'fire' 'notfire' 'notfire' 'notfire' 'notfire'
 'notfire' 'notfire' 'notfire' 'notfire' 'fire' 'notfire' 'notfire' 'fire'
 'fire' 'fire' 'fire' 'fire' 'fire' 'notfire' 'notfire' 'fire' 'fire'
 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'notfire' 'notfire' 'fire'
 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire'
 'fire' 'notfire' 'notfire' 'notfire' 'notfire' 'fire' 'fire' 'fire'
 'fire' 'notfire' 'fire' 'fire' 'fire' 'fire' 'notfire' 'notfire' 'fire'
 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire'
 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'fire' 'notfire'
 'fire' 'fire' 'fire' 'notfire' 'notfire' 'fire' 'notfire' 'notfire'
 'notfire' 'fire' 'fire' 'fire' 'notfire' 'notfire' 'fire' 'fire' 'fire'
 'fire' 'fire' 'fire' 'fire' 'fire' 'notfire' 'fire' 'fire' 'fire'
 'notfire' 'notfire' 'fire' 'notfire' 'notfire' 'notfire' 'notfire']

 

#使用训练好的LabelEncoder对原数据进行编码,notfire为1.fire为0
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y=le.fit_transform(s)            
y

 

array([1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
       0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1,
       1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
       0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
       0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0,
       0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0,
       0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
       1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1,
       0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1,
       1, 1])

 

y= pd.DataFrame(y)
#使用train_test_split函数自动随机划分训练集与测试集(70%和 30%)
x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=1)
#x_train,x_test,y_train,y_test
#查看训练集和测试集的大小
x_train.shape, x_test.shape, y_train.shape,y_test.shape

 

((170, 12), (74, 12), (170, 1), (74, 1))

 

(3)标准化处理

使不同维度之间的特征在数值上有一定比较性,可以大大提高分类器的准确性。

#对X进行标准化处理,让模型更拟合
scaler = StandardScaler().fit(x_train)
x_train = pd.DataFrame(scaler.transform(x_train))
x_train

 


 

.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}

</style>


 

0

1

2

3

4

5

6

7

8

9

10

11

0

1.693550

-0.377923

-0.338241

1.164128

-0.203369

-0.414083

0.508256

1.099453

1.786169

-0.022055

1.423974

0.490624

1

-0.549241

1.406713

-0.622900

1.027785

2.027127

0.621124

-1.406602

-1.043440

-0.895966

-0.921917

-1.024626

-0.941239

2

1.221384

-1.270241

1.085051

0.005213

0.168381

-0.414083

0.679098

0.132734

-0.347347

0.552856

-0.045186

0.325409

3

-0.667282

1.406713

-0.907558

0.823271

-0.203369

0.218544

-1.335418

-0.817872

-0.900170

-0.996906

-0.870714

-0.941239

4

1.457467

0.514395

0.515734

0.141556

0.168381

-0.414083

0.792993

2.847602

3.350048

0.627845

3.207954

1.757272

...

...

...

...

...

...

...

...

...

...

...

...

...

165

0.040967

-1.270241

-0.907558

1.709500

-0.203369

-0.184037

-2.196748

-0.858152

-0.904374

-1.146882

-0.905694

-0.968775

166

-0.431199

0.514395

0.800393

-0.744673

-0.946867

-0.241548

0.216400

0.060230

0.506060

-0.571971

0.255642

-0.404291

167

0.395092

-1.270241

-0.053583

0.346070

-0.575118

2.173935

-0.972378

-0.842040

-0.900170

-0.946913

-0.898698

-0.927471

168

0.749217

1.406713

0.231076

0.141556

-0.946867

-0.414083

0.757401

0.906109

1.161879

0.577852

1.074174

0.903661

169

-0.903366

-0.377923

0.231076

0.414242

1.283628

-0.414083

0.522493

-0.189505

-0.025743

0.302895

-0.115146

0.118890

170 rows × 12 columns

</div>

 

scaler = StandardScaler().fit(x_test)
x_test = pd.DataFrame(scaler.transform(x_test))
x_test

 


 

.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}

</style>


 

0

1

2

3

4

5

6

7

8

9

10

11

0

-0.943092

0.304017

-0.034882

0.460196

0.195027

-0.343850

0.637408

0.101718

0.070002

0.167530

0.101785

0.151281

1

1.470656

1.241402

-2.099869

0.132749

-0.132973

-0.263328

-0.655240

-0.859719

-0.610651

-0.782701

-0.792830

-0.818248

2

0.840982

0.304017

0.739489

-1.569978

-0.132973

-0.343850

1.014430

3.043550

2.171333

1.648122

2.821703

2.594495

3

-1.572765

-1.570753

-0.034882

0.591175

-1.116970

-0.062024

-1.341959

-0.966545

-0.786645

-0.915292

-0.937123

-0.857029

4

1.365710

0.304017

0.739489

-0.915083

0.851025

-0.343850

0.879779

3.281855

3.712874

1.714418

3.723532

3.021087

...

...

...

...

...

...

...

...

...

...

...

...

...

69

-0.943092

-0.633368

1.513859

-1.242530

-0.788971

-0.142546

0.536420

-0.103717

-0.209892

-0.141848

-0.150727

-0.210676

70

-0.838146

1.241402

-0.551129

0.722154

0.523026

0.018498

-1.012064

-0.958327

-0.782404

-0.804800

-0.922694

-0.831175

71

0.631091

-0.633368

-0.034882

-0.915083

0.851025

-0.343850

0.974035

2.460114

0.949974

1.869106

2.035307

2.400589

72

0.945928

-0.633368

1.771983

0.132749

-2.100968

0.139281

-0.217625

-0.210543

-0.623373

-0.804800

-0.316664

-0.792393

73

-1.257928

1.241402

-0.809252

0.722154

0.523026

-0.303589

-0.581182

-1.015849

-0.627614

-0.738505

-0.929908

-0.818248

74 rows × 12 columns

</div>

 

2. 构建逻辑回归模型

简单易懂,易于实施,训练高效;当数据集线性可分时表现良好;对于较小的数据集具有良好的准确性

from sklearn.linear_model import LogisticRegression
model_logic = LogisticRegression(max_iter=10000).fit(x_train, y_train)
#查看训练结果
print(model_logic.score(x_train,y_train))
#查看测试结果
print(model_logic.score(x_test,y_test))
0.9705882352941176
0.9054054054054054
D:\Anoconda\lib\site-packages\sklearn\utils\validation.py:63: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  return f(*args, **kwargs)

预测结果及分类准确率

#测试集预测结果
y_pred=model_logic.predict(x_test)
y_pred
y_pred= pd.DataFrame(y_pred)
#真实结果 
y_true=y_test.reset_index(drop=True)
y_true

 


 

.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}

</style>


 

0

0

0

1

1

2

0

3

1

4

0

...

...

69

0

70

1

71

0

72

1

73

1

74 rows × 1 columns

</div>

 

#train_accu正确分类样本数
train_accu = np.equal(y_pred,y_true)
t=np.sum(train_accu!=0)
t[0]

 

67

 

#计算模型在测试集上的分类准确率
t[0]/len(y_test)

 

0.9054054054054054

 

3. 构建决策树模型

3.1 构建决策树模型

3.1.1 分别取分裂节点为“gini”基尼指标和“entropy”信息增益,构建决策树模型并训练,查看二者指标模型是否有区别,并设置树深为5
#gini指标的决策树模型
dt_gini = DecisionTreeClassifier(criterion='gini',max_depth=5,random_state=0)
dt_gini = dt_gini.fit(x_train,y_train)   #用训练集进行训练,调用该对象的训练方法,接收两个参数:训练数据集及其样本标签
#entropy指标的决策树模型
dt_entropy = DecisionTreeClassifier(criterion='entropy',max_depth=5,random_state=0)
dt_entropy = dt_entropy.fit(x_train,y_train)
#查看两者的模型参数
dt_gini,dt_entropy
#查看特征系数,系数反映每个特征的影响力,越大表示该特征在分类中起到的作用越大
print(dt_gini.feature_importances_)
[0.         0.         0.         0.00382647 0.         0.
 0.97248796 0.         0.         0.02368557 0.         0.        ]
3.1.2 查看训练的预测结果
#Gini指标
answer = dt_gini.predict(x_train)
score_ = dt_gini.score(x_train,y_train)
print(answer)   #分别输出预测的和真实的,进行比较
print(y_train.values)
print(score_)
#entropy指标
answer = dt_entropy.predict(x_train)
score_ = dt_entropy.score(x_train,y_train)
print(answer)   #分别输出预测的和真实的,进行比较
print(y_train.values)
print(score_)
[0 1 0 1 0 1 0 1 0 0 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0
 1 0 1 1 0 1 1 1 0 1 0 0 0 0 0 0 1 0 1 1 0 0 1 0 1 1 0 0 0 0 0 0 0 1 1 0 0
 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 1 1 0 1 0 1 1 0 0 0 1 1 0
 0 0 1 0 0 1 0 1 0 0 0 0 0 1 1 1 1 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 1 1 0 0 0
 0 1 0 0 1 0 1 0 1 0 0 1 1 0 0 0 0 1 1 1 0 0]
[[0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [0]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [0]
 [1]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [0]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [1]
 [0]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [0]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [1]
 [1]
 [1]
 [0]
 [1]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [1]
 [1]
 [1]
 [0]
 [0]]
1.0
[0 1 0 1 0 1 0 1 0 0 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0
 1 0 1 1 0 1 1 1 0 1 0 0 0 0 0 0 1 0 1 1 0 0 1 0 1 1 0 0 0 0 0 0 0 1 1 0 0
 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 1 1 0 1 0 1 1 0 0 0 1 1 0
 0 0 1 0 0 1 0 1 0 0 0 0 0 1 1 1 1 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 1 1 0 0 0
 0 1 0 0 1 0 1 0 1 0 0 1 1 0 0 0 0 1 1 1 0 0]
[[0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [0]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [0]
 [1]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [0]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [1]
 [0]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [0]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [1]
 [1]
 [1]
 [0]
 [1]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [1]
 [0]
 [0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [0]
 [1]
 [1]
 [1]
 [0]
 [0]]
1.0

结果:可以看出分裂节点为Gini指标和entropy指标的模型对训练的数据进行测试后,其结果都为1.0,准确率都为100%

3.1.3 查看测试结果
# gini指标
y_gini_pre = dt_gini.predict(x_test)  #调用该对象的测试方法,接收一个参数:测试数据集
score_gini = dt_gini.score(x_test,y_test)   #调用该对象的准确率方法,接收两个参数:测试数据集及其样本标签,返回测试集样本映射到指定分类标记上的准确率
#输出
print("Gini测试结果:",y_gini_pre)  
print("正确结果:",y_test.values)
print("正确率:",score_gini)

# entropy指标
y_entropy_pre = dt_entropy.predict(x_test)  #调用该对象的测试方法,接收一个参数:测试数据集
score_entropy = dt_entropy.score(x_test,y_test)   #调用该对象的准确率方法,接收两个参数:测试数据集及其样本标签,返回测试集样本映射到指定分类标记上的准确率
#输出
print("entropy测试结果:",y_entropy_pre)  
print("正确结果:",y_test.values)
print("正确率:",score_entropy)
Gini测试结果: [0 1 0 1 0 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 1 0 1 1 0 0 1 0 1 1 0 1 1 0 0 1 1
 1 0 0 1 1 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1]
正确结果: [[0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [1]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [1]
 [0]
 [1]
 [1]
 [1]
 [1]
 [0]
 [1]
 [1]
 [1]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [1]
 [0]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [0]
 [0]
 [0]
 [1]
 [0]
 [1]
 [1]]
正确率: 0.9324324324324325
entropy测试结果: [0 1 0 1 0 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 1 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1
 1 0 0 1 1 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1]
正确结果: [[0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [0]
 [0]
 [1]
 [1]
 [0]
 [1]
 [0]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [0]
 [1]
 [1]
 [1]
 [0]
 [1]
 [1]
 [1]
 [1]
 [0]
 [1]
 [1]
 [1]
 [0]
 [1]
 [1]
 [0]
 [0]
 [0]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [1]
 [0]
 [1]
 [0]
 [0]
 [0]
 [0]
 [0]
 [1]
 [0]
 [0]
 [0]
 [1]
 [0]
 [1]
 [1]]
正确率: 0.8918918918918919

结果:由输出可以看出,Gini指标的测试误差大概为93%,而entropy指标的测试误差为89%,说明此数据集对gini指标的模型具有较好的泛化能力。使用决策树分类后,说明本例的决策树对训练集的规则吸收的很好,但是预测性稍微差点,仅有0.9的准确率。

3.2 数据可视化

#提取出列名,为决策树画图做准备
feature_names = pd.DataFrame(X).columns.values 
feature_names 
target_name = [] 
for i in Y.values:
    if i not in target_name:
        target_name.append(i)
print(target_name)
plt.figure(figsize=(25,30))   #设置图形大小宽为25英寸,高为30英寸
#gini模型
plot_tree(dt_gini,filled = True,feature_names = feature_names, class_names=target_name)    #设置自动填充颜色
['notfire', 'fire']

 

 

[Text(398.57142857142856, 1467.72, 'FFMC <= 0.131\ngini = 0.482\nsamples = 170\nvalue = [101, 69]\nclass = notfire'),
 Text(199.28571428571428, 1141.56, 'gini = 0.0\nsamples = 67\nvalue = [0, 67]\nclass = fire'),
 Text(597.8571428571429, 1141.56, 'ISI <= -0.559\ngini = 0.038\nsamples = 103\nvalue = [101, 2]\nclass = notfire'),
 Text(398.57142857142856, 815.4000000000001, 'gini = 0.0\nsamples = 1\nvalue = [0, 1]\nclass = fire'),
 Text(797.1428571428571, 815.4000000000001, ' RH <= 1.266\ngini = 0.019\nsamples = 102\nvalue = [101, 1]\nclass = notfire'),
 Text(597.8571428571429, 489.24, 'gini = 0.0\nsamples = 96\nvalue = [96, 0]\nclass = notfire'),
 Text(996.4285714285713, 489.24, 'FFMC <= 0.277\ngini = 0.278\nsamples = 6\nvalue = [5, 1]\nclass = notfire'),
 Text(797.1428571428571, 163.08000000000015, 'gini = 0.0\nsamples = 1\nvalue = [0, 1]\nclass = fire'),
 Text(1195.7142857142858, 163.08000000000015, 'gini = 0.0\nsamples = 5\nvalue = [5, 0]\nclass = notfire')]

 

 

#结果:从图中可以看出根节点的信息增益gini的值最大,一直分类直到为0.此时为叶子节点。而samples属性统计出它应用于多少个训练样本实例,从一开始
#的170个逐渐减少。value属性告诉这个节点对于每一个类别的样例有多少个。

3.3 绘制决策树模型的学习曲线

#对gini指标和entropy指标的模型绘制学习曲线,树深从1到30
test1 = []  #保存gini指标的每一次训练后的测试结果
test2 = []  #保存entropy指标的每一次训练后的测试结果
for i in range(30):
    clf_gini = DecisionTreeClassifier(max_depth=i+1,criterion='gini',random_state=30,splitter='random')
    clf_entropy = DecisionTreeClassifier(max_depth=i+1,criterion='entropy',random_state=30,splitter='random')
    clf_gini = clf_gini.fit(x_train,y_train)   #训练模型
    clf_entropy = clf_entropy.fit(x_train,y_train)
    score1 = clf_gini.score(x_train,y_train)   #计算测试结果
    score2 = clf_entropy.score(x_train,y_train)
    test1.append(score1)   #gini指标模型的每一次测试结果都存到test1中
    test2.append(score2)   #entropy指标模型的每一次测试结果都存到test2中

#画图
plt.title('Gini')
plt.plot(range(1,31),test1,color='red',label='Gini')      #定义gini指标模型的图形的横轴范围在30以内,曲线颜色为红色,命名为gini
plt.xlabel('max_depth')                                   #命名x轴为max_depth
plt.ylabel('training accuracy')                           #命名y轴为training accuracy


plt.title('entropy')
plt.plot(range(1,31),test2,color='blue',label='entropy')   #定义entropy指标模型的图形的横轴范围在30以内,曲线颜色为蓝色,命名为entropy
plt.xlabel('max_depth')                                   #命名x轴为max_depth
plt.ylabel('training accuracy')                           #命名y轴为training accuracy

plt.legend()                                              #创建图例
plt.show()                                                #展示图形

结果:Gini指标模型比entropy得要好一点。

4.模型评估与优化

4.1 查看模型各项指标

(1)查看逻辑回归指标

cm=confusion_matrix(y_test, y_pred,labels=[1,0])
cm

 

array([[30,  7],
       [ 0, 37]], dtype=int64)

 

from sklearn.metrics import confusion_matrix
tn, fp, fn, tp = confusion_matrix(y_test, y_pred,labels=[0,1]).ravel()
print(tn,fp,fn,tp)
𝑎𝑐𝑐𝑢𝑟𝑎𝑐𝑦 = (tn+tp)/(tn+tp+fn+fp)
trp = (tp)/(tp+fn)
fpr = (fp)/(tn+fp)
tpr = tp / (tp + fp)
print("准确率为:{}%".format(accuracy*100))
print("查全率为:{}%".format(trp*100))
print("假正率为:{}%".format(fpr*100))
print("精确率为:{}%".format(tpr*100))
37 0 7 30
准确率为:90.54054054054053%
查全率为:81.08108108108108%
假正率为:0.0%
精确率为:100.0%

 

import seaborn as sn
df_cm = pd.DataFrame(cm)
df_cm
#annot = True 显示数字 ,fmt参数不使用科学计数法进行显示
ax = sn.heatmap(df_cm,annot=True,fmt='.20g')
ax.set_title('LogisticRegression') #标题
ax.set_xlabel('predict') #x轴
ax.set_ylabel('true') #y轴

 

Text(33.0, 0.5, 'true')

 

结果:通过各项指标可以看出准确率能够达到90%,而精确率能达到100%,假正率为0,说明此模型对所有正例都能正确预测。

(2)查看gini指标的决策树模型的指标

#计算预测值
gini_pre = dt_gini.predict(x_test)
gini_pre
#输出混淆矩阵
cm = confusion_matrix(y_test,gini_pre,labels=[0,1])
print(cm)
tn,fp,fn,tp = cm.ravel()
print(tp,tn,fp,fn)
#计算模型的准确率
accuracy = (tp + tn) / (tp + tn + fp + fn)   
#计算模型的查全率
tpr = tp / (tp + fn)
#计算模型的假正率
fpr = fp / (fp + tn)
#计算模型的精确率
tpr = tp / (tp + fp)
print("准确率为:{}%".format(accuracy*100))   #能正确预测的概率,(有100个正例,只能预测成功50个为正例)
print("查全率为:{}%".format(tpr*100))        #有89个正例就预测成功89个正例,(可能会将一个反例预测成正例)
print("假正率为:{}%".format(fpr*100))
print("精确率为:{}%".format(tpr*100))
[[37  0]
 [ 5 32]]
32 37 0 5
准确率为:93.24324324324324%
查全率为:100.0%
假正率为:0.0%
精确率为:100.0%

(3)查看entropy指标的决策树模型的指标

#计算预测值
entropy_pre = dt_entropy.predict(x_test)
entropy_pre
#输出混淆矩阵
cm = confusion_matrix(y_test,entropy_pre,labels=[0,1])
print(cm)

tn,fp,fn,tp = cm.ravel()
print(tp,tn,fp,fn)
#计算模型的准确率
accuracy = (tp + tn) / (tp + tn + fp + fn)   
#计算模型的查全率
tpr = tp / (tp + fn)
#计算模型的假正率
fpr = fp / (fp + tn)
#计算模型的精确(真正率)率
tpr = tp / (tp + fp)
print("准确率为:{}%".format(accuracy*100))   #能正确预测的概率,(有100个正例,只能预测成功50个为正例)
print("查全率为:{}%".format(tpr*100))        #有89个正例就预测成功89个正例,(可能会将一个反例预测成正例)
print("假正率为:{}%".format(fpr*100))
print("精确率为:{}%".format(tpr*100))
[[37  0]
 [ 8 29]]
29 37 0 8
准确率为:89.1891891891892%
查全率为:100.0%
假正率为:0.0%
精确率为:100.0%

结果:通过使用混淆矩阵来计算模型的准确率和查全率等,可以看出此决策树对数据集训练后,Gini指标能正确预测的概率为93%,#而entropy得为89%,模型预测能力较好。

(3)用10折交叉验证法对逻辑回归模型和决策树模型的分类效果进行评估

为什么用交叉验证法?交叉验证用于评估模型的预测性能,尤其是训练好的模型在新数据上的表现,可以在一定程度上减小过拟合。

#已使用“留出法”划分好数据集
result1 = cross_val_score(dt_gini,X,Y,cv = 10)    #传入指定的gini指标学习器,数据集中的样本集X和标签集Y,设置cv为10
print("10折交叉验证结果_gini指标的决策树:",result1)
result2 = cross_val_score(dt_entropy,X,Y,cv = 10)    #传入指定的entropy指标的学习器,数据集中的样本集X和标签集Y,设置cv为10
print("10折交叉验证结果_entropy指标的决策树:",result2)
result3 = cross_val_score(model_logic,X,Y,cv = 10)    #传入指定的entropy指标的学习器,数据集中的样本集X和标签集Y,设置cv为10
print("10折交叉验证结果_逻辑回归:",result3)

#将10折交叉验证结果可视化
plt.figure(figsize=(15,5))
plt.subplot(1,3,1)
plt.title('Gini')
plt.plot(range(10),result1,color='red')      #定义gini指标模型的图形的横轴范围在10以内,曲线颜色为红色,命名为gini                         #命名y轴为training accuracy

plt.subplot(1,3,2)
plt.title('entropy')
plt.plot(range(10),result2,color='blue')  #定义entropy指标模型的图形的横轴范围在10以内,曲线颜色为蓝色,命名为entropy

plt.subplot(1,3,3)
plt.title('model_logic')
plt.plot(range(10),result2,color='green')  #定义逻辑回归模型的图形的横轴范围在10以内,曲线颜色为绿色,命名为model_logic

plt.legend()                                              #创建图例
plt.show()
10折交叉验证结果_gini指标的决策树: [0.96       0.96       0.92       0.92       1.         1.
 1.         1.         1.         0.95833333]
10折交叉验证结果_entropy指标的决策树: [0.96       0.96       0.92       1.         1.         0.95833333
 1.         1.         0.95833333 0.95833333]
No handles with labels found to put in legend.
10折交叉验证结果_逻辑回归: [0.96       1.         0.96       0.96       1.         0.875
 1.         1.         0.91666667 1.        ]

 

结果:但是波动范围都在0.92 到 1不等,差距较大。由此可见决策树模型的预测性能的差距比逻辑回归的好一点。

4.2 使用正则化对逻辑回归分类器进行参数调优

param =  {'penalty':['l2','l1'],'C': [0.001, 0.01, 0.1],
        'class_weight':['balanced',None],'multi_class':['ovr'],'solver':['liblinear']}
gc = GridSearchCV(model_logic, param_grid=param, cv=10)                                                 
gc.fit(x_train, y_train.values.ravel())
print("在测试集上的准确率(得分):",gc.score(x_test,y_test))
print("交叉验证的最好结果:",gc.best_score_)
print("最佳参数组合:",gc.best_params_)
在测试集上的准确率(得分): 0.8918918918918919
交叉验证的最好结果: 0.9647058823529413
最佳参数组合: {'C': 0.1, 'class_weight': None, 'multi_class': 'ovr', 'penalty': 'l1', 'solver': 'liblinear'}

4.3 使用暴力搜索对决策树分类器进行参数调优

#构建一个没有选取任何分裂节点指标的决策树模型
dtc = DecisionTreeClassifier()
dtc.fit(x_train,y_train)

param1 =  {'criterion':['gini','entropy'],'max_features': [0.1,0.2,0.5,0.8,1],
        'splitter':['best','random'],'min_samples_split':[2,4,6,8]}
clf1 = GridSearchCV(dtc, param1, cv=10)                                                 
clf1.fit(x_train, y_train)
print("在测试集上的准确率(得分):",clf1.score(x_test,y_test))
print("交叉验证的最好结果:",clf1.best_score_)
print("最好的参数组合为:",clf1.best_params_)
在测试集上的准确率(得分): 0.8918918918918919
交叉验证的最好结果: 0.9882352941176471
最好的参数组合为: {'criterion': 'gini', 'max_features': 0.5, 'min_samples_split': 8, 'splitter': 'best'}