经过前面的两章的知识点的学习,我可以对数数据的本身进行处理,比如数据本身的增删查补,还可以做必要的清洗工作。那么下面我们就要开始使用我们前面处理好的数据了。这一章我们要做的就是使用数据,我们做数据分析的目的也就是,运用我们的数据以及结合我的业务来得到某些我们需要知道的结果。那么分析的第一步就是建模,搭建一个预测模型或者其他模型;我们从这个模型的到结果之后,我们要分析我的模型是不是足够的可靠,那我就需要评估这个模型。今天我们学习建模,下一节我们学习评估。
我们拥有的泰坦尼克号的数据集,那么我们这次的目的就是,完成泰坦尼克号存活预测这个任务。载入这些库,如果缺少某些库,请安装他们:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import Image
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rcParams['figure.figsize'] = (10, 6) # 设置输出图片大小
【思考】这些库的作用是什么呢?你需要查一查
clear_data = pd.read_csv('./clear_data.csv')
train = pd.read_csv('./train.csv')
clear_data.head()
train.head()
输出:
clear_data:
train:
【思考】数据集哪些差异会导致模型在拟合数据是发生变化
1. 样本数多少,有限的训练数据可能会导致训练出的模型出现过度拟合的现象,模型的泛化能力较差。
2. 特征值的多少。
3. 异常值、噪音干扰过大,让模型过分记住了噪音的特征,忽略了正常值输入输出的关系。
4. 训练集和测试集的特征分布是否一致。
这里使用留出法划分数据集
【思考】
1. 划分数据集的方法:
X_train,X_test, y_train, y_test =sklearn.model_selection.train_test_split(train_data,train_target,test_size=0.4, random_state=0,stratify=y_train)
train_test_split详解 :sklearn的train_test_split()各函数参数含义解释(非常全) - The-Chosen-One - 博客园
https://blog.csdn.net/qq_38233659/article/details/101553277
2. 分割训练集与测试集步骤:(回顾之前数据处理的过程,重新对train进行数据清洗后用于建模)
(1) 首先,处理缺失值:
train['Age']=train['Age'].fillna(train['Age'].median())
train = train.drop(['Cabin'],axis=1)
train = train.dropna(subset=['Embarked'],axis=0)
(2)去除无关特征值:
train_clean = train.drop(['Name','Ticket','PassengerId'],axis=1)
(3)归一化处理:
Pclass=pd.get_dummies(train_clean['Pclass'],prefix='Pclass')
Sex=pd.get_dummies(train_clean['Sex'],prefix='Sex')
SibSp=pd.get_dummies(train_clean['SibSp'],prefix='SibSp')
Parch=pd.get_dummies(train_clean['Parch'],prefix='Parch')
Embarked=pd.get_dummies(train_clean['Embarked'],prefix='Embarked')
train_clean=pd.concat([train_clean.drop(['Pclass','Sex','SibSp','Parch','Embarked'],axis=1),Pclass,Sex,SibSp,Parch,Embarked],axis=1)
train_clean.head()
输出:
(4)数据标准化处理:
number = ['Age','Fare']
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
train_clean[number] = scaler.fit_transform(train_clean[number])
(5)分割训练集与测试集:
#方法一:用train_test_split()
from sklearn.model_selection import train_test_split
X = train_clean.drop(['Survived'],axis=1)
Y = train_clean['Survived']
train_x, test_x, train_y, test_y = train_test_split(X,Y,test_size=0.2,random_state=42)
#方法二:使用StratifiedShuffleSplit()
from sklearn.model_selection import StratifiedShuffleSplit
s = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42) #把数据集随机分,最后得到的训练集/测试集对是1组
for train_index, test_index in s.split(train_clean, train_clean["Survived"]):#需要分层抽样元原数据 和 需在此分层基础上的数据
strat_train_set = train_clean.loc[train_index]
strat_test_set = train_clean.loc[test_index]
for set in (strat_train_set, strat_test_set):
set.drop(["Survived"], axis=1, inplace=True)
【思考】什么情况下切割数据集的时候不用进行随机选取
数据集较大,样本分布较为均匀。
提示
LinearRegression
混淆sklearn.linear_model
sklearn.ensemble
1. 随机森林:
#建模
from sklearn.ensemble import RandomForestClassifier
forest_clf = RandomForestClassifier(random_state=42)
forest_clf.fit(train_x,train_y)
#输出:
RandomForestClassifier(random_state=42)
#查看训练集和测试集score:
print("Training set score: {:.2f}".format(forest_clf.score(train_x, train_y)))
print("Testing set score: {:.2f}".format(forest_clf.score(test_x, test_y)))
#输出:
Training set score: 0.98
Testing set score: 0.75
可以看出random forest在训练集上的分数高达0.98,而测试集仅有0.75,现更改参数n_estimators,max_depth:
forest_clf2 = RandomForestClassifier(n_estimators=100, max_depth=5)
forest_clf2.fit(train_x, train_y)
#输出:
RandomForestClassifier(max_depth=5)
#查看训练集和测试集的score:
print("Training set score: {:.2f}".format(forest_clf2.score(train_x, train_y)))
print("Testing set score: {:.2f}".format(forest_clf2.score(test_x, test_y)))
#输出:
Training set score: 0.85
Testing set score: 0.80
可以看出虽然在train上的score降低了,但在test上的score升高了。
2. 逻辑回归:
#公式:
LogisticRegression(
penalty='l2',
*,
dual=False,
tol=0.0001,
C=1.0,
fit_intercept=True,
intercept_scaling=1,
class_weight=None,
random_state=None,
solver='lbfgs',
max_iter=100,
multi_class='auto',
verbose=0,
warm_start=False,
n_jobs=None,
l1_ratio=None,
)
#建模
from sklearn.linear_model import LogisticRegression
lr_clf = LogisticRegression(random_state=42)
lr_clf.fit(train_x,train_y)
#输出:
LogisticRegression(random_state=42)
# 查看训练集和测试集score值
print("Training set score: {:.2f}".format(lr_clf.score(train_x, train_y)))
print("Testing set score: {:.2f}".format(lr_clf.score(test_x, test_y)))
#输出:
Training set score: 0.81
Testing set score: 0.81
可以看逻辑回归模型的score在train和test中都达到了0.81,现在更改参数c=100:
#调整参数
lr_clf = LogisticRegression(C=100,random_state=42)
lr_clf.fit(train_x,train_y)
#输出:
LogisticRegression(C=100, random_state=42)
# 查看训练集和测试集score值
print("Training set score: {:.2f}".format(lr_clf2.score(train_x, train_y)))
print("Testing set score: {:.2f}".format(lr_clf2.score(test_x, test_y)))
#输出:
Training set score: 0.81
Testing set score: 0.82
可以看逻辑回归模型的score在test中上升到了0.82。
1. 随机森林
#predict()
forest_predict = forest_clf.predict(train_x)
forest_predict[:10]
#输出:
array([1, 0, 0, 0, 0, 0, 0, 0, 0, 1], dtype=int64)
#predict_proba()
forest_pred_pr = forest_clf.predict_proba(train_x)
forest_pred_pr[:10]
#输出:
array([[0. , 1. ],
[0.9 , 0.1 ],
[0.96, 0.04],
[0.99, 0.01],
[1. , 0. ],
[0.8 , 0.2 ],
[1. , 0. ],
[1. , 0. ],
[1. , 0. ],
[0.38, 0.62]])
2. 逻辑回归
#predict()
lr_predict = lr_clf.predict(train_x)
lr_predict[:10]
#输出:
array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int64)
#predict_proba()
lr_pred_pr = lr_clf.predict_proba(train_x)
lr_pred_pr[:10]
#输出:
array([[0.05543158, 0.94456842],
[0.29285178, 0.70714822],
[0.9245138 , 0.0754862 ],
[0.79121241, 0.20878759],
[0.95074891, 0.04925109],
[0.58191983, 0.41808017],
[0.89122519, 0.10877481],
[0.91249951, 0.08750049],
[0.91249951, 0.08750049],
[0.54714094, 0.45285906]])
【思考】预测标签的概率对我们有什么帮助
predict_proba返回的是一个n行k列的数组,第i行第j列上的数值是模型预测第i个预测样本的标签为j的概率,所以每一行的和应该等于1。