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) # 设置输出图片大小
载入这些库,如果缺少某些库,请安装他们
#这一章新出现的库是ipython
#ipython shell是一个增强版的交互式python解释器,它的设计目的是在交互式计算和软件开发两个方面最大化的提高生产力。
#通过ipython可以对大部分python代码进行探索式的操作,例如使用试错法来练习和学习python中的函数,所以使用ipython将有助于提高你的工作效率。
#安装 ipython
!pip install ipython
%matplotlib inline
载入我们提供清洗之后的数据(clear_data.csv),大家也将原始数据载入(train.csv),说说他们有什么不同
clear_data =pd.read_csv('clear_data.csv')
clear_data.head(3)
PassengerId | Pclass | Age | SibSp | Parch | Fare | Sex_female | Sex_male | Embarked_C | Embarked_Q | Embarked_S | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 3 | 22.0 | 1 | 0 | 7.2500 | 0 | 1 | 0 | 0 | 1 |
1 | 1 | 1 | 38.0 | 1 | 0 | 71.2833 | 1 | 0 | 1 | 0 | 0 |
2 | 2 | 3 | 26.0 | 0 | 0 | 7.9250 | 1 | 0 | 0 | 0 | 1 |
#写入代码
train_data =pd.read_csv('train.csv')
train_data.head(3)
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
#写入代码
c_data.shape
(891, 11)
train_data.shape
(891, 12)
这里我的建模,并不是从零开始,自己一个人完成完成所有代码的编译。我们这里使用一个机器学习最常用的一个库(sklearn)来完成我们的模型的搭建
这里使用留出法划分数据集
train_test_split
train_test_split?
后回车即可看到要从clear_data.csv和train.csv中提取train_test_split()所需的参数
from sklearn.model_selection import train_test_split
# 一般先取出X和y后再切割,有些情况会使用到未切割的,这时候X和y就可以用,x是清洗好的数据,y是我们要预测的存活数据'Survived'
X = clear_data
y = train_data['Survived']
# 对数据集进行切割
#设置训练集为0.8
#设置random_state为整数
# random_state:是随机数的种子。
# 随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。
#比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, stratify=y, random_state=10)
# 查看数据形状
X_train.shape, X_test.shape
((712, 11), (179, 11))
LinearRegression
混淆sklearn.linear_model
sklearn.ensemble
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
# 默认参数逻辑回归模型
lr = LogisticRegression()
lr.fit(X_train, y_train)
LogisticRegression()
# 查看训练集和测试集score值
print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))
print("Testing set score: {:.2f}".format(lr.score(X_test, y_test)))
Training set score: 0.80
Testing set score: 0.80
# 调整参数后的逻辑回归模型
lr2 = LogisticRegression(C=100)
lr2.fit(X_train, y_train)
LogisticRegression(C=100)
print("Training set score: {:.2f}".format(lr2.score(X_train, y_train)))
print("Testing set score: {:.2f}".format(lr2.score(X_test, y_test)))
Training set score: 0.79
Testing set score: 0.80
# 默认参数的RandomForest分类模型
rfc = RandomForestClassifier()
rfc.fit(X_train, y_train)
RandomForestClassifier()
print("Training set score: {:.2f}".format(rfc.score(X_train, y_train)))
print("Testing set score: {:.2f}".format(rfc.score(X_test, y_test)))
Training set score: 1.00
Testing set score: 0.82
# 调整参数后的随机森林分类模型
#n_estimators :森林里(决策)树的数目
#max_features :寻找最佳分割时需要考虑的特征数目
rfc2 = RandomForestClassifier(n_estimators=100, max_depth=5)
rfc2.fit(X_train, y_train)
RandomForestClassifier(max_depth=5)
print("Training set score: {:.2f}".format(rfc2.score(X_train, y_train)))
print("Testing set score: {:.2f}".format(rfc2.score(X_test, y_test)))
Training set score: 0.86
Testing set score: 0.85
predict
能输出预测标签,predict_proba
则可以输出标签概率# 预测标签
pred = lr.predict(X_train)
pred1 = rfc.predict(X_train)
# 此时我们可以看到0和1的数组
print(pred[:10])
pred1[:10]
[1 0 1 1 0 0 0 0 0 0]
array([0, 0, 1, 1, 0, 0, 0, 1, 0, 0], dtype=int64)
# 预测标签概率
pred_proba = lr.predict_proba(X_train)
pred_proba1 = rfc.predict_proba(X_train)
print(pred_proba[:5])
pred_proba1[:5]
[[0.39896952 0.60103048]
[0.86503172 0.13496828]
[0.10722357 0.89277643]
[0.33815696 0.66184304]
[0.86736473 0.13263527]]
array([[0.93, 0.07],
[0.94, 0.06],
[0.05, 0.95],
[0.2 , 0.8 ],
[0.95, 0.05]])
加载下面的库
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from IPython.display import Image
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rcParams['figure.figsize'] = (10, 6) # 设置输出图片大小
任务:加载数据并分割测试集和训练集
# 一般先取出X和y后再切割,有些情况会使用到未切割的,这时候X和y就可以用,x是清洗好的数据,y是我们要预测的存活数据'Survived'
clear_data =pd.read_csv('clear_data.csv')
train_data =pd.read_csv('train.csv')
X = clear_data
y = train_data['Survived']
# 对数据集进行切割
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, stratify=y, random_state=10)
# 默认参数逻辑回归模型
lr = LogisticRegression()
lr.fit(X_train, y_train)
LogisticRegression()
# 调整参数后的逻辑回归模型
lr2 = LogisticRegression(C=100)
lr2.fit(X_train, y_train)
LogisticRegression(C=100)
#提示:交叉验证
Image('Snipaste_2020-01-05_16-37-56.png')
sklearn.model_selection
from sklearn.model_selection import cross_val_score
# k折交叉验证分数
scores = cross_val_score(lr2, X_train, y_train, cv=10)
scores
array([0.84722222, 0.80555556, 0.8028169 , 0.77464789, 0.77464789,
0.77464789, 0.83098592, 0.76056338, 0.77464789, 0.74647887])
# 平均交叉验证分数
print("Average cross-validation score: {:.2f}".format(scores.mean()))
Average cross-validation score: 0.79
如果数据有限,单一的把数据都用来做训练模型,容易导致过拟合。(反过来,如果数据足够多,完全可以不使用交叉验证。)较小的k值会导致可用于建模的数据量太小,所以小数据集的交叉验证结果需要格外注意,建议选择较大的k值。
数据量较小的情况K越大可以提高模型评估的精确度。
【思考】什么是二分类问题的混淆矩阵,理解这个概念,知道它主要是运算到什么任务中的
#混淆矩阵是一个 2 维方阵,它主要用于评估二分类问题(例如:预测患或未患心脏病、股票涨或跌等这种只有两类情况的问题)的好坏。
#两个方向一起看:
#预测阳性且实际也阳性,我们称它为真阳性 (True Positive),预测阴性且实际也阴性,被称为真阴性 (True Negative),这两个区域是模型预测正确的部分;
#模型预测错误也分两种情况,假阳性 (False Positive) 表示预测阳性,但实际却阴性,假阴性 (False Negative) 表示预测阴性,但实际阳性的情况。
sklearn.metrics
模块classification_report
模块from sklearn.metrics import confusion_matrix
# 模型预测结果
pred = lr2.predict(X_train)
# 混淆矩阵
cm = confusion_matrix(y_train, pred)
cm
array([[377, 62],
[ 84, 189]], dtype=int64)
# 混淆矩阵可视化
sns.heatmap(cm, annot=True, cmap='Blues',fmt='.20g')
plt.title('confusion_matrix')
plt.xlabel('predict')
plt.ylabel('True labels')
plt.show()
from sklearn.metrics import classification_report
# 精确率、召回率以及f1-score
print(classification_report(y_train, pred))
precision recall f1-score support
0 0.82 0.86 0.84 439
1 0.75 0.69 0.72 273
accuracy 0.79 712
macro avg 0.79 0.78 0.78 712
weighted avg 0.79 0.79 0.79 712
【思考】什么是ROC曲线,OCR曲线的存在是为了解决什么问题?
#1、ROC曲线能很容易的查出任意阈值对学习器的泛化性能影响。
#2、有助于选择最佳的阈值。ROC曲线越靠近左上角,模型的准确性就越高。最靠近左上角的ROC曲线上的点是分类错误最少的最好阈值,其假正例和假反例总数最少。
#3、可以对不同的学习器比较性能。将各个学习器的ROC曲线绘制到同一坐标中,直观地鉴别优劣,靠近左上角的ROC曲所代表的学习器准确性最高。
#该方法简单、直观、通过图示可观察分析学习器的准确性,并可用肉眼作出判断。ROC曲线将真正例率和假正例率以图示方法结合在一起,可准确反映某种学习器真正例率和假正例率的关系,是检测准确性的综合代表。
sklearn.metrics
from sklearn.metrics import roc_curve
#decision_function:输出样本距离各个分类器的分隔超平面的置信度,并由此可以推算出predict的预测结果
#decision_function表示通过度量样本距离分隔超平面距离的来表示置信度。
#通常使用decision_function的置信度来计算ROC
fpr, tpr, thresholds = roc_curve(y_test, lr2.decision_function(X_test))
plt.plot(fpr, tpr, label="ROC Curve")
plt.xlabel("FPR")
plt.ylabel("TPR (recall)")
# 找到最接近于0的阈值
close_zero = np.argmin(np.abs(thresholds))
plt.plot(fpr[close_zero], tpr[close_zero], 'o', markersize=10, label="threshold zero", fillstyle="none", c='k', mew=2)
plt.legend(loc=4)
from sklearn import metrics
#计算auc,auc为Roc曲线下的面积
roc_auc = metrics.auc(fpr, tpr)
print(roc_auc)
0.861133069828722
#带有AUC值得Roc曲线可视化
plt.plot(fpr, tpr, 'b',label='AUC = %0.2f'% roc_auc)
plt.legend(loc='lower right')
plt.xlabel('False Positive Rate') #横坐标是fpr
plt.ylabel('True Positive Rate') #纵坐标是tpr
plt.title('Receiver operating characteristic')
plt.show()
#多分类绘制多个ROC曲线,每个分类绘制一个。
【思考】你能从这条OCR曲线的到什么信息?这些信息可以做什么?
#进行模型准确性的评估