用分类算法预测手机价格区间,用网格搜索调参
文章目录
- 前言
- 一、了解数据
- 二、建立模型前准备
- 1.分训练集测试集
- 2.定义一个函数输出每个算法的结果
- 3.网格搜索优化算法
- 二、建立模型
- 1.逻辑回归模型
- 2. KNN
- 3. 决策森林
- 4. 随机森林
- 总结
前言
数据为二手手机的各个性能的数据,最后根据这些性能得到3个价格区间,作为这些二手手机售出的价格区间。
注意:该数据集已经经过预处理,可以直接用于预测价格区间。
一、了解数据
battery_power:电池一次可储存的总能量,单位为毫安时
blue :是否有蓝牙
clock_speed:微处理器执行指令的速度
dual_sim:是否支持双卡
fc:前置摄像头百万像素
four_g:是否有4G
int_memory:内存(GB)
m_dep:移动深度(cm)
mobile_wt:手机重量
n_cores:处理器内核数
pc:主摄像头百万像素
px_height:像素分辨率高度
px_width:像素分辨率宽度
ram:随机存取存储器(兆字节)
sc_h:手机屏幕高度(cm)
sc_w:手机屏幕宽度(cm)
talk_time:一次电池充电持续时间最长的时间
three_g:是否有3G
touch_screen:是否有触控屏
wifi:是否能连wifi
price_range:价格区间(0,1,2,3)
用describe()看每个特征的描述统计:


二、建立模型前准备
1.分训练集测试集
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report,confusion_matrix#X为特征数据,y为结果数据
X=df.drop('price_range',axis=1)
y=df['price_range']X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=101)
2.定义一个函数输出每个算法的结果
#定义模型计算,之后调用模型,输出预测结果和预测准确性分数
def model_evl(algo):algo_model = algo.fit(X_train, y_train)global y_predy_pred = algo_model.predict(X_test)#confusion_matrix混淆矩阵,主要用于比较分类结果和实际测的值print('\nConfusion Matrix:\n {}'.format(confusion_matrix(y_test,y_pred)))print("--"*20)print(classification_report(y_test,y_pred))
这里有两个知识点:
1、confusion_matrix(混淆矩阵)
混淆矩阵把各标签的真实值(Truth)放到横向,把各标签的预测值(Predicted)放到纵向,形成矩阵中可视化出来,便于比较。

如图所示,混淆矩阵的对角线为预测正确的数,其余的为预测错误。图中显示有4个样本真实是混凝土(Concrete),但是被模型预测为沥青(Asphalt)。
2、classification_report(分类模型评估报告):
以逻辑回归的分类模型评估报告(—分割线后)为例子:

- support:当前行的类别在测试数据中的样本总量,如上表就是,在class 0 类别在测试集中总数量为115;
- precision:精度,即模型预测的结果中有多少是预测正确的
- recall:召回率,就是某个类别测试集中的总量,有多少样本预测正确了;
- f1-score:F1 = 2 x 精度 x 召回率/(精度+召回率)
- accuracy:计算所有数据下的指标值,假设全部数据 5 个样本中有 3 个预测正确,所以 accuracy 为 375/500=0.75
- macro avg:每个类别评估指标未加权的平均值,比如准确率的 macro avg,(0.81+0.68+0.80+0.71)/4=0.75
- weighted avg:加权平均,就是测试集中样本量大的,我认为它更重要,给他设置的权重大点;比如第一个值的计算方法,(0.81x115+0.68x122+0.80x152+0.71x111)/500=0.75304
3.网格搜索优化算法
网格搜索可以实现自动调参,非常适用于小数据集,大数据集可能会耗时较长。
def optimal_alg(classifier,param_grid):model=GridSearchCV(classifier,param_grid=param_grid,cv=5)model.fit(X_train, y_train)print('训练集数据交叉验证下最好的预测分数: ',model.best_score_)print('该网格搜索找到的最佳参数: ',model.best_params_)print('在训练集/测试集的最好预测分数:{:.3f}'.format(model.score(X_test,y_test)))
二、建立模型
这里会运用四个典型的分类模型,回顾算法原理和解读重要参数,并选择重要参数进行网格搜索调参:
- 逻辑回归模型
- KNN模型
- 决策树模型
- 随机森林模型
1.逻辑回归模型
逻辑回归使用的是Sigmoid函数,并将预测值映射为(0, 1)上的概率值,帮助判断结果。

没有给模型加任何参数
from sklearn.linear_model import LogisticRegression
print('Logistic Regression\n')
classifier = LogisticRegression()
model_evl(classifier)

逻辑回归重要参数:
1、penalty(惩罚项、正则项):
可选参数:{“L1”,“L2”}
2、solver(优化算法方法):
可选参数:{”liblinear“,”sag“,“saga”,“newton-cg”,“lbfgs”}
- liblinear(默认):使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。
- lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
- newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
- sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅用一部分的样本来计算梯度,适合于样本数据多的时候。
- saga:快速梯度下降法,线性收敛的随机优化算法的的变种。
如何选择:
- 对于小数据集来说,“liblinear”是个不错的选择,而“sag”和’saga’对于大型数据集会更快。
- 对于多类问题,只有newton-cg, sag
- saga和lbfgs可以处理多项损失
- liblinear仅限于one-versus-rest分类。
- 如果是L2正则化,那么4种可选的算法{‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’}都可以选择。但是如果penalty是L1正则化的话,就只能选择‘liblinear’了。
3、multi_class(分类方式选择参数):
可选参数:{“ovr”,“auto”}。(旧版本Skleran)
网格搜索优化后
parameters_grid= {'solver':['liblinear', 'newton-cg', 'lbfgs', 'sag', 'saga'],'multi_class':["ovr","auto"]}
optimal_alg(classifier,parameters_grid)
训练集数据交叉验证下最好的预测分数: :0.966
该网格搜索找到的最佳参数: {‘multi_class’: ‘auto’, ‘solver’: ‘newton-cg’}
在训练集/测试集的最好预测分数:0.944
2. KNN
当预测一个新的值x的时候,根据它距离最近的K个点是什么类别来判断x属于哪个类别。
没有给模型加任何参数
from sklearn.neighbors import KNeighborsClassifier
print('KNN\n')
model_evl(KNeighborsClassifier())

KNN在不用调参的时候就已经有很好的效果了。
KNN重要参数:
1、n_neighbors(指 KNN 中的K,用于查询邻居数):
默认为5,可以选择其他整数
2、weights(权重):
可选参数:{”uniform“,”distance“,其他自定义函数}。
- 默认是uniform,uniform是均等的权重,就说所有的邻近点的权重都是相等的
- distance是不均等的权重,距离近的点比距离远的点的影响大。用户自定义的函数,接收距离的数组,返回一组维数相同的权重。
网格搜索优化后
parameters_grid= {'n_neighbors':range(4,10),"weights":["uniform","distance"]}
optimal_alg(classifier,parameters_grid)
训练集数据交叉验证下最好的预测分数: :0.927
该网格搜索找到的最佳参数: {‘n_neighbors’: 9, ‘weights’: ‘distance’}
在训练集/测试集的最好预测分数:0.938
这里看到即使调参了也没有很大的提升。
3. 决策森林
决策树模型是一种树形结构,由一系列节点组成,每一个节点代表一个特征和相应的决策规则。是基于特征对实例进行分类或回归的过程,即根据某个特征把数据分划分到若干个子区域(子树),再对子区域递归划分,直到满足某个条件则停止划分并作为叶子节点,不满足条件则继续递归划分。

没有给模型加任何参数
from sklearn.tree import DecisionTreeClassifier
print('Decision Tree\n')
model_evl(DecisionTreeClassifier())

决策树重要参数:
1、criterion(特征选择标准):
可选参数:{”entropy“,”gini“},默认gini,即CART算法。
2、splitter(控制决策树中的随机选项)
可选参数:{”best“,”random“},默认best,优先选择更重要的特征进行分枝,random使决策树在分枝时会更加随机,降低对训练集的拟合。
3、max_depth(最大深度):
限制树的最大深度,超过设定深度的树枝全部剪掉
4、max_features(划分时考虑的最大特征数):
默认是"None",意味着划分时考虑所有的特征数。如果特征数非常多,我们可以只考虑的部分特征,以控制决策树的生成时间
5、min_impurity_decrease(节点划分最小不纯度):
默认为0,这个值限制了决策树的增长,如果某节点的不纯度(基尼系数,信息增益,均方差,绝对差)小于这个阈值,则该节点不再生成子节点。
6、min_samples_split:(内部节点再划分所需最小样本数)
一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝,否则分枝就不会发生
parameters_grid= {'criterion':["gini","entropy"],"splitter":["best","random"],'max_depth':range(4,10),"max_features":range(10,21),"min_impurity_decrease":np.linspace(0,0.2,10),'min_samples_split':range(2,10,2)}optimal_alg(classifier,parameters_grid)
训练集数据交叉验证下最好的预测分数: :0.855
该网格搜索找到的最佳参数: {‘criterion’: ‘gini’, ‘max_depth’: 7, ‘max_features’: 17, ‘min_impurity_decrease’: 0.0, ‘min_samples_split’: 6, ‘splitter’: ‘best’}
在训练集/测试集的最好预测分数:0.856
这里看到即使调参了也没有很大的提升。
4. 随机森林
随机森林是一个包含多个决策树的分类器, 并且其输出的类别是由个别树输出的类别的众数而定。

没有给模型加任何参数
from sklearn.ensemble import RandomForestClassifier
print('Random Forest\n')
classifier = RandomForestClassifier()
model_evl(classifier)

通常来说,随机森林都会比决策树的效果要好一点。
随机森林重要参数:
因为随机森林包含多个决策树,所以其参数与和决策树的参数都很多相似之处。
1、n_estimators(决策树的数量):
默认是100,这个参数的数量越大,模型的效果越好。
2、bootstrap(随机抽样方式是否为有放回):
可选参数:{”True“,”False“},默认True,即采用有放回的随机抽样技术。
其余的max_features、min_impurity_decrease也是比较重要的,可参考决策树重要参数
parameters_grid= {'n_estimators':range(5,11),"max_features":range(4,10),'max_depth':range(4,10)}
optimal_alg(classifier,parameters_grid)
训练集数据交叉验证下最好的预测分数: :0.901
该网格搜索找到的最佳参数: {‘bootstrap’: ‘True’, ‘max_features’: 11, ‘n_estimators’: 90}
在训练集/测试集的最好预测分数:0.888
随机森林在调参后有不错的提升,但是运行时间较慢。
同时分享一个在知乎上看到的关于随机森林的调参建议:
首先增大n_estimators,提高模型的拟合能力,当模型的拟合能力没有明显提升的时候,则在增大max_features,提高每个子模型的拟合能力,则相应的提高了模型的拟合能力。
总结
针对该数据集,KNN在用默认参数的时候就有很好的效果,即使用了网格搜索变化也不大,建议用KNN或者网格搜索后,调了参的逻辑回归。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
