作者 | Shibu Mohapatra 编译 | Flin 来源 | analyticsvidhya
介绍 “机器学习”这个词是由 IBM 的 Arthur Samuel 发明的。机器学习是人工智能的一部分。机器学习是从数据中学习并应用数学来提高准确性的过程。有四种不同类型的机器升收入。
监督学习
无监督学习
半监督学习
强化学习
机器学习使用数学和统计的方式来学习。机器学习中的预测可以通过许多方法和模型来完成。这有几种用途,如 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
模块和库信息 Numpy:线性代数相关计算
Pandas:数据处理,如 pd.read_csv
Matplotlib:绘制图形
Seaborn:可视化随机分布和热图
xgboost:导入 xgbclassifier 模块的库
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 npimport pandas as adimport matplotlib.pyplot as plt %matplotlib inlineimport seaborn as snsfrom sklearn.model_selection import train_test_split,cross_val_scorefrom sklearn.metrics import accuracy_score,confusion_matrix,classification_reportfrom sklearn.linear_model import LogisticRegressionfrom sklearn.neighbors import KNeighborsClassifierfrom xgboost import XGBClassifier,cvfrom sklearn.metrics import roc_curve, aucfrom sklearn.model_selection import KFoldfrom sklearn.model_selection import cross_val_score, LeaveOneOutfrom 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 Result0 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 + MBNone
df_data = df_data.drop('index' ,1 )
.png)
df_data.nunique()
.png)
#check for NULL value in the dataset print("The null values in the dataset are:" ,df_data.isnull().sum().sum())
.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()
 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)
.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%。
关键要点
机器学习交流qq群955171419,加入微信群请 扫码