机器学习模型比较分析

2022-12-23 12:31 470 阅读 ID:624
磐创AI
磐创AI

介绍

“机器学习”这个词是由 IBM 的 Arthur Samuel 发明的。机器学习是人工智能的一部分。机器学习是从数据中学习并应用数学来提高准确性的过程。有四种不同类型的机器升收入。

  1. 监督学习
  2. 无监督学习
  3. 半监督学习
  4. 强化学习

机器学习使用数学和统计的方式来学习。机器学习中的预测可以通过许多方法和模型来完成。这有几种用途,如 OCR、垃圾邮件检测等。

在本文中,我们将使用 Book-My-Show 数据集,并应用三个机器学习模型来分析哪种模型适合该数据集。

问题确认

Book-My-Show 发现了一个需要解决的问题。Book-My-Show 允许在其网站上显示广告,这引起了对其用户隐私及其访问信息的担忧。所显示的广告可能包含旨在欺骗某些用户安装恶意程序、锁定其计算机和泄露用户隐私的链接,这可能是毁灭性的。

Book-My-Show 希望对特定 URL 进行分析,以确定它是否容易受到网络钓鱼攻击,从而解决问题。

为了解决 Book-My-Show 问题,我们将使用 Logistic Regression、KNeighbors 和 XGB进行预测。我们将得出关于哪种模型效果最好的结论。

关于 Book-My-Show 数据集

11k 样本对应于输入数据集中的 11k URL。每个示例对具有不同值的 URL 都有不同的描述。如果 URL 在 -1(可疑)、0(网络钓鱼)或 1(合法)的范围内,则该 URL 可能是合法链接或网络钓鱼链接。

实现

实践是在 Kaggle 中实现的。你可以通过以下链接访问数据集和笔记本。book-my-show notebook 链接在我的kaggle.com帐户上。

我的 kaggle.com帐户:https://www.kaggle.com/shibumohapatra

数据集链接:https://www.kaggle.com/datasets/shibumohapatra/book-my-show

Notebook链接:https://www.kaggle.com/code/shibumohapatra/logistics-regression-kneighbors-xgb

模块和库信息

  1. Numpy:线性代数相关计算
  2. Pandas:数据处理,如 pd.read_csv
  3. Matplotlib:绘制图形
  4. Seaborn:可视化随机分布和热图
  5. xgboost:导入 xgbclassifier 模块的库
  6. Sklearn:机器学习工具和统计建模。Sklearn 有许多用于机器学习的模块,例如:
  • Sklearn.model_selection:将数据拆分为训练集和测试集的随机子集
  • Cross_val_score:通过处理结果集的方差问题来评估模型性能。它评估数据并返回分数。
  • KFold:将数据拆分为 K 折以避免过度拟合。
  • GridSearchCV:交叉验证以提取最佳参数值以进行预测
  • StratifiedKFold:用于分层抽样(分为性别、种族等子组)
  • sklearn.linear_model:导入机器学习模型
  • Sklearn.neighbors:导入 KNeighbors 分类器模块
  • Sklearn.metrics:用于预测和确定准确度分数、混淆矩阵、ROC 曲线和 AUC
import numpy as np
import pandas as ad
import matplotlib.pyplot as plt

%matplotlib inline
import seaborn as sns

from sklearn.model_selection import train_test_split,cross_val_score
from sklearn.metrics import accuracy_score,confusion_matrix,classification_report
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier

from xgboost import XGBClassifier,cv

from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score, LeaveOneOut
from sklearn.model_selection import GridSearchCV, StratifiedKFold

探索性数据分析 (EDA)

我们需要使用热图和直方图来探索数据。我们将确定数据中的样本数和所有特征中的唯一元素,检查列中是否有空值。

#import numpy as np
import pandas as pd

df_data = pd.read_csv('bookmyshow.csv')

print('shape of the df', df_data.shape)

print(df_data.head())
print()
print(df_data.describe())

#identify the type of data in each column
print(df_data.info())

输出:

shape of the df (11055, 32)
  index  having_IPhaving_IP_Address  URLURL_Length  Shortining_Service  ...  Google_Index  Links_pointing_to_page  Statistical_report  Result
0     1                           0              1                   1  ...             1                       1                   0       0
1     2                           1              1                   1  ...             1                       1                   1       0
2     3                           1             -1                   1  ...             1                      -1                   0       0
3     4                           1             -1                   1  ...             1                       0                   1       0
4     5                           1             -1                   0  ...             1                       1                   1       1

[5 rows x 32 columns]

       having_IPhaving_IP_Address  URLURL_Length  Shortining_Service  ...  Links_pointing_to_page  Statistical_report        Result
count                11055.000000   11055.000000        11055.000000  ...            11055.000000        11055.000000  11055.000000
mean                     0.656897       0.165084            0.869380  ...               -0.163275            0.859792      0.556943
std                      0.474767       0.402826            0.336999  ...                0.961174            0.347218      0.496769
min                      0.000000      -1.000000            0.000000  ...               -1.000000            0.000000      0.000000
25%                      0.000000       0.000000            1.000000  ...               -1.000000            1.000000      0.000000
50%                      1.000000       0.000000            1.000000  ...               -1.000000            1.000000      1.000000
75%                      1.000000       0.000000            1.000000  ...                1.000000            1.000000      1.000000
max                      1.000000       1.000000            1.000000  ...                1.000000            1.000000      1.000000

[8 rows x 31 columns]
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 11055 entries, 0 to 11054
Data columns (total 32 columns):
 #   Column                       Non-Null Count  Dtype 
---  ------                       --------------  ----- 
 0   index                        11055 non-null  object
 1   having_IPhaving_IP_Address   11055 non-null  int64 
 2   URLURL_Length                11055 non-null  int64 
 3   Shortining_Service           11055 non-null  int64 
 4   having_At_Symbol             11055 non-null  int64 
 5   double_slash_redirecting     11055 non-null  int64 
 6   Prefix_Suffix                11055 non-null  int64 
 7   having_Sub_Domain            11055 non-null  int64 
 8   SSLfinal_State               11055 non-null  int64 
 9   Domain_registeration_length  11055 non-null  int64 
 10  Favicon                      11055 non-null  int64 
 11  port                         11055 non-null  int64 
 12  HTTPS_token                  11055 non-null  int64 
 13  Request_URL                  11055 non-null  int64 
 14  URL_of_Anchor                11055 non-null  int64 
 15  Links_in_tags                11055 non-null  int64 
 16  SFH                          11055 non-null  int64 
 17  Submitting_to_email          11055 non-null  int64 
 18  Abnormal_URL                 11055 non-null  int64 
 19  Redirect                     11055 non-null  int64 
 20  on_mouseover                 11055 non-null  int64 
 21  RightClick                   11055 non-null  int64 
 22  popUpWidnow                  11055 non-null  int64 
 23  Iframe                       11055 non-null  int64 
 24  age_of_domain                11055 non-null  int64 
 25  DNSRecord                    11055 non-null  int64 
 26  web_traffic                  11055 non-null  int64 
 27  Page_Rank                    11055 non-null  int64 
 28  Google_Index                 11055 non-null  int64 
 29  Links_pointing_to_page       11055 non-null  int64 
 30  Statistical_report           11055 non-null  int64 
 31  Result                       11055 non-null  int64 
dtypes: int64(31), object(1)
memory usage: 2.7+ MB
None
df_data = df_data.drop('index',1)

![](http://qiniu.aihubs.net/数据集 (1).png)

df_data.nunique()

![](http://qiniu.aihubs.net/数据集 (3).png)

#check for NULL value in the dataset

print("The null values in the dataset are:",df_data.isnull().sum().sum())

![](http://qiniu.aihubs.net/数据集 (2).png)

# NULL value check
df_data.info()
# Duplicate check
df1 = df_data.T
print("The duplicate values in dataset is:",df1.duplicated().sum())

数据探索绘制直方图

df_data.hist(bins=50, figsize=(20,15))
plt.show()

数据的分布如上面的直方图所示。-1、0 和 1 是值。

pd.value_counts(df_data['Result']).plot.bar()

![](http://qiniu.aihubs.net/合法 (1) URL 和网络钓鱼 (0) URL 的分布.png)

合法 (1) URL 和网络钓鱼 (0) URL 的分布如上图所示。

相关特征和特征选择

我们需要找出数据中是否存在任何相关特征,并删除可能与阈值相关的特征。

#correlation map
f,ax=plt.subplots(figsize=(18,18))
sns.heatmap(df_data.corr(),annot=True, linewidths=.5, fmt='.1f',ax=ax)

![](http://qiniu.aihubs.net/数据集 (4).png)

上述热图输出“popUpWindow”和“Favicon”具有0.9的强相关性。它表明数据冗余。因此,必须删除其中一列。

热图输出“popUpWindow”和“Favicon”之间存在相关性。有 9 个。这表明数据源不止一个。需要删除其中一列。我们需要找到高度相关的自变量并删除列。

阈值设置为 0.75。相关值大于 0. 75 的列将被删除。

cor_matrix = df_data.corr().abs()
upper_tri=cor_matrix.where(np.triu(np.ones(cor_matrix.shape),k=1).astype(np.bool))
# threshold greater than 0.75
to_drop = [column for column in upper_tri.columns if any(upper_tri[column] > 0.75)]
print(to_drop)
#drop the columns which are highly correlated
df_data.drop(to_drop,axis=1,inplace=True)
df_data.shape
X=df_data.drop(columns='Result')
X
Y=df_data['Result']
Y= pd.DataFrame(Y)
Y.head()

在这里,我们将数据分成训练集和测试集。

# split train - test to 70-30
train_X,test_X,train_Y,test_Y = train_test_split(X,Y,test_size=0.3, random_state=9)
print(train_X.shape)
print(train_Y.shape)
print(test_X.shape)
print(test_Y.shape)

分类模型

如果我们清楚地了解数据,就可以建立分类模型。我们首先开发了一个分类模型来识别恶意 URL。

#model build for different binary classification and show confusion matrix
def build_model(model_name,train_X, train_Y, test_X, test_Y):
   if model_name == 'LogisticRegression':
       model=LogisticRegression()
   elif model_name =='KNeighborsClassifier':
       model = KNeighborsClassifier(n_neighbors=4)
   elif model_name == 'XGBClassifier':
       model = XGBClassifier(objective='binary:logistic',eval_metric='auc')
   else:
       print('not a valid model name')
   model=model.fit(train_X,train_Y)
   pred_prob=model.predict_proba(test_X)
   fpr, tpr, thresh = roc_curve(test_Y, pred_prob[:,1], pos_label=1)
   model_predict= model.predict(test_X)
   acc=accuracy_score(model_predict,test_Y)
   print("Accuracy: ",acc)

    # Classification report
   print("Classification Report: ")
   print(classification_report(model_predict,test_Y))

    #print("Confusion Matrix for", model_name)
   con =  confusion_matrix(model_predict,test_Y)
   sns.heatmap(con,annot=True, fmt ='.2f')

   plt.suptitle('Confusion Matrix for '+model_name, x=0.44, y=1.0, ha='center', fontsize=25)
   plt.xlabel('Predict Values', fontsize =25)
   plt.ylabel('Test Values', fontsize =25)
   plt.show()
   return model, acc, fpr, tpr, thresh

一旦我们构建了所有模型,我们将使用热图来查看每个模型的混淆矩阵及其性能。

模型 1 – 逻辑回归

逻辑回归是一种监督方法。逻辑回归用于计算或预测事件。有两个条件:是或否。

一个典型的例子是一个人是否感冒了。患者要么具有传染性,要么没有。

# Model 1 - LogisticRegression
lg_model,acc1, fpr1, tpr1, thresh1 = build_model('LogisticRegression',train_X, train_Y, test_X, test_Y.values.ravel())

模型 2 – KNeighbors 分类器

这是一种通常用于分类和回归问题的监督方法。它用于重采样。

新数据点预测类别或连续值。KNeighbors 是一种惰性机器学习模型。

# Model 2 - KNeighborsClassifier
knn_model,acc2, fpr2, tpr2, thresh2 = build_model('KNeighborsClassifier',train_X, train_Y, test_X, test_Y.values.ravel())

模型 3 – XGB 分类器

它是一种使用可上升的分布式决策树的机器学习形式。XGB 提供并行树提升。在 XGB 中使用了 boosting 技术来尝试构建一个强分类器。

# Model 3 - XGBClassifier
xgb_model, acc3, fpr3, tpr3, thresh3 = build_model('XGBClassifier',train_X, train_Y, test_X, test_Y.values.ravel())

上面的混淆矩阵表明 XGB 分类的准确率最高。

我们需要绘制 ROC 曲线来展示这个分类器的能力。

# roc curve for tpr = fpr
random_probs = [0 for i in range(len(test_Y))]
p_fpr, p_tpr, _ = roc_curve(test_Y, random_probs, pos_label=1)

绘制 ROC 曲线

plt.style.use('seaborn')

# plot roc curves
plt.plot(fpr1, tpr1, linestyle='--',color='orange', label='Logistic Regression')
plt.plot(fpr2, tpr2, linestyle='--',color='green', label='KNN')
plt.plot(fpr3, tpr3, linestyle='--',color='red', label='XGBClassifier')
plt.plot(p_fpr, p_tpr, linestyle='--', color='blue')

# title
plt.title('ROC curve')

# x label
plt.xlabel('False Positive Rate')

# y label
plt.ylabel('True Positive rate')
plt.legend(loc='best')
plt.savefig('ROC',dpi=300)
plt.show()

ROC 图显示的是 XGBClassifier 与其他模型相比,(TPR) True Positive Rate 更高。

我们需要使用 K-Fold 交叉验证来验证我们绘制的数据的准确性。我们将使用 GridSearchCV 来寻找不同模型的最佳参数,并使用 StratifiedKFold 交叉验证技术来寻找数据准确性。

用于逻辑回归模型评估的 Liblinear 和 newton-CG 求解器以及 l1、l2 惩罚

对于逻辑回归,我们在 4 个 StratifiedKFold 折叠中得出了91%的准确率。

import warnings
warnings.filterwarnings("ignore")

# Create the parameter grid based on the results of random search
param_grid = {
   'solver':['liblinear','newton-cg'],
   'C': [0.01,0.1,1,10,100],
   'penalty': ["l1","l2"]
}

# Instantiate the grid search model
grid_search = GridSearchCV(estimator = LogisticRegression() , param_grid = param_grid,
cv = StratifiedKFold(4), n_jobs = -1, verbose = 1, scoring = 'accuracy' )
grid_search.fit(train_X,train_Y.values.ravel())
print('Best Parameter:')
print('F1 Score:', grid_search.best_score_)
print('Best Hyperparameters:', grid_search.best_params_)
print('Model object with best parameters:')
print(grid_search.best_estimator_)

用于 KNeighborsClassifier 模型评估的 GridSearchCV 技术

对于 KNeighbors 分类器,我们在 3 次 GridSearchCV 折叠中获得了95%的准确率。

grid_params = {
   'n_neighbors':[3,4,11,19],
   'weights':['uniform','distance'],
   'metric':['euclidean','manhattan']
}

gs= GridSearchCV(
KNeighborsClassifier(),
grid_params,
verbose=1,
cv=3,
n_jobs=-1
)

gs_results = gs.fit(train_X,train_Y.values.ravel())
print('Best Parameter:')
print('F1 Score:', gs_results.best_score_)
print('Best Hyperparameters:', gs_results.best_params_)
print('Model object with best parameters:')
print(gs_results.best_estimator_)

XGBClassifier模型的KFold交叉验证技术

对于 XGB 分类器,我们在 10 折中获得了96%的准确率。

xgb_cv = XGBClassifier(n_estimators=100,objective='binary:logistic',eval_metric='auc')
scores = cross_val_score(xgb_cv, train_X, train_Y.values.ravel(), cv=10, scoring = "accuracy")

print("Scores:", scores)
print("Mean:", scores.mean())
print("Standard Deviation:", scores.std())

模型比较

模型的最终输出将在具有选定属性的验证数据集上提供最大的准确性。以下代码的输出表明 XGBoost 是赢家,是适合广告 URL 分析的模型。

results=pd.DataFrame({'Model':['LogisticRegression','KNeighbors','XGB'],
                    'Accuracy Score':[acc1,acc2,acc3]})
result_df=results.sort_values(by='Accuracy Score', ascending=False)
result_df=result_df.set_index('Model')
result_df

结论

上述实现有助于我们确定适合广告 URL 的机器学习模型。通过探索性数据分析分析数据的基本结构。我们借助直方图和热图了解了数据集的特征,收集了每个模型的准确度指标,并制作了一个比较表,显示了每个模型的整体准确度。

XGBoost 模型以 96% 的准确率在三个机器学习模型中胜出。KNeighbors 的得分为 94%。逻辑回归是 90%。

关键要点

  • KNeighbors 模型比其他两个模型慢,因为它只输出标签。
  • 逻辑回归不够灵活,无法捕捉更复杂的关系。
  • 其他两个模型比 XGB 模型慢。
  • XGB 具有处理连续数据和分类数据的能力。
  • 综上,XGBoost 模型适用解决 Book-My-Show 问题。
免责声明:作者保留权利,不代表本站立场。如想了解更多和作者有关的信息可以查看页面右侧作者信息卡片。
反馈
to-top--btn