文章目录
- 1. 鸢尾花数据集分类
- 使用袋外数据作为测试集
- 2.泰坦尼克号
1. 鸢尾花数据集分类
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
np.random.seed(42)
# 特征
iris_feature = '花萼长度', '花萼宽度', '花瓣长度', '花瓣宽度'
if __name__ == '__main__':
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
try:
data = pd.read_parquet('iris.parquet')
except:
data = pd.read_csv('DATA/iris.data')
data.to_parquet('iris.parquet')
X = data.iloc[:, :4]
y = pd.Categorical(data.iloc[:, 4]).codes
# 特征组合-共6个
feature_iris = [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]
plt.figure(facecolor='#FFFFFF', figsize=(10, 9))
for i, pair in enumerate(feature_iris):
X_pair = X.iloc[:, pair]
# 随机森林
clf = RandomForestClassifier(n_estimators=200, criterion='entropy', max_depth=3)
clf.fit(X_pair, y)
# 预测
y_hat = clf.predict(X_pair)
# 统计结果
c = np.count_nonzero(y_hat == y)
print('特征 :', iris_feature[pair[0]], '+', iris_feature[pair[1]])
print('\t预测正确的数目为:', c)
print('\t预测准确率为:%.2f%%' % (100 * (float(c) / float(len(y)))))
# 画决策边界图
M, N = 50, 50
x1_min, x1_max = min(X_pair.iloc[:, 0]) - 0.05, max(X_pair.iloc[:, 0]) + 0.05
x2_min, x2_max = min(X_pair.iloc[:, 1]) - 0.05, max(X_pair.iloc[:, 1]) + 0.05
t1 = np.linspace(x1_min, x1_max, M)
t2 = np.linspace(x2_min, x2_max, N)
# 生成网格点坐标矩阵
x1, x2 = np.meshgrid(t1, t2)
# 测试点
x_test = np.stack((x1.flat, x2.flat), axis=1)
y_test = clf.predict(x_test).reshape(x1.shape)
cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
plt.subplot(2, 3, i + 1)
plt.pcolormesh(x1,x2,y_test,shading='auto',cmap=cm_light)
# 画样本点
plt.scatter(X_pair.iloc[:, 0],X_pair.iloc[:,1],c=y,cmap=cm_dark,edgecolors='k')
plt.xlabel(iris_feature[pair[0]],fontsize=14)
plt.xlabel(iris_feature[pair[1]],fontsize=14)
plt.xlim(x1_min,x1_max)
plt.ylim(x2_min,x2_max)
plt.grid(b=True)
plt.tight_layout()
plt.suptitle('随机森林对鸢尾花数据集的特征组合的分类结果',fontsize=18)
plt.show()
运行结果
特征 : 花萼长度 + 花萼宽度
预测正确的数目为: 122
预测准确率为:81.88%
特征 : 花萼长度 + 花瓣长度
预测正确的数目为: 142
预测准确率为:95.30%
特征 : 花萼长度 + 花瓣宽度
预测正确的数目为: 144
预测准确率为:96.64%
特征 : 花萼宽度 + 花瓣长度
预测正确的数目为: 142
预测准确率为:95.30%
特征 : 花萼宽度 + 花瓣宽度
预测正确的数目为: 143
预测准确率为:95.97%
特征 : 花瓣长度 + 花瓣宽度
预测正确的数目为: 144
预测准确率为:96.64%
使用袋外数据作为测试集
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
np.random.seed(42)
# 特征
iris_feature = '花萼长度', '花萼宽度', '花瓣长度', '花瓣宽度'
if __name__ == '__main__':
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
try:
data = pd.read_parquet('iris.parquet')
except:
data = pd.read_csv('DATA/iris.data')
data.to_parquet('iris.parquet')
X = data.iloc[:, :4]
y = pd.Categorical(data.iloc[:, 4]).codes
# 特征组合-共6个
feature_iris = [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]
plt.figure(facecolor='#FFFFFF', figsize=(10, 9))
for i, pair in enumerate(feature_iris):
X_pair = X.iloc[:, pair]
# 随机森林
clf = RandomForestClassifier(n_estimators=200, criterion='entropy', max_depth=3,oob_score=True)
clf.fit(X_pair, y)
print(clf.oob_score_,end='\t')
# 预测
y_hat = clf.predict(X_pair)
# 统计结果
c = np.count_nonzero(y_hat == y)
print('特征 :', iris_feature[pair[0]], '+', iris_feature[pair[1]],end='\t')
print('预测正确的数目为:', c,end='\t')
print('预测准确率为:%.2f%%' % (100 * (float(c) / float(len(y)))))
# 画决策边界图
M, N = 50, 50
x1_min, x1_max = min(X_pair.iloc[:, 0]) - 0.05, max(X_pair.iloc[:, 0]) + 0.05
x2_min, x2_max = min(X_pair.iloc[:, 1]) - 0.05, max(X_pair.iloc[:, 1]) + 0.05
t1 = np.linspace(x1_min, x1_max, M)
t2 = np.linspace(x2_min, x2_max, N)
# 生成网格点坐标矩阵
x1, x2 = np.meshgrid(t1, t2)
# 测试点
x_test = np.stack((x1.flat, x2.flat), axis=1)
y_test = clf.predict(x_test).reshape(x1.shape)
cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
plt.subplot(2, 3, i + 1)
plt.pcolormesh(x1,x2,y_test,shading='auto',cmap=cm_light)
# 画样本点
plt.scatter(X_pair.iloc[:, 0],X_pair.iloc[:,1],c=y,cmap=cm_dark,edgecolors='k')
plt.xlabel(iris_feature[pair[0]],fontsize=14)
plt.xlabel(iris_feature[pair[1]],fontsize=14)
plt.xlim(x1_min,x1_max)
plt.ylim(x2_min,x2_max)
plt.grid(b=True)
plt.tight_layout()
plt.suptitle('随机森林对鸢尾花数据集的特征组合的分类结果',fontsize=18)
plt.show()
0.7583892617449665 特征 : 花萼长度 + 花萼宽度 预测正确的数目为: 122 预测准确率为:81.88%
0.9261744966442953 特征 : 花萼长度 + 花瓣长度 预测正确的数目为: 142 预测准确率为:95.30%
0.9530201342281879 特征 : 花萼长度 + 花瓣宽度 预测正确的数目为: 144 预测准确率为:96.64%
0.9261744966442953 特征 : 花萼宽度 + 花瓣长度 预测正确的数目为: 142 预测准确率为:95.30%
0.9463087248322147 特征 : 花萼宽度 + 花瓣宽度 预测正确的数目为: 143 预测准确率为:95.97%
0.959731543624161 特征 : 花瓣长度 + 花瓣宽度 预测正确的数目为: 144 预测准确率为:96.64%
当max_depth=10时,出现过拟合
0.7046979865771812 特征 : 花萼长度 + 花萼宽度 预测正确的数目为: 138 预测准确率为:92.62%
0.9395973154362416 特征 : 花萼长度 + 花瓣长度 预测正确的数目为: 148 预测准确率为:99.33%
0.9261744966442953 特征 : 花萼长度 + 花瓣宽度 预测正确的数目为: 145 预测准确率为:97.32%
0.9395973154362416 特征 : 花萼宽度 + 花瓣长度 预测正确的数目为: 147 预测准确率为:98.66%
0.9194630872483222 特征 : 花萼宽度 + 花瓣宽度 预测正确的数目为: 146 预测准确率为:97.99%
0.9463087248322147 特征 : 花瓣长度 + 花瓣宽度 预测正确的数目为: 148 预测准确率为:99.33%
2.泰坦尼克号
数据集下载-提取码:foib 变量说明
survival : 是否活着 (0 = No; 1 = Yes)
pclass : Passenger Class (1 = 1st; 2 = 2nd; 3 = 3rd)
name :名字
sex : 性别
age :年龄
sibsp :配偶的人数
parch:父母子女人数
ticket:机票编号
fare :乘客票价
cabin:船舱
embarked:登船的港口(C =瑟堡; Q =皇后镇; S =南安普敦)
特别说明:
Pclass是社会经济地位(SES)状态
1st〜上层; 2nd〜中间; 3〜下
年龄以年为单位; 如果年龄小于一(1),则为分数
#!usr/bin/env python
# -*- coding:utf-8 -*-
"""
@author: admin
@file: 泰坦尼克号.py
@time: 2021/01/25
@desc:
"""
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import csv
import xgboost as xgb
# 读取数据,并数据处理
def loaddata(filename, is_train):
# 输出显示设置
pd.set_option('display.width', 200)
# 加载数据
data = pd.read_csv(filename, header=0, index_col=0)
# 查看数据前几行
print(data.head())
# 显示数据整体情况-数据快速统计摘要
print('data.describe =\n', data.describe())
# 将空格转换为空值
data.replace(to_replace=' ', value=np.NAN, inplace=True)
# 数据的空值统计
print(data.isnull().sum())
# 将类别数据转换成数值数据-字典映射
data['Sex'] = data['Sex'].map({'female': 0, 'male': 1}).astype(int)
# 补充船票价格缺失值
# print(len(data['Fare'][data['Fare'] == 0])) # 15
if len(data.Fare[data['Fare'] == 0]) > 0:
fare = np.zeros(3)
for i in range(0, 3):
fare[i] = data[data.Pclass == i + 1]['Fare'].dropna().median()
print(fare)
# 填充对应等级船票价格
for i in range(0, 3):
data.loc[(data.Fare.isnull()) & (data.Pclass == i + 1), 'Fare'] = fare[i]
# 年龄处理
# 一种是常见的用均值代替缺失值
# mean_age = data['Age'].dropna().mean()
# data['Age'].fillna(mean_age, inplace=True)
# 使用随机森林预测年龄
if is_train:
print('随机森林开始预测年龄')
data_for_age = data[['Age', 'Survived', 'Fare', 'Parch', 'SibSp', 'Pclass']]
age_exist = data_for_age.loc[(data.Age.notnull())]
age_null = data_for_age.loc[(data.Age.isnull())]
print(age_exist)
print(age_null)
x = age_exist.iloc[:, 1:]
y = age_exist.iloc[:, 0]
clf = RandomForestRegressor(n_estimators=1000)
clf.fit(x, y)
age_hat = clf.predict(age_null.values[:, 1:])
# print(age_hat)
# 把预测的数据填充到Age列的空的那些行中
data.loc[(data.Age.isnull()), 'Age'] = age_hat
print('随机森林预测缺失年龄:--over--')
else:
# 如果是测试数据,则没有Survived这一项,
# 所以前面加一个is_train用来判段是测试数据还是训练数据
print('随机森林预测缺失年龄2:--start--')
data_for_age = data[['Age', 'Fare', 'Parch', 'SibSp', 'Pclass']]
age_exist = data_for_age.loc[(data.Age.notnull())] # 年龄不缺失的数据
age_null = data_for_age.loc[(data.Age.isnull())]
print(age_exist.isnull().sum())
x = age_exist.values[:, 1:]
y = age_exist.values[:, 0]
rfr = RandomForestRegressor(n_estimators=1000)
rfr.fit(x, y)
age_hat = rfr.predict(age_null.values[:, 1:])
# print age_hat
data.loc[(data.Age.isnull()), 'Age'] = age_hat
print('随机森林预测缺失年龄2:--over--')
# 起始城市
data.loc[(data.Embarked.isnull()), 'Embarked'] = 'S' # 保留缺失出发城市
# data['Embarked'] = data['Embarked'].map({'S': 0, 'C': 1, 'Q': 2, 'U': 0}).astype(int)
# print(data['Embarked'])
# 取出Embarked这一列的数据,pd.get_dummies表示获得出发城市的哑元,就是有什么值
embarked_data = pd.get_dummies(data.Embarked)
print('embarked_data = \n', embarked_data)
# 把所有出发城市拿出来,加上后缀,形成三个特征
embarked_data = embarked_data.rename(columns=lambda x: 'Embarked_' + str(x))
# 数据和这个新的特征组合在一起,形成新的数据
data = pd.concat([data, embarked_data], axis=1)
print(data.describe())
# 保存数据
data.to_csv('New_Data.csv')
# 把清洗后的数据提取出来作为x
x = data[['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked_C', 'Embarked_Q', 'Embarked_S']]
y = None
# 如果是训练集,提取y
if 'Survived' in data:
y = data['Survived']
# 转成对应的矩阵
x = np.array(x)
y = np.array(y)
# 平铺五行,让测试数据变得更多
# 可以显著提高准确率
x = np.tile(x, (5, 1))
y = np.tile(y, (5,))
if is_train:
return x, y
# print(data.index)
return x, data.index
# 输出结果
def write_result(c, c_type):
file_name = 'Titanic.test.csv'
x, passenger_id = loaddata(file_name, False)
if c_type == 3:
x = xgb.DMatrix(x)
y = c.predict(x)
y[y > 0.5] = 1
y[~(y > 0.5)] = 0
predictions_file = open("Prediction_%d.csv" % c_type, "w")
open_file_object = csv.writer(predictions_file)
open_file_object.writerow(["PassengerId", "Survived"])
open_file_object.writerows(zip(passenger_id, y))
predictions_file.close()
if __name__ == "__main__":
# 读取数据
x, y = loaddata('Titanic.train.csv', True)
# 数据集的分割,这里的test其实是验证数据
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=1)
# 逻辑回归
lr = LogisticRegression(penalty='l2')
lr.fit(x_train, y_train)
y_hat = lr.predict(x_test)
lr_acc = accuracy_score(y_test, y_hat)
write_result(lr, 1)
# 随机森林
rfc = RandomForestClassifier(n_estimators=100)
rfc.fit(x_train, y_train)
y_hat = rfc.predict(x_test)
rfc_acc = accuracy_score(y_test, y_hat)
write_result(rfc, 2)
# XGBoost
data_train = xgb.DMatrix(x_train, label=y_train)
data_test = xgb.DMatrix(x_test, label=y_test)
watch_list = [(data_test, 'eval'), (data_train, 'train')]
param = {'max_depth': 6, 'eta': 0.8, 'silent': 1, 'objective': 'binary:logistic'}
# 'subsample': 1, 'alpha': 0, 'lambda': 0, 'min_child_weight': 1}
bst = xgb.train(param, data_train, num_boost_round=100, evals=watch_list,
early_stopping_rounds=30, verbose_eval=True)
y_hat = bst.predict(data_test, ntree_limit=bst.best_ntree_limit)
write_result(bst, 3)
y_hat[y_hat > 0.5] = 1
y_hat[~(y_hat > 0.5)] = 0
xgb_acc = accuracy_score(y_test, y_hat)
print('Logistic回归:%.3f%%' % lr_acc)
print('随机森林:%.3f%%' % rfc_acc)
print('XGBoost:%.3f%%' % xgb_acc)
Logistic回归:0.797%
随机森林:0.983%
XGBoost:0.983%