预测模型笔记

2018-01-13 07:55:51来源:cnblogs.com作者:NSGUF人点击

分享
第七城市

预测模型

1、简介

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

2、用SVM建立线性分类器

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

# 1、加载数据import numpy as npimport matplotlib.pyplot as pltinput_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,yX,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将不同类分开。结果如下图:


代码如下:

# 使用SVMfrom sklearn.svm import SVCfrom sklearn.model_selection import train_test_splitX_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_reportprint(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_validationfrom 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 preprocessinglabel_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 SVCparams={'kernel':'rbf','probability':True,'class_weight':'balanced'}classifier=SVC(**params)classifier.fit(X,y)# 4、交叉验证from sklearn.model_selection import cross_val_scoreaccuracy=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=0for 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+1result=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 preprocessinglabel_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_errory_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=0for 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)
第七城市

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台