{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import pandas as pd #数据分析库,核心是DataFrame对象\n", "from sklearn.linear_model import LogisticRegression\n", "from sklearn.ensemble import RandomForestClassifier #随机森林\n", "from sklearn.model_selection import train_test_split,cross_val_score,GridSearchCV #训练集和测试集的划分,交叉验证评估模型,网格搜索优化超参数\n", "from sklearn.metrics import accuracy_score,roc_auc_score,roc_curve,auc #模型准确度 \n", "import matplotlib.pyplot as pyt #绘制ROC曲线" ] }, { "cell_type": "code", "execution_count": 3, "id": "59086eb3", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass \\\n", "0 1 0 3 \n", "1 2 1 1 \n", "2 3 1 3 \n", "3 4 1 1 \n", "4 5 0 3 \n", "\n", " Name Sex Age SibSp \\\n", "0 Braund, Mr. Owen Harris male 22.0 1 \n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 \n", "2 Heikkinen, Miss. Laina female 26.0 0 \n", "3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 \n", "4 Allen, Mr. William Henry male 35.0 0 \n", "\n", " Parch Ticket Fare Cabin Embarked \n", "0 0 A/5 21171 7.2500 NaN S \n", "1 0 PC 17599 71.2833 C85 C \n", "2 0 STON/O2. 3101282 7.9250 NaN S \n", "3 0 113803 53.1000 C123 S \n", "4 0 373450 8.0500 NaN S " ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df=pd.read_csv(\"C:\\Learning\\MachineLearning\\RandomForest\\\\train.csv\",header=0)\n", "df.head()" ] }, { "cell_type": "code", "execution_count": 4, "id": "4b0650bf", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\" subset = df[df['Survived'] == 0]\\n\\n# 过采样倍数\\noversampling_factor = 3\\n\\n# 使用 sample 函数对 subset 进行过采样,将采样结果追加到原始数据集中\\noversampled_df = pd.concat([df] + [subset.sample(frac=1, replace=True)] * (oversampling_factor - 1), axis=0)\\n\\n# 输出过采样后的数据集\\nprint(oversampled_df) \"" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\" subset = df[df['Survived'] == 0]\n", "\n", "# 过采样倍数\n", "oversampling_factor = 3\n", "\n", "# 使用 sample 函数对 subset 进行过采样,将采样结果追加到原始数据集中\n", "oversampled_df = pd.concat([df] + [subset.sample(frac=1, replace=True)] * (oversampling_factor - 1), axis=0)\n", "\n", "# 输出过采样后的数据集\n", "print(oversampled_df) \"\"\"" ] }, { "cell_type": "code", "execution_count": 5, "id": "2345dd24", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "891" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[\"Age\"]=df[\"Age\"].fillna(df[\"Age\"].median())\n", "df[\"Cabin\"]=df[\"Cabin\"].bfill() #用相邻后面(back)特征填充前面缺失值\n", "df[\"Embarked\"]=df[\"Embarked\"].fillna(\"S\")\n", "output=df\n", "output.to_csv(\"final.csv\")\n", "len(df)" ] }, { "cell_type": "code", "execution_count": 6, "id": "7d0107fd", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Survived\n", "0 549\n", "1 342\n", "Name: count, dtype: int64" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#看样本是否均衡,下采样(从多的样本中抽取跟少的样本中一样的数量),过采样(把数据量少的样本重复多次使之数量与多的差不多)解决样本不均衡的情况\n", "df.Survived.value_counts()" ] }, { "cell_type": "code", "execution_count": 7, "id": "e43fd930", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 0\n", "1 1\n", "2 1\n", "3 1\n", "4 0\n", "Name: Survived, dtype: int64" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y=df[\"Survived\"]\n", "y.head()" ] }, { "cell_type": "code", "execution_count": 8, "id": "f241e0d5", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
013Braund, Mr. Owen Harrismale22.010A/5 211717.2500C85S
121Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
233Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250C123S
341Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
453Allen, Mr. William Henrymale35.0003734508.0500E46S
\n", "
" ], "text/plain": [ " PassengerId Pclass Name \\\n", "0 1 3 Braund, Mr. Owen Harris \n", "1 2 1 Cumings, Mrs. John Bradley (Florence Briggs Th... \n", "2 3 3 Heikkinen, Miss. Laina \n", "3 4 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) \n", "4 5 3 Allen, Mr. William Henry \n", "\n", " Sex Age SibSp Parch Ticket Fare Cabin Embarked \n", "0 male 22.0 1 0 A/5 21171 7.2500 C85 S \n", "1 female 38.0 1 0 PC 17599 71.2833 C85 C \n", "2 female 26.0 0 0 STON/O2. 3101282 7.9250 C123 S \n", "3 female 35.0 1 0 113803 53.1000 C123 S \n", "4 male 35.0 0 0 373450 8.0500 E46 S " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#删掉Survived列\n", "x=df.drop(\"Survived\",axis=1)\n", "x.head()" ] }, { "cell_type": "code", "execution_count": 9, "id": "5a377d7f", "metadata": {}, "outputs": [], "source": [ "features=[\"Pclass\",\"Sex\",\"Age\",\"Ticket\",\"Fare\",\"Cabin\"]\n", "from FuncToNumberClass import FuncToNumber\n", "x=FuncToNumber.ToNumber(x.loc[:,features])\n" ] }, { "cell_type": "code", "execution_count": 10, "id": "6dd05460", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Pclass Sex Age Ticket Fare Cabin\n", "887 1 0 24 14 153 30\n", "416 2 0 45 224 161 115\n", "479 3 0 6 251 79 31\n", "134 2 1 33 552 85 107\n", "588 3 1 28 79 43 96\n", ".. ... ... ... ... ... ...\n", "400 3 1 52 663 41 78\n", "118 1 1 31 585 244 36\n", "701 1 1 47 579 141 120\n", "206 3 1 42 247 106 8\n", "867 1 1 41 590 184 6\n", "\n", "[712 rows x 6 columns]\n" ] } ], "source": [ "\n", "xtrain,xtest,ytrain,ytest=train_test_split(x,y,test_size=0.2,random_state=5)\n", "\n", "print(xtrain)" ] }, { "cell_type": "code", "execution_count": 11, "id": "7106567b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Pclass Sex Age Ticket Fare Cabin\n", "126 3 1 36 463 30 138\n", "354 3 1 36 182 16 123\n", "590 3 1 47 656 14 96\n", "509 3 1 34 80 193 121\n", "769 3 1 42 511 48 136\n", ".. ... ... ... ... ... ...\n", "732 2 1 36 137 0 15\n", "42 3 1 36 391 40 101\n", "179 3 1 48 574 0 144\n", "123 2 0 43 219 85 116\n", "890 3 1 42 466 30 147\n", "\n", "[179 rows x 6 columns]\n" ] } ], "source": [ "print(xtest)\n" ] }, { "cell_type": "code", "execution_count": 12, "id": "f62148bd", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "126 0\n", "354 0\n", "590 0\n", "509 1\n", "769 0\n", " ..\n", "732 0\n", "42 0\n", "179 0\n", "123 1\n", "890 0\n", "Name: Survived, Length: 179, dtype: int64\n" ] } ], "source": [ "print(ytest)" ] }, { "cell_type": "markdown", "id": "e21ce014", "metadata": {}, "source": [ "n_estimators : 随机森林中树的个数,即学习器的个数。 \n", "max_features : 划分叶子节点,选择的最大特征数目 \n", "n_features:在寻找最佳分割时要考虑的特征数量\n", "max_depth : 树的最大深度,如果选择default=None,树就一致扩展,直到所有的叶子节点都是同一类样本,或者达到最小样本划分(min_samples_split)的数目。\n", "min_samples_split : 最小样本划分的数目,就是样本的数目少于等于这个值,就不能继续划分当前节点了\n", "min_samples_leaf : 叶子节点最少样本数,如果某叶子节点数目小于这个值,就会和兄弟节点一起被剪枝。\n", "min_weight_fraction_leaf:叶子节点最小的样本权重和\n", "max_leaf_nodes: 最大叶子节点数,默认是”None”,即不限制最大的叶子节点数\n", "min_impurity_split:节点划分的最小不纯度,是结束树增长的一个阈值,如果不纯度超过这个阈值,那么该节点就会继续划分,否则不划分,成为一个叶子节点。\n", "min_impurity_decrease : 最小不纯度减少的阈值,如果对该节点进行划分,使得不纯度的减少大于等于这个值,那么该节点就会划分,否则,不划分。\n", "bootstrap :自助采样,又放回的采样,大量采样的结果就是初始样本的63.2%作为训练集。默认选择自助采样法。\n", "oob_score : bool (default=False) \n", "out-of-bag estimate,包外估计;是否选用包外样本(即bootstrap采样剩下的36.8%的样本)作为验证集,对训练结果进行验证,默认不采用。\n", "n_jobs : 并行使用的进程数,默认1个,如果设置为-1,该值为总的核数。\n", "random_state :随机状态,默认由np.numpy生成\n", "verbose:显示输出的一些参数,默认不输出。" ] }, { "cell_type": "code", "execution_count": 13, "id": "7a230210", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
RandomForestClassifier()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" ], "text/plain": [ "RandomForestClassifier()" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rfc=RandomForestClassifier() #实例化\n", "rfc.fit(xtrain,ytrain) " ] }, { "cell_type": "code", "execution_count": 14, "id": "124e234e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1,\n", " 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0,\n", " 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0,\n", " 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1,\n", " 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0,\n", " 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0,\n", " 0, 1, 0], dtype=int64)" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "predicts=rfc.predict(xtest)\n", "predicts\n" ] }, { "cell_type": "code", "execution_count": 15, "id": "72b345bf", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0.91, 0.09],\n", " [0.86, 0.14],\n", " [0.68, 0.32],\n", " [0.24, 0.76],\n", " [0.82, 0.18],\n", " [0.93, 0.07],\n", " [0.01, 0.99],\n", " [0.87, 0.13],\n", " [0.04, 0.96],\n", " [0.96, 0.04],\n", " [0.67, 0.33],\n", " [0.6 , 0.4 ],\n", " [0.33, 0.67],\n", " [0.02, 0.98],\n", " [1. , 0. ],\n", " [0.15, 0.85],\n", " [0.97, 0.03],\n", " [0.47, 0.53],\n", " [0.96, 0.04],\n", " [1. , 0. ],\n", " [0.81, 0.19],\n", " [0.41, 0.59],\n", " [0.03, 0.97],\n", " [0.18, 0.82],\n", " [0.85, 0.15],\n", " [0.55, 0.45],\n", " [0.77, 0.23],\n", " [0.67, 0.33],\n", " [0.65, 0.35],\n", " [0.88, 0.12],\n", " [0.93, 0.07],\n", " [0.53, 0.47],\n", " [0.2 , 0.8 ],\n", " [0.98, 0.02],\n", " [0.09, 0.91],\n", " [0.45, 0.55],\n", " [0.97, 0.03],\n", " [0.77, 0.23],\n", " [0.82, 0.18],\n", " [0.86, 0.14],\n", " [0.98, 0.02],\n", " [0.15, 0.85],\n", " [0.91, 0.09],\n", " [0.96, 0.04],\n", " [0.92, 0.08],\n", " [0.98, 0.02],\n", " [0.09, 0.91],\n", " [0.04, 0.96],\n", " [0.68, 0.32],\n", " [0.97, 0.03],\n", " [0.8 , 0.2 ],\n", " [0.03, 0.97],\n", " [0.04, 0.96],\n", " [0.84, 0.16],\n", " [0.94, 0.06],\n", " [0.91, 0.09],\n", " [0.34, 0.66],\n", " [0.98, 0.02],\n", " [0.77, 0.23],\n", " [0.22, 0.78],\n", " [0.9 , 0.1 ],\n", " [0.69, 0.31],\n", " [0.81, 0.19],\n", " [0.91, 0.09],\n", " [0.44, 0.56],\n", " [0.68, 0.32],\n", " [0.99, 0.01],\n", " [0.81, 0.19],\n", " [0.86, 0.14],\n", " [0.55, 0.45],\n", " [0.13, 0.87],\n", " [0.9 , 0.1 ],\n", " [0.1 , 0.9 ],\n", " [0.94, 0.06],\n", " [0.27, 0.73],\n", " [0.8 , 0.2 ],\n", " [0.93, 0.07],\n", " [0.87, 0.13],\n", " [0.03, 0.97],\n", " [0.13, 0.87],\n", " [0.87, 0.13],\n", " [0.95, 0.05],\n", " [0.93, 0.07],\n", " [0.97, 0.03],\n", " [0.05, 0.95],\n", " [0.06, 0.94],\n", " [0.86, 0.14],\n", " [0.16, 0.84],\n", " [0.87, 0.13],\n", " [0.42, 0.58],\n", " [0.88, 0.12],\n", " [1. , 0. ],\n", " [0.01, 0.99],\n", " [0.81, 0.19],\n", " [0.02, 0.98],\n", " [0.9 , 0.1 ],\n", " [0.06, 0.94],\n", " [0.82, 0.18],\n", " [0.92, 0.08],\n", " [0.93, 0.07],\n", " [0.58, 0.42],\n", " [0.11, 0.89],\n", " [0.93, 0.07],\n", " [0.8 , 0.2 ],\n", " [0.21, 0.79],\n", " [0.07, 0.93],\n", " [0.95, 0.05],\n", " [0.77, 0.23],\n", " [0.99, 0.01],\n", " [0.5 , 0.5 ],\n", " [0.97, 0.03],\n", " [0.71, 0.29],\n", " [0.83, 0.17],\n", " [1. , 0. ],\n", " [0.09, 0.91],\n", " [0.44, 0.56],\n", " [0.37, 0.63],\n", " [0.88, 0.12],\n", " [0.05, 0.95],\n", " [0.56, 0.44],\n", " [0.48, 0.52],\n", " [0.72, 0.28],\n", " [0.69, 0.31],\n", " [0.05, 0.95],\n", " [0.84, 0.16],\n", " [0.03, 0.97],\n", " [0.72, 0.28],\n", " [0.89, 0.11],\n", " [0.72, 0.28],\n", " [0.97, 0.03],\n", " [0.94, 0.06],\n", " [0.94, 0.06],\n", " [0.96, 0.04],\n", " [0.81, 0.19],\n", " [0.11, 0.89],\n", " [0.94, 0.06],\n", " [0.98, 0.02],\n", " [0.84, 0.16],\n", " [0.95, 0.05],\n", " [0.9 , 0.1 ],\n", " [0.87, 0.13],\n", " [0.98, 0.02],\n", " [0.96, 0.04],\n", " [0.54, 0.46],\n", " [0.33, 0.67],\n", " [0.06, 0.94],\n", " [0.82, 0.18],\n", " [0.01, 0.99],\n", " [0.86, 0.14],\n", " [0.23, 0.77],\n", " [0.09, 0.91],\n", " [0.79, 0.21],\n", " [0.59, 0.41],\n", " [0.9 , 0.1 ],\n", " [0.86, 0.14],\n", " [0.38, 0.62],\n", " [0.14, 0.86],\n", " [0.82, 0.18],\n", " [0.92, 0.08],\n", " [0.9 , 0.1 ],\n", " [0.89, 0.11],\n", " [0.92, 0.08],\n", " [0.85, 0.15],\n", " [0.65, 0.35],\n", " [0.35, 0.65],\n", " [0.7 , 0.3 ],\n", " [0.12, 0.88],\n", " [0.91, 0.09],\n", " [0.94, 0.06],\n", " [0.95, 0.05],\n", " [0.02, 0.98],\n", " [0.92, 0.08],\n", " [0.32, 0.68],\n", " [0.02, 0.98],\n", " [1. , 0. ],\n", " [0.96, 0.04],\n", " [0.76, 0.24],\n", " [0.1 , 0.9 ],\n", " [0.53, 0.47]])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "predicts_proba=rfc.predict_proba(xtest)[:,:]\n", "predicts_proba" ] }, { "cell_type": "code", "execution_count": 16, "id": "660f8572", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.8491620111731844" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "row=df.loc[xtest.index]\n", "output = pd.DataFrame({'PassengerId':row.PassengerId, \"Name\":row.Name, 'ActualSurvived': row.Survived, 'PredictSurvived': predicts})\n", "\n", "output.to_csv('result.csv', index=False)\n", "outputresult=output[output.ActualSurvived==output.PredictSurvived]\n", "len(outputresult)\n", "len(outputresult)/len(output)" ] }, { "cell_type": "code", "execution_count": 17, "id": "5a3eaa96", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.8579093799682036" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'''percent = accuracy_score(ytest,predicts)\n", "print(\"准确率:\", round(percent, 3))'''\n", "\n", "roc_auc_score(ytest,rfc.predict_proba(xtest)[:,1])" ] }, { "cell_type": "code", "execution_count": 18, "id": "db10f2f8", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAHHCAYAAABTMjf2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/OQEPoAAAACXBIWXMAAA9hAAAPYQGoP6dpAABreklEQVR4nO3de3zO9f/H8ce12clhG8YYYyPHkjlETomWU5ROJnKK1BclUinVpKKjlPRTUjoo5Kv4RsohFZFyzDGHyXHO2xx3ut6/Pz65tDbaNds+267n/Xa7bvl8rs91fV6XS/b0PjqMMQYRERERD+RldwEiIiIidlEQEhEREY+lICQiIiIeS0FIREREPJaCkIiIiHgsBSERERHxWApCIiIi4rEUhERERMRjKQiJiIiIx1IQEpEiw+FwMHr0aNfxtGnTcDgc7Nmz519fGxERQd++fXO1nr59+xIREZGr7ykiuUtBSMSDXAgGFx7FihWjUqVK9O3blwMHDthdXqF08OBBRo8ezfr16+0uRURyoJjdBYhI/hszZgyRkZGcP3+eVatWMW3aNJYvX86mTZvw9/e3u7xc06tXL7p3746fn1+e3ePgwYM899xzREREEBUVleG5KVOm4HQ68+zeInLlFIREPFDHjh1p3LgxAAMGDCAkJISXX36ZefPm0a1bN5uryz3e3t54e3vbdn8fHx/b7i0i2aOuMRGhVatWAOzatSvD+aVLl9KqVStKlChBcHAwt912G1u3bs30+gMHDtC/f3/CwsLw8/MjMjKS//znP6SkpGR5v9TUVMqUKUO/fv0yPZeUlIS/vz8jRowAICUlhWeffZZGjRoRFBREiRIlaNWqFd9///2/fq6sxggZY3jhhReoXLkyxYsXp02bNmzevDnTa0+cOMGIESOoV68eJUuWJDAwkI4dO7JhwwbXNcuWLeO6664DoF+/fq4ux2nTpgFZjxE6c+YMjz76KOHh4fj5+VGrVi1ee+01jDEZrnM4HAwZMoSvvvqKa665Bj8/P66++moWLlz4r59bRLJPLUIi4goKpUuXdp1bvHgxHTt2pFq1aowePZpz584xceJEWrRowdq1a10/4A8ePEiTJk1ISEhg4MCB1K5dmwMHDjB79mzOnj2Lr69vpvv5+Phw++23M2fOHN59990M13z11VckJyfTvXt3wApG77//Pvfccw/3338/p06dYurUqbRv357Vq1dn6o76N88++ywvvPACnTp1olOnTqxdu5Z27dplCm27d+/mq6++4u677yYyMpLDhw/z7rvv0rp1a7Zs2UJYWBh16tRhzJgxPPvsswwcONAVKJs3b57lvY0x3HrrrXz//ff079+fqKgovv32Wx577DEOHDjAG2+8keH65cuXM2fOHAYNGkSpUqV46623uPPOO9m7dy9ly5Z163OLyCUYEfEYH374oQHM4sWLzdGjR82+ffvM7NmzTbly5Yyfn5/Zt2+f69qoqChTvnx5c/z4cde5DRs2GC8vL9O7d2/Xud69exsvLy/z66+/Zrqf0+m8ZC3ffvutAcz//ve/DOc7depkqlWr5jpOS0szycnJGa45efKkCQ0NNffdd1+G84CJjY3N9Hnj4uKMMcYcOXLE+Pr6mltuuSVDbU899ZQBTJ8+fVznzp8/b9LT0zO8f1xcnPHz8zNjxoxxnfv1118NYD788MNMn7FPnz6matWqruOvvvrKAOaFF17IcN1dd91lHA6H2blzZ4bP4uvrm+Hchg0bDGAmTpyY6V4ikjPqGhPxQNHR0ZQrV47w8HDuuusuSpQowbx586hcuTIAhw4dYv369fTt25cyZcq4Xnfttddy8803s2DBAgCcTidfffUVXbp0cY05+juHw3HJGtq2bUtISAgzZ850nTt58iSLFi0iJibGdc7b29vVYuR0Ojlx4gRpaWk0btyYtWvXuvW5Fy9eTEpKCg899FCG2h555JFM1/r5+eHlZf0VmZ6ezvHjxylZsiS1atVy+74XLFiwAG9vbx5++OEM5x999FGMMXzzzTcZzkdHR1O9enXX8bXXXktgYCC7d+/O0f1FJDMFIREPNGnSJBYtWsTs2bPp1KkTx44dyzCz6s8//wSgVq1amV5bp04djh07xpkzZzh69ChJSUlcc801btdQrFgx7rzzTubOnUtycjIAc+bMITU1NUMQAvjoo4+49tpr8ff3p2zZspQrV4758+eTmJjo1j0vfK4aNWpkOF+uXLkM3YJgha433niDGjVq4OfnR0hICOXKlWPjxo1u3/fv9w8LC6NUqVIZztepUydDfRdUqVIl03uULl2akydP5uj+IpKZgpCIB2rSpAnR0dHceeedzJs3j2uuuYYePXpw+vTpfK2je/funDp1ytUSMmvWLGrXrk39+vVd13z66af07duX6tWrM3XqVBYuXMiiRYto27Ztnk5NHzt2LMOHD+eGG27g008/5dtvv2XRokVcffXV+TYl/lIz3sw/BlaLSM5psLSIh/P29mbcuHG0adOGt99+m5EjR1K1alUAtm/fnun6bdu2ERISQokSJQgICCAwMJBNmzbl6N433HADFStWZObMmbRs2ZKlS5cyatSoDNfMnj2batWqMWfOnAzdWbGxsW7f78Ln2rFjB9WqVXOdP3r0aKZWltmzZ9OmTRumTp2a4XxCQgIhISGu48t1/2V1/8WLF3Pq1KkMrULbtm3LUJ+I5B+1CIkIN954I02aNGHChAmcP3+eihUrEhUVxUcffURCQoLruk2bNvHdd9/RqVMnALy8vOjatSv/+9//+O233zK977+1XHh5eXHXXXfxv//9j08++YS0tLRM3WIXWkX+/l6//PILK1eudPtzRkdH4+Pjw8SJEzO834QJEzJd6+3tnan+L774ItMK3CVKlADI8Pt0KZ06dSI9PZ233347w/k33ngDh8NBx44ds/lJRCS3qEVIRAB47LHHuPvuu5k2bRoPPvggr776Kh07dqRZs2b079/fNX0+KCgow35eY8eO5bvvvqN169YMHDiQOnXqcOjQIb744guWL19OcHDwZe8bExPDxIkTiY2NpV69eq7xMhd07tyZOXPmcPvtt3PLLbcQFxfH5MmTqVu3rttdeeXKlWPEiBGMGzeOzp0706lTJ9atW8c333yToZXnwn3HjBlDv379aN68Ob///jvTp0/P0JIEUL16dYKDg5k8eTKlSpWiRIkSNG3alMjIyEz379KlC23atGHUqFHs2bOH+vXr89133zF37lweeeSRDAOjRSSf2DllTUTy14Xp5FlNdU9PTzfVq1c31atXN2lpacYYYxYvXmxatGhhAgICTGBgoOnSpYvZsmVLptf++eefpnfv3q5p+NWqVTODBw/ONO09K06n04SHh2c5rfzC82PHjjVVq1Y1fn5+pkGDBubrr7/ONDXdmH+fPn/hcz733HOmYsWKJiAgwNx4441m06ZNpmrVqpmmzz/66KOu61q0aGFWrlxpWrdubVq3bp3hvnPnzjV169Y1xYoVyzCVPqsaT506ZYYNG2bCwsKMj4+PqVGjhnn11VczLTUAmMGDB2f6/fhnnSJyZRzGaNSdiIiIeCaNERIRERGPpSAk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a4D0c89plWiRyygQg6XBarXJLTExMRw9epRnn32W+Ph4oqKiWLhwoWsA9d69ezMEr/DwcL799luGDRvGtddeS6VKlRg6dChPPPFErtWUXRemyV8dFpTv9xaRQuyzz+DsWas7DKBxY+shIrZwu0WosMutRHn92CXEJ53n64dack0lhSER+Rdnz8LQofD+++DrC+vXQ506dlclUmgUmBYhERFx09at0K0bbNoEDoc1Lkj7hIkUCApC2WCM4fcDiRw9dXFhxvNp2R8LJSIe7KOPrE1Sz56F0FCra6xtW7urEpG/KAhlwy9xJ+j+3qosn/PWitEikhVj4P77YepU6zg6Gj791ApDIlJgKAhlw6HEcwCU9CtG9XIXlwuoXr4kNUNL2VWWiBRkDoe1QaqXlzUj7Mknrf3CRKRAyVEQ2rVrFx9++CG7du3izTffpHz58nzzzTdUqVKFq6++OrdrLDAaVAnmk/5N7S5DRAoqY6xtMYKDreORI6FDB2jY0NayROTS3N7N74cffqBevXr88ssvzJkzh9OnTwOwYcOGS+73JSJS5J06BT17QqtW1nggsFqDFIJECjS3g9DIkSN54YUXWLRoUYbVnNu2bcuqVVmPoxERKdLWr4dGjeDzz60ZYj/+aHdFIpJNbgeh33//ndtvvz3T+fLly3Ps2LFcKUpEpFAwBv7v/+D662HHDggPt0JQhw52VyYi2eR2EAoODubQoUOZzq9bt45KlSrlSlEiIgVeYiLExFhT45OToUsXWLcOmje3uzIRcYPbQah79+488cQTxMfH43A4cDqdrFixghEjRtC7d++8qFFEpOAZMgS++MLaH+z112HuXGv3eBEpVNwOQmPHjqV27dqEh4dz+vRp6tatyw033EDz5s15+umn86JGEZGCZ9w4a1zQ8uUwfLg1XV5ECh23p8/7+voyZcoUnnnmGTZt2sTp06dp0KABNWrUyIv6REQKhpMnYd486NPHOq5cGX79VQFIpJBzOwgtX76cli1bUqVKFapUqZIXNYmIFCy//GKNB/rzT2uNoNtus84rBIkUem53jbVt25bIyEieeuoptmzZkhc1iYgUDMZY439atrRCUPXqVkuQiBQZbgehgwcP8uijj/LDDz9wzTXXEBUVxauvvsr+/fvzoj4REXscPw633gojRkBamrV7/Nq11rggESky3A5CISEhDBky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wYMH52qBIlKIHD8OffvC119bx3PmwN1321qSiMjluN0ilJCQQIcOHTKdb9euHYmJiblSlIgUQj//DA0aWCHIzw/+7//grrvsrkpE5LLcDkK33norX375Zabzc+fOpXPnzrlSlIgUIk4nvPwy3HAD7NsHNWrAqlXw4IPqChORAs/trrG6devy4osvsmzZMpo1awbAqlWrWLFiBY8++ihvvfWW61rtPSbiAR5+GC6MD+zRw1o1ulQpe2sSEckmhzF/n9rx7yIjI7P3xg4Hu3fvzlFReSkpKYmgoCASExMJDAzM1mu+XLefYTM30KpGCJ/019onIhls3Aht2sArr8B996kVSETyRE5+fmeH2y1CcXFxuXZzESmE0tPht98uLoh47bWwZ49agUSkUMrROkIi4qEOH4YOHaBlS/jll4vnFYJEpJBSEBKR7Fm6FOrXh8WLwdcX9u+3uyIRkSumICQil5eeDrGxEB1ttQhdc43VNXbnnXZXJiJyxXK015iIeIiDB6FnT1i2zDoeMADefBOKF7e1LBGR3KIgJCKXNmeOFYJKloR337Wmx4uIFCE56hr76aefuPfee2nWrBkHDhwA4JNPPmH58uU5KmLSpElERETg7+9P06ZNWb16dbZeN2PGDBwOB127ds3RfUXkXwweDCNGwJo1CkEiUiS5HYT++9//0r59ewICAli3bh3JyckAJCYmMnbsWLcLmDlzJsOHDyc2Npa1a9dSv3592rdvz5EjRy77uj179jBixAhatWrl9j1F5BL277f2Cjt1yjp2OODVV6FmTVvLEhHJK24HoRdeeIHJkyczZcoUfHx8XOdbtGjB2rVr3S5g/Pjx3H///fTr14+6desyefJkihcvzgcffHDJ16Snp9OzZ0+ee+45qlWr5vY9RSQL8+dDVBR89BE8+qjd1YiI5Au3g9D27du54YYbMp0PCgoiISHBrfdKSUlhzZo1REdHXyzIy4vo6GhWrlx5ydeNGTOG8uXL079//3+9R3JyMklJSRkeIvI3qanw2GPQubO1e3yjRvDEE3ZXJSKSL9wOQhUqVGDnzp2Zzi9fvtzt1pljx46Rnp5OaGhohvOhoaHEx8dn+Zrly5czdepUpkyZkq17jBs3jqCgINcjPDzcrRpFirQ//7Q2S33tNev44YdhxQqoXt3eukRE8onbQej+++9n6NCh/PLLLzgc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eKwiGYQmTZpEREQE/v7+NG3alNWrV1/2+i+++ILatWvj7+9PvXr1WLBgQT5VWvS5811MmTKFVq1aUbp0aUqXLk10dPS/fnfiHnf/37hgxowZOBwO18KncuXc/S4SEhIYPHgwFStWxM/Pj5o1a+rvqlzi7ncxYcIEatWqRUBAAOHh4QwbNozz58/nU7VF148//kiXLl0ICwvD4XDw1Vdf/etrli1bRsOGDfHz8+Oqq65i2rRp7t/YFDEzZswwvr6+5oMPPjCbN282999/vwkODjaHDx/O8voVK1YYb29v88orr5gtW7aYp59+2vj4+Jjff/89nysvetz9Lnr06GEmTZpk1q1bZ7Zu3Wr69u1rgoKCzP79+/O58qLJ3e/jgri4OFOpUiXTqlUrc9ttt+VPsUWcu99FcnKyady4senUqZNZvny5iYuLM8uWLTPr16/P58qLHne/i+nTpxs/Pz8zffp0ExcXZ7799ltTsWJFM2zYsHyuvOhZsGCBGTVqlJkzZ44BzJdffnnZ63fv3m2KFy9uhg8fbrZs2WImTpxovL29zcKFC926b5ELQk2aNDGDBw92Haenp5uwsDAzbty4LK/v1q2bueWWWzKca9q0qXnggQfytE5P4O538U9paWmmVKlS5qOPPsqrEj1KTr6PtLQ007x5c/P++++bPn36KAjlEne/i//7v/8z1apVMykpKflVosdw97sYPHiwadu2bYZzw4cPNy1atMjTOj1NdoLQ448/bq6++uoM52JiYkz79u3duleR6hpLSUlhzZo1REdHu855eXkRHR3NypUrs3zNypUrM1wP0L59+0teL9mTk+/in86ePUtqamqub7DniXL6fYwZM4by5cvTv3///CjTI+Tku5g3bx7NmjVj8ODBhIaGcs011zB27FjS09Pzq+wiKSffRfPmzVmzZo2r+2z37t0sWLCATp065UvNclFu/fwuECtL55Zjx46Rnp7u2p7jgtDQULZt25bla+Lj47O8Pj4+Ps/q9AQ5+S7+6YknniAsLCzTH3RxX06+j+XLlzN16lTWr1+fDxV6jpx8F7t372bp0qX07NmTBQsWsHPnTgYNGkRqaiqxsbH5UXaRlJPvokePHhw7doyWLVtijCEtLY0HH3yQp556Kj9Klr+51M/vpKQkzp07R0BAQLbep0i1CEnR8dJLLzFjxgy+/PJL/P397S7H45w6dYpevXoxZcoUQkJC7C7H4zmdTsqXL897771Ho0aNiImJYdSoUUyePNnu0jzOsmXLGDt2LO+88w5r165lzpw5zJ8/n+eff97u0iSHilSLUEhICN7e3hw+fDjD+cOHD1OhQoUsX1OhQgW3rpfsycl3ccFrr73GSy+9xOLFi7n22mvzskyP4e73sWvXLvbs2UOXLl1c55xOJwDFihVj+/btVK9ePW+LLqJy8v9GxYoV8fHxwdvb23WuTp06xMfHk5KSgq+vb57WXFTl5Lt45pln6NWrFwMGDACgXr16nDlzhoEDBzJq1KgMm4RL3rrUz+/AwMBstwZBEWsR8vX1pVGjRixZssR1zul0smTJEpo1a5bla5o1a5bheoBFixZd8nrJnpx8FwCvvPIKzz//PAsXLqRx48b5UapHcPf7qF27Nr///jvr1693PW699VbatGnD+vXrCQ8Pz8/yi5Sc/L/RokULdu7c6QqjAH/88QcVK1ZUCLoCOfkuzp49mynsXAioRlt35qtc+/nt3jjugm/GjBnGz8/PTJs2zWzZssUMHDjQBAcHm/j4eGOMMb169TIjR450Xb9ixQpTrFgx89prr5mtW7ea2NhYTZ/PJe5+Fy+99JLx9fU1s2fPNocOHXI9Tp06ZddHKFLc/T7+SbPGco+738XevXtNqVKlzJAhQ8z27dvN119/bcqXL29eeOEFuz5CkeHudxEbG2tKlSplPv/8c7N7927z3XffmerVq5tu3brZ9RGKjFOnTpl169aZdevWGcCMHz/erFu3zvz555/GGGNGjhxpevXq5br+wvT5xx57zGzdutVMmjRJ0+cvmDhxoqlSpYrx9fU1TZo0MatWrXI917p1a9OnT58M18+aNcvUrFnT+Pr6mquvvtrMnz8/nysuutz5LqpWrWqATI/Y2Nj8L7yIcvf/jb9TEMpd7n4XP//8s2natKnx8/Mz1apVMy+++KJJS0vL56qLJne+i9TUVDN69GhTvXp14+/vb8LDw82gQYPMyZMn87/wIub777/P8mfAhd//Pn36mNatW2d6TVRUlPH19TXVqlUzH374odv3dRijtjwRERHxTEVqjJCIiIiIOxSERERExGMpCImIiIjHUhASERERj6UgJCIiIh5LQUhEREQ8loKQiIiIeCwFIRHJZNq0aQQHB9tdxhVxOBx89dVXl72mb9++dO3aNV/qEZGCSUFIpIjq27cvDocj02Pnzp12l5YvDh06RMeOHQHYs2cPDoeD9evXZ7jmzTffZNq0aflfXDYsW7YMh8NBQkKC3aWIFGlFavd5EcmoQ4cOfPjhhxnOlStXzqZq8teldg//u6CgoHyoJCPtFi9SsKhFSKQI8/Pzo0KFChke3t7ejB8/nnr16lGiRAnCw8MZNGgQp0+fvuT7bNiwgTZt2lCqVCkCAwNp1KgRv/32m+v55cuX06pVKwICAggPD+fhhx/mzJkzl3y/0aNHExUVxbvvvkt4eDjFixenW7duJCYmuq5xOp2MGTOGypUr4+fnR1RUFAsXLnQ9n5KSwpAhQ6hYsSL+/v5UrVqVcePGuZ7/e9dYZGQkAA0aNMDhcHDjjTcCGbvG3nvvPcLCwjLs8A5w2223cd9997mO586dS8OGDfH396datWo899xzpKWlXfKzXrjHiy++SFhYGLVq1QLgk08+oXHjxpQqVYoKFSrQo0cPjhw5AlgtWG3atAGgdOnSOBwO+vbt6/p9GTduHJGRkQQEBFC/fn1mz559yfuLyOUpCIl4IC8vL9566y02b97MRx99xNKlS3n88ccveX3Pnj2pXLkyv/76K2vWrGHkyJH4+PgAsGvXLjp06MCdd97Jxo0bmTlzJsuXL2fIkCGXrWHnzp3MmjWL//3vfyxcuJB169YxaNAg1/Nvvvkmr7/+Oq+99hobN26kffv23HrrrezYsQOAt956i3nz5jFr1iy2b9/O9OnTiYiIyPJeq1evBmDx4sUcOnSIOXPmZLrm7rvv5vjx43z//feucydOnGDhwoX07NkTgJ9++onevXszdOhQtmzZwrvvvsu0adN48cUXL/tZlyxZwvbt21m0aBFff/01AKmpqTz//PNs2LCBr776ij179rjCTnh4OP/9738B2L59O4cOHeLNN98EYNy4cXz88cdMnjyZzZs3M2zYMO69915++OGHy9YgIpdwpbvFikjB1KdPH+Pt7W1KlCjhetx1111ZXvvFF1+YsmXLuo4//PBDExQU5DouVaqUmTZtWpav7d+/vxk4cGCGcz/99JPx8vIy586dy/I1sbGxxtvb2+zfv9917ptvvjFeXl7m0KFDxhhjwsLCzIsvvpjhddddd50ZNGiQMcaYhx56yLRt29Y4nc4s7wGYL7/80hhjTFxcnAHMunXrMlzTp08fc9ttt7mOb7vtNnPfffe5jt99910TFhZm0tPTjTHG3HTTTWbs2LEZ3uOTTz4xFStWzLKGC/cIDQ01ycnJl7zGGGN+/fVXA5hTp04ZYy7uxP33Xc3Pnz9vihcvbn7++ecMr+3fv7+55557Lvv+IpI1jRESKcLatGnD//3f/7mOS5QoAVgtI+PGjWPbtm0kJSWRlpbG+fPnOXv2LMWLF8/0PsOHD2fAgAF88sknREdHc/fdd1O9enXA6jbbuHEj06dPd11vjMHpdBIXF0edOnWyrK1KlSpUqlTJddysWTOcTifbt2+nePHiHDx4kBYtWmR4TYsWLdiwYQNgdTndfPPN1KpViw4dOtC5c2fatWuXw98pS8+ePbn//vt555138PPzY/r06XTv3h0vLy/XZ12xYkWGFqD09PTL/t4B1KtXL9O4oDVr1jB69Gg2bNjAyZMnXV1ye/fupW7dulm+z86dOzl79iw333xzhvMpKSk0aNAgx59bxJMpCIkUYSVKlOCqq67KcG7Pnj107tyZ//znP7z44ouUKVOG5cuX079/f1JSUrL8YT569Gh69OjB/Pnz+eabb4iNjWXGjBncfvvtnD59mgceeICHH3440+uqVKmSZ5+tYcOGxMXF8c0337B48WK6detGdHT0FY2X6dKlC8YY5s+fz3XXXcdPP/3EG2+84Xr+9OnTPPfcc9xxxx2ZXuvv73/J970QQC84c+YM7du3p3379kyfPp1y5cqxd+9e2rdvT0pKyiXf58I4rvnz52cIkWCNBxMR9ykIiXiYNWvW4HQ6ef31110tHbNmzfrX19WsWZOaNWsybNgw7rnnHj788ENuv/12GjZsyJYtWzIFrn+zd+9eDh48SFhYGACrVq3Cy8uLWrVqERgYSFhYGCtWrKB169au16xYsYImTZq4jgMDA4mJiSEmJoa77rqLDh06cOLECcqUKZPhXhdaY9LT0y9bk7+/P3fccQfTp09n586d1KpVi4YNG7qeb9iwIdu3b3f7s/7Ttm3bOH78OC+99BLh4eEAGQafX6rmunXr4ufnx969ezP8vohIzikIiXiYq666itTUVCZOnEiXLl1YsWIFkydPvuT1586d47HHHuOuu+4iMjKS/fv38+uvv3LnnXcC8MQTT3D99dczZMgQBgwYQIkSJdiyZQuLFi3i7bffvuT7+vv706dPH1577TWSkpJ4+OGH6datm2va+2OPPUZsbCzVq1cnKiqKDz/8kPXr17u64MaPH0/FihVp0KABXl5efPHFF1SoUCHLhSDLly9PQEAACxcupHLlyvj7+19y6nzPnj3p3Lkzmzdv5t57783w3LPPPkvnzp2pUqUKd911F15eXmzYsIFNmzbxwgsvXPb3/e+qVKmCr68vEydO5MEHH2TTpk08//zzGa6pWrUqDoeDr7/+mk6dOhEQEECpUqUYMWIEw4YNw+l00rJlSxITE1mxYgWBgYH06dMn2zWIyF/sHqQkInnjnwOB/278+PGmYsWKJiAgwLRv3958/PHHGQbm/n2wdHJysunevbsJDw83vr6+JiwszAwZMiTDQOjVq1ebm2++2ZQsWdKUKFHCXHvttZkGOv9dbGysqV+/vnnnnXdMWFiY8ff3N3fddZc5ceKE65r09HQzevRoU6lSJePj42Pq169vvvnmG9fz7733nomKijIlSpQwgYGB5qabbjJr1651Pc/fBksbY8yUKVNMeHi48fLyMq1bt77k71F6erqpWLGiAcyuXbsy1b5w4ULTvHlzExAQYAIDA02TJk3Me++9d8nPeqnv4bPPPjMRERHGz8/PNGvWzMybNy/TgO4xY8aYChUqGIfDYfr06WOMMcbpdJoJEyaYWrVqGR8fH1OuXDnTvn1788MPP1yyBhG5NIcxxtgbxUTE04wePZqvvvoq00rPIiL5TesIiYiIiMdSEBIRERGPpa4xERER8VhqERIRERGPpSAkIiIiHktBSERERDyWgpCIiIh4LAUhERER8VgKQiIiIuKxFIRERETEYykIiYiIiMdSEBIRERGP9f/JPV0b417l+AAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "predict_validation=rfc.predict_proba(xtest)[:,1]\n", "fpr,tpr,_=roc_curve(ytest,predict_validation)\n", "roc_auc=auc(fpr,tpr)\n", "pyt.title(\"Roc validation\")\n", "pyt.plot(fpr,tpr,label=\"AUC=%0.4f\" %roc_auc)\n", "pyt.legend(loc='lower right')\n", "pyt.plot([0,1],[0,1],'r--')\n", "pyt.xlim([0,1])\n", "pyt.ylim([0,1])\n", "pyt.ylabel(\"True positive rate\")\n", "pyt.xlabel(\"False positive rate\")\n", "pyt.show()" ] }, { "cell_type": "code", "execution_count": 19, "id": "bf61bd49", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'bootstrap': True,\n", " 'ccp_alpha': 0.0,\n", " 'class_weight': None,\n", " 'criterion': 'gini',\n", " 'max_depth': None,\n", " 'max_features': 'sqrt',\n", " 'max_leaf_nodes': None,\n", " 'max_samples': None,\n", " 'min_impurity_decrease': 0.0,\n", " 'min_samples_leaf': 1,\n", " 'min_samples_split': 2,\n", " 'min_weight_fraction_leaf': 0.0,\n", " 'n_estimators': 100,\n", " 'n_jobs': None,\n", " 'oob_score': False,\n", " 'random_state': None,\n", " 'verbose': 0,\n", " 'warm_start': False}" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "rfc.get_params()\n" ] }, { "cell_type": "code", "execution_count": 20, "id": "fad5d90c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.88688017 0.91869835 0.86290491 0.87920585 0.80944865]\n", "0.8714275856791531\n" ] } ], "source": [ "rfc=RandomForestClassifier() #实例化\n", "\n", "\n", "score=cross_val_score(rfc,xtrain,ytrain,scoring='roc_auc',cv=5)\n", "print(score)\n", "print(score.mean())" ] }, { "cell_type": "code", "execution_count": 21, "id": "959954bb", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.86956522 0.88086691 0.8565508 0.76604278]\n", "0.843256426568887\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\Python\\Python311\\Lib\\site-packages\\sklearn\\linear_model\\_logistic.py:460: ConvergenceWarning: lbfgs failed to converge (status=1):\n", "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", "\n", "Increase the number of iterations (max_iter) or scale the data as shown in:\n", " https://scikit-learn.org/stable/modules/preprocessing.html\n", "Please also refer to the documentation for alternative solver options:\n", " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", " n_iter_i = _check_optimize_result(\n" ] } ], "source": [ "rfc1=LogisticRegression() #实例化\n", "score=cross_val_score(rfc1,xtrain,ytrain,scoring='roc_auc',cv=4)\n", "print(score)\n", "print(score.mean())" ] }, { "cell_type": "code", "execution_count": 22, "id": "901c12e5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'n_estimators': 450} 0.8753070939277835\n" ] } ], "source": [ "#调整超参数\n", "params_test1 = {'n_estimators' :range(25,500,25)}\n", "gsearch1=GridSearchCV(estimator=RandomForestClassifier(min_samples_split=2,\n", " min_samples_leaf=1,\n", " max_depth=8,random_state=2),\n", " param_grid=params_test1,\n", " scoring='roc_auc',\n", " cv=5)\n", "gsearch1.fit(xtrain,ytrain)\n", "print(gsearch1.best_params_,gsearch1.best_score_)\n", " \n", " " ] }, { "cell_type": "code", "execution_count": 23, "id": "24704a5e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'max_depth': 11} 0.8767195729499804\n" ] } ], "source": [ "params_test2 = {'max_depth' :range(2,30,3)}\n", "gsearch2=GridSearchCV(estimator=RandomForestClassifier(n_estimators=225,\n", " min_samples_split=2,\n", " min_samples_leaf=1,random_state=2),\n", " param_grid=params_test2,\n", " scoring='roc_auc',\n", " cv=5)\n", "gsearch2.fit(xtrain,ytrain)\n", "print(gsearch2.best_params_,gsearch2.best_score_)" ] }, { "cell_type": "code", "execution_count": 24, "id": "ac90a0e3", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
RandomForestClassifier(max_depth=11, n_estimators=225, random_state=2)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" ], "text/plain": [ "RandomForestClassifier(max_depth=11, n_estimators=225, random_state=2)" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gsearch2.best_estimator_" ] }, { "cell_type": "code", "execution_count": 25, "id": "fd6d6a1b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.8657260201377848" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#accuracy_score(ytest,gsearch3.best_estimator_.predict_proba(xtest)[:,1])\n", "roc_auc_score(ytest,gsearch2.best_estimator_.predict_proba(xtest)[:,1])" ] }, { "cell_type": "code", "execution_count": 26, "id": "d3415abc", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
08923Kelly, Mr. Jamesmale34.5003309117.8292NaNQ
18933Wilkes, Mrs. James (Ellen Needs)female47.0103632727.0000NaNS
28942Myles, Mr. Thomas Francismale62.0002402769.6875NaNQ
38953Wirz, Mr. Albertmale27.0003151548.6625NaNS
48963Hirvonen, Mrs. Alexander (Helga E Lindqvist)female22.011310129812.2875NaNS
\n", "
" ], "text/plain": [ " PassengerId Pclass Name Sex \\\n", "0 892 3 Kelly, Mr. James male \n", "1 893 3 Wilkes, Mrs. James (Ellen Needs) female \n", "2 894 2 Myles, Mr. Thomas Francis male \n", "3 895 3 Wirz, Mr. Albert male \n", "4 896 3 Hirvonen, Mrs. Alexander (Helga E Lindqvist) female \n", "\n", " Age SibSp Parch Ticket Fare Cabin Embarked \n", "0 34.5 0 0 330911 7.8292 NaN Q \n", "1 47.0 1 0 363272 7.0000 NaN S \n", "2 62.0 0 0 240276 9.6875 NaN Q \n", "3 27.0 0 0 315154 8.6625 NaN S \n", "4 22.0 1 1 3101298 12.2875 NaN S " ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df1=pd.read_csv(\"C:\\Learning\\MachineLearning\\RandomForest\\\\test.csv\",header=0)\n", "df1.head()" ] }, { "cell_type": "code", "execution_count": 27, "id": "c283c83f", "metadata": {}, "outputs": [], "source": [ "from FuncToNumberClass import FuncToNumber\n", "xtest2=FuncToNumber.ToNumber(df1.loc[:,features])" ] }, { "cell_type": "code", "execution_count": 28, "id": "371558e8", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
RandomForestClassifier(max_depth=14, n_estimators=230, random_state=2)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" ], "text/plain": [ "RandomForestClassifier(max_depth=14, n_estimators=230, random_state=2)" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rfc=RandomForestClassifier(max_depth=14, min_samples_leaf=1, min_samples_split=2,\n", " n_estimators=230, random_state=2) #实例化\n", "rfc.fit(x,y) " ] }, { "cell_type": "code", "execution_count": 29, "id": "76baeb7f", "metadata": {}, "outputs": [], "source": [ "predictresult=rfc.predict(xtest2)\n", "row=df1.loc[xtest2.index]\n", "output = pd.DataFrame({'PassengerId': row.PassengerId,\"Name\":row.Name,'PredictSurvived': predictresult})\n", "output.to_csv(\"ResultPredict.csv\",index=0)" ] }, { "cell_type": "code", "execution_count": 31, "id": "2d404f2e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0 0 0 0 1 0 1 0 1 0 0 0 1 0 1 1 0 0 1 1 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1\n", " 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 1 1 1 0 0 1 1 0 1 0\n", " 1 0 0 1 0 1 1 0 0 0 0 0 1 1 0 1 1 0 1 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 0 0 0\n", " 1 1 1 1 0 0 1 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0\n", " 0 0 1 0 0 0 1 0 1 1 0 0 1 1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 1 0 1 1 0 0 1 0 1\n", " 0 1 0 0 0 0 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 0\n", " 1 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 1 1 1 0 1 0 0 0 0 0 1\n", " 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 1 1 0 0 1 0 0 0 1 0 0 0 0\n", " 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0\n", " 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 1 1 0 1 0 0 1 1 0\n", " 0 1 0 0 1 1 1 0 0 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0\n", " 0 1 1 0 1 1 0 1 0 0 0]\n" ] } ], "source": [ "import pickle\n", "\n", "# 保存模型\n", "with open('model.pkl', 'wb') as f:\n", " pickle.dump(rfc, f)\n", "\n", "# 加载模型\n", "with open('model.pkl', 'rb') as f:\n", " loaded_model = pickle.load(f)\n", "\n", "# 使用加载后的模型进行预测或其他操作\n", "result = loaded_model.predict(xtest2)\n", "print(result)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.5" } }, "nbformat": 4, "nbformat_minor": 5 }