根据手机参数对手机价格进行预测

#---------------------------config文件夹----------------------

import os
import pandas as pd

# 数据集路径
dataset_path = './data'

# 输出集路径
output_path = './output'
if not os.path.exists(output_path):
    os.makedirs(output_path)

#数字数值列
numeric_cols=['battery_power','clock_speed','fc','int_memory','m_dep','mobile_wt',
              'n_cores','pc','px_height','px_width','ram','sc_h','sc_w','talk_time']

#类别数值列  这类是 bool类型的,即是0者来表示的,即是或者否,就用one-hot编码表示成数值型的
cat_cols=['blue', 'dual_sim', 'four_g', 'three_g', 'touch_screen', 'wifi']

#要使用的特征列
feat_cols=numeric_cols+cat_cols

#标签列
label_col='price_range'





#下面只是为了获得行名而已,是辅助的作用
ttt=pd.read_csv('./data/data.csv')
print(ttt.iloc[:0])

data = [[1,2,3],[4,5,6]]
index = ['d','e']
columns=['a','b','c']
df = pd.DataFrame(data=data, index=index, columns=columns)
print (df)
print (df.iloc[:,0])


#---------------------------main.py文件夹---------------------------
'''
任务描述
  建立不同的集成学习模型来进行手机的价格的预测
  并使用交叉验证的方式为每个模型选择最优化的超参数
  
'''
import config
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import time
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder, StandardScaler

from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.ensemble import AdaBoostClassifier, GradientBoostingClassifier, RandomForestClassifier
from mlxtend.classifier import StackingClassifier
from sklearn.model_selection import GridSearchCV

def main():

    #加载数据
    all_data=pd.read_csv(os.path.join(config.dataset_path,'data.csv'))
    train_data,test_data=train_test_split(all_data,test_size=1/3, random_state=10)

    #数据查看
    inspect_dataset(train_data,test_data)

    #构建训练测试数据
    #特征处理
    x_train,x_test=do_feature_engineering(train_data,test_data)
    print('共有{}维特征'.format(x_train.shape[1]))

    #标签处理
    y_train=train_data[config.label_col].values
    y_test=test_data[config.label_col].values


    #数据建模以及验证  很多模型放到一块
    print('================数据建模以及验证=================')

    sclf=StackingClassifier(classifiers=[KNeighborsClassifier(),  #基分类器
                                         SVC(kernel='linear'),    #基分类器
                                         DecisionTreeClassifier()],#基分类器
                            meta_classifier=LogisticRegression()) #提取基分类器权重

    # model_name_param_dict={'KNN':(KNeighborsClassifier(),{'n_neighbors':[5,25,55]}),
    #                        'LR':(LogisticRegression(),{'c':[0.01,1,100]}),
    #                        'SVM':(SVC(kernel='linear'),{'c':[0.01,1,100]}),
    #                        'DT':(DecisionTreeClassifier(),{'max_depth':[50,100,150]}),
    #                        'Stacking':(sclf,{'kneighborsclassifier__n_neighbors': [5, 25, 55],
    #                                        'svc_C': [0.01, 1, 100],
    #                                        'decisiontreeclassifier__max_depth': [50, 100, 150],
    #                                        'meta-logisticregression__C': [0.01, 1, 100]}),
    #                        'AdaBoost': (AdaBoostClassifier(),
    #                                     {'n_estimators': [50, 100, 150, 200]}),
    #                        'GBDT': (GradientBoostingClassifier(),
    #                                 {'learning_rate': [0.01, 0.1, 1, 10, 100]}),
    #                        'RF': (RandomForestClassifier(),
    #                               {'n_estimators': [100, 150, 200, 250]})
    #                           }

    #对分类器指定超参数
    model_name_param_dict = {'kNN': (KNeighborsClassifier(),
                                     {'n_neighbors': [5, 25, 55]}),
                             'LR': (LogisticRegression(),
                                    {'C': [0.01, 1, 100]}),
                             'SVM': (SVC(kernel='linear'),
                                     {'C': [0.01, 1, 100]}),
                             'DT': (DecisionTreeClassifier(),
                                    {'max_depth': [50, 100, 150]}),
                             'Stacking': (sclf,
                                          {'kneighborsclassifier__n_neighbors': [5, 25, 55],  #注意拼写别错了
                                           'svc__C': [0.01, 1, 100],
                                           'decisiontreeclassifier__max_depth': [50, 100, 150],
                                           'meta-logisticregression__C': [0.01, 1, 100]}),
                             'AdaBoost': (AdaBoostClassifier(),
                                          {'n_estimators': [50, 100, 150, 200]}),  #分类器的个数
                             'GBDT': (GradientBoostingClassifier(),
                                      {'learning_rate': [0.01, 0.1, 1, 10, 100]}),
                             'RF': (RandomForestClassifier(),
                                    {'n_estimators': [100, 150, 200, 250]})}  #树的个数

    # 比较结果的DataFrame
    #新建一个空的dataframe用于存放个模型的时间准确度
    results_df = pd.DataFrame(columns=['Accuracy (%)', 'Time (s)'],
                              index=list(model_name_param_dict.keys()))
    results_df.index.name = 'Model'

    for model_name, (model, param_range) in model_name_param_dict.items():
        best_clf, best_acc, mean_duration = train_model(x_train, y_train, x_test, y_test,
                                                        model_name, model, param_range)
        results_df.loc[model_name, 'Accuracy (%)'] = best_acc * 100
        results_df.loc[model_name, 'Time (s)'] = mean_duration

    results_df.to_csv(os.path.join(config.output_path, 'model_comparison.csv'))

    # 模型及结果比较
    print('\n===================== 模型及结果比较 =====================')

    plt.figure(figsize=(10, 4))
    ax1 = plt.subplot(1, 2, 1)
    #注意下面的绘制图像的简单的方法,可以直接dataframe类型的.plot
    results_df.plot(y=['Accuracy (%)'], kind='bar', ylim=[50, 100], ax=ax1, title='Accuracy(%)', legend=False)

    ax2 = plt.subplot(1, 2, 2)
    results_df.plot(y=['Time (s)'], kind='bar', ax=ax2, title='Time (s)', legend=False)
    plt.tight_layout()
    plt.savefig(os.path.join(config.output_path, './pred_results.png'))
    plt.show()





def inspect_dataset(train_data,test_data):
    '''
     查看数据集
    '''
    print('=====================数据查看====================')
    print('训练集共有{}条数据'.format(len(train_data)))
    print('测试集共有{}条数据'.format(len(test_data)))
    #可视化个类别的数量统计图
    plt.figure(figsize=(10,5))
    #训练集
    ax1=plt.subplot(1,2,1)
    sns.countplot(x='price_range',data=train_data)  #统计train_data总数据中price_range列中每个每个数字的个数
    plt.title('Training_Data')
    # plt.xticks(rotation='vertical')
    plt.xlabel('Price Range')
    plt.ylabel('Count')


    #测试集
    ax1=plt.subplot(1,2,2,sharey=ax1)
    sns.countplot(x='price_range',data=test_data)  #统计train_data总数据中price_range列中每个每个数字的个数
    plt.title('Test_Data')
    # plt.xticks(rotation='vertical')
    plt.xlabel('Price Range')
    plt.ylabel('Count')
    plt.show()


def do_feature_engineering(train_data,test_data):
    '''
     特征工程:处理训练集和测试集中的特征
     1,类别特征,使用独热编码
     2,数值特征 使用标准化或者归一化
     
    '''
    #类别特征
    trn_cat_feats=train_data[config.cat_cols].values
    tes_cat_feats=test_data[config.cat_cols].values

    #数值特征
    trn_numeric_feats=train_data[config.numeric_cols]
    tes_numeric_feats=test_data[config.numeric_cols]

    #独热编码  对类别特征进行独热编码然后添加到数值特征汇总,作为总的特征
    enc=OneHotEncoder(sparse=False)  #返回的是稀疏矩阵,不能用在模型中  sparse=False可以变成正常矩阵
    enc_trn_cat_feats=enc.fit_transform(trn_cat_feats)
    enc_tes_cat_feats=enc.transform(tes_cat_feats)

    trn_all_feats=np.hstack((trn_numeric_feats,enc_trn_cat_feats))  #合并在一块
    tes_all_feats=np.hstack((tes_numeric_feats,enc_tes_cat_feats))  #合并在一块

    #标准化 类似归一化
    std_scaler=StandardScaler()
    scaler_trn_all_feats=std_scaler.fit_transform(trn_all_feats)
    scaler_tes_al_feats=std_scaler.transform(tes_all_feats)
    return scaler_trn_all_feats,scaler_tes_al_feats




def train_model(x_train, y_train, x_test, y_test, model_name, model, param_range):
    """

        根据给定的参数训练模型,并返回
        1. 最优模型
        2. 平均训练耗时
        3. 准确率
    """
    print('训练{}...'.format(model_name))
    clf = GridSearchCV(estimator=model,
                       param_grid=param_range,
                       cv=5,  #五折训练
                       scoring='accuracy',
                       refit=True)  #默认就是TRUE   意思是交叉验证后又吧全部数据训练了一边
    start = time.time()
    clf.fit(x_train, y_train)
    # 计时
    end = time.time()
    duration = end - start
    print('耗时{:.4f}s'.format(duration))

    # 验证模型
    print('训练准确率:{:.3f}'.format(clf.score(x_train, y_train)))
   #有训练准确率和测试准确率
    score = clf.score(x_test, y_test)
    print('测试准确率:{:.3f}'.format(score))
    print('训练模型耗时: {:.4f}s'.format(duration))
    print()

    return clf, score, duration









main()











 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值