如何利用机器学习甄别淘宝优质店铺

文章发布于公号【数智物语】 (ID:decision_engine),关注公号不错过每一篇干货。

转自 | 数据团学社,微信搜索metrodata_xuexi 即可关注


本文约2400字,阅读需要7分钟

关键词:Python sklearn 决策树 KNN 逻辑回归 SVM

本文讲述了使用python分别构建决策树、KNN、逻辑回归、SVM、神经网络共五种不同的模型甄别淘宝优质店铺的过程。


目录

1. 背景知识介绍

2. 数据和工具准备

3. 模型介绍、代码示范和结果比较

4. 调参方法

5. 模型进阶:随机森林

背景知识介绍

在经历数年双十一血拼,双十二剁手之后,作为一名优秀的数据分析师,我觉得我需要研究一下如何精准的定位优质店铺,看穿套路,理性消费。

今天的数据来自于阿里云天池。

这是一份包含2000家店铺的评分,等级,评论等信息和数年交易记录的数据。

数据维度可以查看明细:

通过这份数据,我们可以构建一套选店模型,为即将到来的各种大小节日做准备。这个过程我们将使用sklearn包来完成。

我们要做的事情,就是构建模型,根据店铺的访问、购买信息等数据,来评测该店铺是否为优质店铺。一部分数据将用来作为训练集,另一部分数据会用来测试已经训练好模型的精确度。我们这里将重点关注模型的拟合情况,对每个模型进行调参比较,选出最适合的那一个~

欠拟合指模型没有很好地捕捉到数据特征,不能够很好地拟合数据:

过拟合通俗一点地说就是模型把数据学习的太彻底,以至于把噪声数据的特征也学习到了,这样就会导致在后期测试的时候不能够很好地识别数据,即不能正确的分类,模型泛化能力太差:

数据和工具准备

一组数据到手,清理整合等预处理工作是绕不开的。我们可以得到了一份适合建模使用的样本数据:

准备好数据以后,文末导入所需的包、填充数据空值,再拆分提取训练集测试集数据,并将数据进行标准化,为后续的模型构建做足准备~

训练集(Training Set):帮助我们训练模型,简单的说就是通过训练集的数据让我们确定拟合曲线的参数。 

验证集(Validation Set):用来做模型选择(model selection),即做模型的最终优化及确定的,用来辅助我们的模型的构建,可选。 

测试集(Test Set):用来测试已经训练好的模型的精确度。 

实际应用中,一般只将数据集分成两类,即训练集Training set 和测试集Test set。

既然数据都准备好了,那就开始我的表演~对于每个模型,我都会给出模型介绍代码、简单的调参过程和查看模型结果的混淆矩阵。

*考虑这份数据比较粗糙,我们仅使用0分店铺和4分店铺的数据。

不同模型的构建及其效果

模型一:决策树

#决策树

max_depth_l = [2,3,4,5,6,7,8,9,10]

formax_depthinmax_depth_l:

dt_model = DecisionTreeClassifier(max_depth=max_depth)

dt_model.fit(x_train_scaled,y_train)

train_accuracy = dt_model.score(x_train_scaled,y_train)

test_accuracy = dt_model.score(x_test_scaled,y_test)

print('max depth',max_depth)

print('训练集上的准确率:{:2f}%'.format(train_accuracy*100))

print('测试集上的准确率:{:2f}%'.format(test_accuracy*100))

决策树是一个类似于人们决策过程的树结构,从根节点开始,每个分枝代表一个新的决策事件,会生成两个或多个分枝,每个叶子代表一个最终判定所属的类别。

决策树,需要调节的主要参数是树的深度。深度越浅,容易造成欠拟合;而深度越深,则会过拟合。我们建立一个列表,罗列不同的深度,建立模型进行尝试,最终选择在测试集上表现最好的模型。

我们看到,随着深度的增加,模型在训练集上的准确率越来越高,而在测试集上的效果则越来越差,这是过拟合的表现,而在深度为5的时候,测试集的准确率为73.39,达到最高值,所以这组模型为决策树的最佳模型。

绘制混淆矩阵查看模型效果:

dt_model = DecisionTreeClassifier(max_depth=5)

dt_model.fit(x_train_scaled,y_train)

predictions = dt_model.predict(x_test_scaled)

test_accuracy = dt_model.score(x_test_scaled,y_test)

print(classification_report(y_test,predictions))

print('决策树的准确率:{:2f}%'.format(test_accuracy*100))

cnf_matrix = confusion_matrix(y_test,predictions)

plot_confusion_matrix(cnf_matrix, classes=[0,1],

title='Confusion matrix')

*横坐标是预测值,即“模型认为该店铺为差评/优质店铺”,纵坐标代表真实值,即“该店铺为差评/优质店铺”。0为差评,1为优质

模型在预测优质店铺上容易误杀,把优质店铺预测为差评店铺,错误达到43个,不过店铺茫茫多,错过这个还有下个,本着宁可错杀,不能放过的原则,模型还是可以的。

模型二:KNN

k_values = range(3,13)

fork_valueink_values:

knn_model = KNeighborsClassifier(n_neighbors=k_value)

knn_model.fit(x_train_scaled,y_train)

train_accuracy = knn_model.score(x_train_scaled,y_train)

test_accuracy = knn_model.score(x_test_scaled,y_test)

print('k value:',k_value)

print('训练集上的准确率:{:2f}%'.format(train_accuracy*100))

print('测试集上的准确率:{:2f}%'.format(test_accuracy*100))

K最近邻(k-Nearest Neighbor,KNN)分类算法是最简单的机器学习算法。 KNN算法的指导思想是“近朱者赤,近墨者黑”——由你的邻居来推断出你的类别。

KNN同样需要调节超参数,我们需要选取不同的邻近点个数,调试模型达到最优状态。

参数n_neighbors达到10的时候,效果最棒

knn_model = KNeighborsClassifier(n_neighbors=10)

knn_model.fit(x_train_scaled,y_train)

predictions = knn_model.predict(x_test_scaled)

print(classification_report(y_test,predictions))

accuracy = knn_model.score(x_test_scaled,y_test)

print('KNN预测准确率:{:2f}%'.format(accuracy*100))

cnf_matrix = confusion_matrix(y_test,predictions)

plot_confusion_matrix(cnf_matrix, classes=[0,1],

title='Confusion matrix')

*横坐标是预测值,即“模型认为该店铺为差评/优质店铺”,纵坐标代表真实值,即“该店铺为差评/优质店铺”。0为差评,1为优质

模型在判断差评店铺方面效果比决策树更好,但错杀优质店铺的数量也达到51,好像多了一点。

模型三:逻辑回归

c_list = [0.01,0.1,1,1e1,1e2,1e3,1e4]

forcinc_list:

lg_model = LogisticRegression(C=c)

lg_model.fit(x_train_scaled,y_train)

train_accuracy = lg_model.score(x_train_scaled,y_train)

test_accuracy = lg_model.score(x_test_scaled,y_test)

print('C value:',c)

print('训练集上的准确率:{:2f}%'.format(train_accuracy*100))

print('测试集上的准确率:{:2f}%'.format(test_accuracy*100))

回归分析是一种预测建模技术的方法,研究因变量(目标)和自变量(预测器)之前的关系。逻辑回归是一种广泛应用于分类问题的回归方法。

逻辑回归是一种广义线性回归,原理是在线性回归的结果外套用sigmoid函数,

把输出结果压缩在0-1之间,如果结果>0.5,也就意味着概率大于一半,我们把它判定为1,反之为-1,从而起到分类的作用。

Sklearn的逻辑回归中,默认加入正则化超参数用于防止过拟合。可调节的参数是C,C越小、抵抗过拟合的力度越大;C越大则效果越小,我们也需要根据实际情况调节。

*参数中1e1,1e2……为科学计数法,表示10,100……以此类推

我们看到C在100的时候,效果就已经达到最优,而C越小模型的拟合程度越差,所以并不是任何情况,都需要使用过拟合调节。

lg_model = LogisticRegression(C=100)

lg_model.fit(x_train_scaled,y_train)

predictions = lg_model.predict(x_test_scaled)

print(classification_report(y_test,predictions))

accuracy = lg_model.score(x_test_scaled,y_test)

print('逻辑回归预测准确率:{:2f}%'.format(accuracy*100))

cnf_matrix = confusion_matrix(y_test,predictions)

plot_confusion_matrix(cnf_matrix, classes=[0,1],

title='Confusion matrix')

*横坐标是预测值,即“模型认为该店铺为差评/优质店铺”,纵坐标代表真实值,即“该店铺为差评/优质店铺”。0为差评,1为优质

预测准确率约为70.39%,效果相较于前两个模型要差一点。错杀还是51,也不少~

模型四:支持向量机

c_list = [1,1e1,1e2,1e3,1e4,1e5,1e6]

forcinc_list:

svm_model = SVC(C=c)

svm_model.fit(x_train_scaled,y_train)

train_accuracy = svm_model.score(x_train_scaled,y_train)

test_accuracy = svm_model.score(x_test_scaled,y_test)

print('C value:',c)

print('训练集上的准确率:{:2f}%'.format(train_accuracy*100))

print('测试集上的准确率:{:2f}%'.format(test_accuracy*100))

什么是SVM:支持向量机就是使用一条直线(二维)或超平面(多维)将数据分成两类,同时保证离超平面最近的点与超平面的间隔尽可能小。就像下图那样。

C为惩罚项,同样是为了防止过拟合。不同的C值可以有不同的结果:

svm_model = SVC(C=1e6)

svm_model.fit(x_train_scaled,y_train)

predictions = svm_model.predict(x_test_scaled)

print(classification_report(y_test,predictions))

accuracy = svm_model.score(x_test_scaled,y_test)

print('支持向量机预测准确率:{:2f}%'.format(accuracy*100))

cnf_matrix = confusion_matrix(y_test,predictions)

plot_confusion_matrix(cnf_matrix, classes=[0,1],

title='Confusion matrix')

预测准确率为75.11%,是目前为止效果最好的模型了~

模型五:神经网络

mlp =MLPClassifier(hidden_layer_sizes=(100,50),max_iter=1000,activation='relu')

mlp.fit(x_train_scaled,y_train)

train_accuracy = mlp.score(x_train_scaled,y_train)

test_accuracy = mlp.score(x_test_scaled,y_test)

print('训练集上的准确率:{:2f}%'.format(train_accuracy*100))

print('测试集上的准确率:{:2f}%'.format(test_accuracy*100))

predictions = mlp.predict(x_test_scaled)

cnf_matrix = confusion_matrix(y_test,predictions)

plot_confusion_matrix(cnf_matrix, classes=[0,1],

title='Confusion matrix')

*这个原理比较复杂,文末提供了参考资料供大家阅读~

使用sklearn中BP神经网络的包,建立神经网络模型进行预测,我们可以调节的超参数有神经网络隐藏层的层数,激活函数等。

预测准确率为71.67%,结果一般般吧~

我们用了这么多模型,我相信有同学一定会问,每个模型都有一种甚至数种超参数需要调节,那么哪种排列组合是最佳组合呢?

呵呵~~~这个问题难度有点高哦!如果我说每次都是蒙的,你会信吗?

如何调节超参数

对于模型的超参数调节,并没有固定的套路,通常需要经过数轮尝试和以往的经验才能找到最正确的那个。当然,每次手动调节也确实是一件挺麻烦的事,所以,这里分享一个一劳永逸的方法——网格搜索,交叉验证。

原理很简单,我们把测试集再分成数份作为验证集。比如分成10份,我们叫10折,然后选取一组参数,分别在每个折上进行运行,得到10个结果,求出平均结果作为这一组最后的结果,最后得到最优结果的那一组参数。

好!下面我们来看下具体代码实现过程。

首先建立一个字典,字典里包含我们需要比较的模型,和每个模型中参数的选取范围。

model_dict = {

'Decision Tree':(DecisionTreeClassifier(),

{'max_depth':[2,3,4,5,6,7,8,9,10],}

),

'KNN':(KNeighborsClassifier(),

{'n_neighbors':list(range(1,21)),

'p':[1,2],}

),

'Logistic Regression':(LogisticRegression(),

{'C':[1,1e1,1e2,1e3,1e4,1e5,1e6],}

),

'SVM':(SVC(),

{'C':[1,1e1,1e2,1e3,1e4,1e5,1e6],}

),

'MLP':(MLPClassifier(),

{'hidden_layer_sizes':[(100,50),(100,30),(100,50,30),(100,100)],

'max_iter':[200,500,1000,5000,10000],

'activation':['relu','logistic','tanh']

}

),

}

然后我们使用GridSearchCV,遍历参数,并排列组合,然后再进行交叉验证,选取最佳参数组合。我们采用5折对训练集进行划分:

formodel_name,(model,model_params)inmodel_dict.items():

clf = GridSearchCV(estimator=model,param_grid=model_params,cv=5)

clf.fit(x_train_scaled,y_train)

best_model = clf.best_estimator_

acc = best_model.score(x_test_scaled,y_test)

print('{}模型预测准确率:{:2f}%'.format(model_name,acc*100))

print('{}模型最佳参数:{}'.format(model_name,clf.best_params_))

因为经过了验证集进一步的验证,最后的结果有所变化,神经网络模型的结果为最优结果,并且这里罗列了每个模型的最佳参数组合。

我们使用了5种模型,并通过反复调节,正确率达到了74.3%,显然,这并不是一个十分满意的结果。那么是否还有其他更强大的模型,可以再进一步提升呢?

更强大的模型:随机森林

既然任何的一种模型都达不到要求,那么我们就用许多模型,把他们组合在一起,这叫强强联手。对于这类把许多模型组合在一起,成为一个整体的模型我们称之为集成模型

下面,我使用一种集成模型——随机森林来进一步探索数据。主要原理是构建多棵决策树,每棵决策树都会有一个结果,最后通过投票机制,选出最终结果。

from sklearn.ensemble import RandomForestClassifier

tree_param_grid = {'n_estimators':[10,20,30,50,80],

'min_samples_split':[2,8,10,20,30,50,60,70,80],

'min_samples_leaf':[2,5,10,20,30,50],

'random_state':[2]

}

grid = GridSearchCV(RandomForestClassifier(),param_grid=tree_param_grid,cv=5)

grid.fit(x_train_scaled,y_train)

best_model = grid.best_estimator_

acc1 = best_model.score(x_train_scaled,y_train)

acc2 = best_model.score(x_test_scaled,y_test)

print('随机森林模型训练准确率:{:2f}%'.format(acc1*100))

print('随机森林模型预测准确率:{:2f}%'.format(acc2*100))

print('随机森林模型最佳参数:{}'.format(grid.best_params_))

同样采用交叉验证来调节参数。特别注意的是random_state参数,一定要限定一下随机数种子,否则每次运行模型,采用的是不同的随机数,呈现的结果不同,就无法对比了。

随机森林模型训练准确率:76.559140%

随机森林模型预测准确率:78.111588%

随机森林模型最佳参数:{'min_samples_leaf': 2,'min_samples_split': 70,'n_estimators': 50,'random_state': 2}

从结果上看,有了比较明显的提升,在预测集上达到了78.11%的准确率,对比前面的模型有了较大的提升。

集成模型有很多种,每一种都尝试下,最终的准确率应该可以达到80%。但是,相比起模型,数据更为重要。受限于数据量,数据精度和数据维度,模型离愿望中的90%准确性还有很大的距离。如果有更大的样本,比如2W条数据,更精细的分类,比如score精确到小数点后一位4.0,4.1,4.2……和更多的字段,比如成交金额,成交数量,店铺年份等等,那么模型一定会更精确。

毕竟模型不是魔法,我们讨论的也只是科学而不是玄学。最后,最重要的不是买买买,学到模型才是正事,再来了解下跟模型相关的算法吧。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容