• 3、预测模型笔记


    预测模型

    1、简介

    预测建模(Predictive modeling)是一种用来预测系统未来行为的分析技术,它由一群能够识别独立输入变量与反馈目标关联关系的算法构成。根据观测值创建一个数学模型,然后用这个模型去预测未来发生的事情。
    预测模型是用若干个可能对系统行为产生影响的特征构建的,当处理系统问题时,需要先判断哪些因素可能会影响系统的行为,然后在训练模型之前将这些因素添加进特征中。

    2、用SVM建立线性分类器

    SVM是用来构建分类器和回归器的监督学习模型,SVM通过对数学方程组求解,可以找出两组数据之间的最佳分割边界。下面先使用第2章的创建简单分类器将数据分类并画出。

    # 1、加载数据
    import numpy as np
    import matplotlib.pyplot as plt
    input_file = 'data_multivar.txt'
    
    def load_data(input_file):
        X = []
        y = []
        with open(input_file, 'r') as f:
            for line in f.readlines():
                data = [float(x) for x in line.split(',')]
                X.append(data[:-1])
                y.append(data[-1])
        X=np.array(X)
        y = np.array(y)
        return X,y
    X,y=load_data(input_file)
    
    # 2、分类
    class_0=np.array([X[i] for i in range(len(X)) if y[i]==0])
    class_1=np.array([X[i] for i in range(len(X)) if y[i]==1])
    print(class_0)
    # 3、画图
    plt.figure()
    plt.scatter(class_0[:,0],class_0[:,1],facecolor='black',edgecolors='black',marker='s')
    plt.scatter(class_1[:,0],class_1[:,1],facecolor='none',edgecolors='black',marker='s')
    plt.show()
    
    # 定义画图函数
    def plot_classifier(classifier, X, y):
        # 获取x,y的最大最小值,并设置余值
        x_min, x_max = min(X[:, 0]) - 1.0, max(X[:, 0] + 1.0)
        y_min, y_max = min(X[:, 1]) - 1.0, max(X[:, 1] + 1.0)
        # 设置网格步长
        step_size = 0.01
        # 设置网格
        x_values, y_values = np.meshgrid(np.arange(x_min, x_max, step_size), np.arange(y_min, y_max, step_size))
        # 计算出分类器的分类结果
        mesh_output = classifier.predict(np.c_[x_values.ravel(), y_values.ravel()])
        mesh_output = mesh_output.reshape(x_values.shape)
        # 画图
        plt.figure()
        # 选择配色方案
        plt.pcolormesh(x_values, y_values, mesh_output, cmap=plt.cm.gray)
        # 画点
        plt.scatter(X[:, 0], X[:, 1], c=y, s=80, edgecolors='black', linewidths=1, cmap=plt.cm.Paired)
        # 设置图片取值范围
        plt.xlim(x_values.min(), x_values.max())
        plt.ylim(y_values.min(), y_values.max())
        # 设置x与y轴
        plt.xticks((np.arange(int(min(X[:, 0]) - 1), int(max(X[:, 0]) + 1), 1.0)))
        plt.yticks((np.arange(int(min(X[:, 1]) - 1), int(max(X[:, 1]) + 1), 1.0)))
        plt.show()
    

    如图:

    从上面的结果可以看出,空心和实心分别为不同类。下面使用SVM将不同类分开。结果如下图:


    代码如下:

    # 使用SVM
    from sklearn.svm import SVC
    from sklearn.model_selection import train_test_split
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=5)
    params = {'kernel': 'linear'}
    classifier = SVC(**params)
    # 训练线性SVM分类器,并查看结果边界
    classifier.fit(X_train, y_train)
    plot_classifier(classifier, X_train, y_train)
    # 测试数据集
    y_test_pred = classifier.predict(X_test)
    plot_classifier(classifier, X_test, y_test)
    # 查看数据的精准性,训练数据集的分类报告
    from sklearn.metrics import classification_report
    print(classification_report(y_train,classifier.predict(X_train),target_names=['Class-'+str(int(i)) for i in set(y)]))
    # 测试数据集的分类报告
    print(classification_report(y_test,classifier.predict(X_test),target_names=['Class-'+str(int(i)) for i in set(y)]))
    

    3、用SVM建立非线性分类器

    从上面的分类报告可知,我们的分类情况并不理想,而且,最开始的数据可视化也可看出,实心完全被空心包围着,所以,我们需要尝试非线性分类器。
    SVM为建立非线性分类器提供了许多选项,需要用不同的核函数建立费线性分类器。为了简单起见,考虑一下两种情况。

    3.1、多项式函数

    直接将线性中的params={'kernel':'linear'}替换成params={'kernel':'poly','degree':3},其中degree表示三次多项式,随着次数增加,可让曲线变得更弯,但是训练时间也会越长,计算强度越大。结果如下图:

    3.2、径向基函数(Radial Basis Function,RBF)

    直接将线性中的params={'kernel':'linear'}替换成params={'kernel':'rbf'},结果如下图:

    4、解决类型数量不平衡问题

    在现实生活中,我们得到的数据可能会出现某类数据比其他类型数据多很多的情况,在这种情况下分类器会有偏差,边界线也不会反应数据的真实性,所以需要对数据进行调和。
    换一个数据,以上面线性SVM为例,将数据换成data_multivar_imbalance.txt之后,显示为

    由图可知,没有边界线,这是因为分类器不能区分这两种类型,所以,将参数改为params={'kernel':'linear','class_weight':'balanced'}即可。结果如下:

    5、提取置信度

    当一个信的数据点被分类为某一个已知类别时,我们可训练SVM来计算输出类型的置信度。

    input_datapoints = np.array([[2, 1.5], [8, 9], [4.8, 5.2], [4, 4], [2.5, 7], [7.6, 2], [5.4, 5.9]])
    
    for i in input_datapoints:
        print(i, '-->', classifier.decision_function(i)[0])# 测量点到边界的距离
    
    params = {'kernel': 'rbf', 'probability': True}
    classifier = SVC(**params)
    classifier.fit(X_train, y_train)
    
    for i in input_datapoints:
        print(i, '-->', classifier.predict_proba(i)[0])# 这里要求params中probability必须为True,计算输入数据点的置信度
    
    plot_classifier(classifier, input_datapoints, [0]*len(input_datapoints))
    

    6、寻找最优超参数

    超参数对分类器的性能至关重要。寻找步骤如下:

    # 1、加载数据,通过交叉验证
    parameter_grid = [{'kernel': ['linear'], 'C': [1, 10, 50, 600]},
                      {'kernel': ['poly'], 'degree': [2, 3]},
                      {'kernel': ['rbf'], 'gamma': [0.01, 0.001], 'C': [1, 10, 50, 600]},
                      ]
    
    metrics = ['precision', 'recall_weighted']
    
    from sklearn import svm, grid_search, cross_validation
    from sklearn.metrics import classification_report
    # 2、为每个指标搜索最优超参数
    for metric in metrics:
        classifier = grid_search.GridSearchCV(svm.SVC(C=1), parameter_grid, cv=5, scoring=metric)# 获取对象
        classifier.fit(X_train, y_train)# 训练
        for params, avg_score, _ in classifier.grid_scores_:# 看指标得分
            print(params, '-->', round(avg_score, 3))
        print('最好参数集:',classifier.best_params_)# 最优参数集
        y_true, y_pred = y_test, classifier.predict(X_test)
        print(classification_report(y_true, y_pred))# 打印一下性能报告
    

    7、建立时间预测器

    这个例子和之前的差不多,主要是记住步骤。

    # 1、读取数据
    input_file='building_event_multiclass.txt'
    # input_file='building_event_binary.txt'
    
    X=[]
    y=[]
    with open(input_file,'r') as f:
        for line in f.readlines():
            data=line[:-1].split(',')
            X.append([data[0]]+data[2:])
    X=np.array(X)
    # 2、编码器编码
    from sklearn import preprocessing
    label_encoder=[]
    X_encoder=np.empty(X.shape)
    for i,item in enumerate(X[0]):
        if item.isdigit():
            X_encoder[:,i]=X[:,i]
        else:
            label_encoder.append(preprocessing.LabelEncoder())
            X_encoder[:,i]=label_encoder[-1].fit_transform(X[:,i])
    X=np.array(X_encoder[:,:-1]).astype(int)
    y=np.array(X_encoder[:,-1]).astype(int)
    # 3、进行分类
    from sklearn.svm import SVC
    params={'kernel':'rbf','probability':True,'class_weight':'balanced'}
    classifier=SVC(**params)
    classifier.fit(X,y)
    # 4、交叉验证
    from sklearn.model_selection import cross_val_score
    accuracy=cross_val_score(classifier,X,y,scoring='accuracy',cv=3)
    print('accuracy:',accuracy.mean())
    # 5、对新数据进行验证
    input_data = ['Tuesday', '12:30:00','21','23']
    input_data_encoder=[-1]*len(input_data)
    count=0
    
    for i,item in enumerate(input_data):
        if item.isdigit():
            input_data_encoder[i]=int(input_data[i])
        else:
            label=[]
            label.append(input_data[i])
            input_data_encoder[i]=label_encoder[count].transform(label)
            count=count+1
    
    result=int(classifier.predict(np.array(input_data_encoder)))
    print('result:',label_encoder[-1].inverse_transform(result))
    

    8、估算交通流量

    在之前的SVM都是用作分类器,现在展示一个回归器的例子:

    # 1、获取数据
    X=[]
    input_file='traffic_data.txt'
    with open(input_file,'r') as f:
        for line in f.readlines():
            data=line[:-1].split(',')
            X.append(data)
    
    X=np.array(X)
    
    # 2、编码
    from sklearn import preprocessing
    label_encoder=[]
    X_encoder=np.empty(X.shape)
    for i,item in enumerate(X[0]):
        if item.isdigit():
            X_encoder[:,i]=X[:,i]
        else:
            label_encoder.append(preprocessing.LabelEncoder())
            X_encoder[:,i]=label_encoder[-1].fit_transform(X[:,i])
    
    X=X_encoder[:,:-1].astype(int)
    y=X_encoder[:,-1].astype(int)
    
    # 3、线性回归
    from sklearn.svm import SVR
    # params = {'kernel': 'rbf', 'C': 10.0, 'epsilon': 0.2}
    params={'kernel':'rbf','C':10.0,'epsilon':0.2}# C表示对分类的惩罚,参数epsilon表示不使用惩罚的限制
    regressor=SVR(**params)
    regressor.fit(X,y)
    # 4、验证
    from sklearn.metrics import mean_absolute_error
    y_pred=regressor.predict(X)
    print('mean_absolute_error:',mean_absolute_error(y,y_pred))
    # 5、预测新值
    input_data = ['Tuesday', '13:35', 'San Francisco', 'yes']
    input_data_encoder=[-1]*len(input_data)
    count=0
    for i,item in enumerate(input_data):
        if item.isdigit():
            input_data_encoder[i]=int(input_data[i])
        else:
            label=[]
            label.append(input_data[i])
            input_data_encoder[i]=int(label_encoder[count].transform(label))
            count=count+1
            
    result=regressor.predict(input_data_encoder)
    print(result)
    文章来源:NSGUF,欢迎分享,转载请保留出处
  • 相关阅读:
    【转】读《冰鉴》有感:职场生存术——企业观人十一招
    [转]msn主要端口问题
    关于linux下的openmp编程基础[转]
    C#运用正则表达式智能获取html模版页中模版信息的应用
    获取当前程序文件的路径
    ASP对UTF8编码支持有问题
    论.NET反射、委托技术与设计模式关系
    序列化与反序列化
    利用反射将数据读入实体类
    随心所欲操作Enum枚举类型
  • 原文地址:https://www.cnblogs.com/NSGUF/p/8278119.html
Copyright © 2020-2023  润新知