完整代码和数据地址:https://download.youkuaiyun.com/download/qq475225253/87880725
什么是“众包任务”,就是一个app在上面发送任务,众多注册的会员可以在上面领取任务,完成后就可以后相应金额的奖励。任务很简单,例如去采集当地或附近的一些商品的价格。有点类似市场调查,让注册用户去帮我们实地拍照上传调查数据。
但我们现在手头有两张表,附件一是已完成项目任务数据,附件二会员信息数据。附件一中的价格是我们初始人工定义的,执行一段时间后,发现还是有很多任务没有被完成。那如何来优化这些任务价格,使得未完成的任务会较大概率被完成呢?这就是我们今天要解决的问题。
一、可视化原始数据
拿到附件一和附件二后,我们可能首先想看下这些会员和任务之间的地理关系,由此分析出一些内部关联。
1、安装Folium
Folium是一个地理信息可视化包,也就是有了它,待会我们就可以在地图上描点,并展示出来。安装命令:pip install folium
2、编写代码将会员和任务的地理信息展示出来
import pandas as pd
A=pd.read_excel('附件一:已结束项目任务数据.xls')
B=pd.read_excel('附件二:会员信息数据.xlsx')
#2.导入地图可视化包
import folium as f
#利用map函数创建地图,参数依次为地图中心位置(纬度,经度)、地图缩放大小、地理坐标系编码
M=f.Map([A.iloc[0,1],A.iloc[0,2]],zoom_start=14,crs='EPSG3857')
#利用Circle函数在地图上画圆圈,参数依次为半径大小(单位:米)、圆心位置(纬度、经度)、颜色…
for t in range(len(A)):
f.Circle(radius=50, location=[A.iloc[t,1],A.iloc[t,2]], color='black',
fill=True, fill_color='black').add_to(M)
for t in range(len(B)):
f.Circle(radius=50, location=[B.iloc[t,1],B.iloc[t,2]], color='red',
fill=True, fill_color='red').add_to(M)
#3.保存地图,html文件,可以在浏览器打开,比如360极速浏览器
M.save('f.html')
二、确定任务价格的因素
任务定价和那些因素有关呢?比如一定范围内,如果会员越多,价格可以更低。比如6点半接单的兴趣没有8点接单的兴趣高。等等。我们从中选出12个与定价有关的因素,如下图:
写代码,算出12个因素的值
# -*- coding: utf-8 -*-
import pandas as pd #导入pandas库
import numpy as np #导入nmypy库
import math #导入数学函数模
import fun #导入定义的函数
A=pd.read_excel('附件一:已结束项目任务数据.xls')
B=pd.read_excel('附件二:会员信息数据.xlsx')
Z=np.zeros((len(A),13))
for t in range(len(A)):
A_Wt=A.iloc[t,1] #第t个任务的维度
A_Jt=A.iloc[t,2] #第t个任务的经度
D1=np.zeros(len(A))
D2=np.zeros(len(B))
for i in range(len(A)):
A_Wi=A.iloc[i,1] #第i个任务的维度
A_Ji=A.iloc[i,2] #第i个任务的经度
d1=111.19*math.sqrt((A_Wt-A_Wi)**2+(A_Jt-A_Ji)**2*
math.cos((A_Wt+A_Wi)*math.pi/180)**2);
D1[i]=d1
for k in range(len(B)):
B_Wk=B.iloc[k,1] #第k个会员的维度
B_Jk=B.iloc[k,2] #第k个会员的经度
d2=111.19*math.sqrt((A_Wt-B_Wk)**2+(A_Jt-B_Jk)**2*
math.cos((A_Wt+B_Wk)*math.pi/180)**2);
D2[k]=d2
Z[t,0]=t
Z[t,1]=len(D1[D1<=5])
Z[t,2]=A.iloc[D1<=5,3].mean()
Z[t,3]=len(D2[D2<=5])
Z[t,4]=B.iloc[D2<=5,5].mean()
Z[t,5]=B.iloc[D2<=5,3].sum()
Z[t,6]=B.iloc[fun.find_I(6,30,6,30,D2,B),3].sum()
Z[t,7]=B.iloc[fun.find_I(6,33,6,45,D2,B),3].sum()
Z[t,8]=B.iloc[fun.find_I(6,48,7,3,D2,B),3].sum()
Z[t,9]=B.iloc[fun.find_I(7,6,7,21,D2,B),3].sum()
Z[t,10]=B.iloc[fun.find_I(7,24,7,39,D2,B),3].sum()
Z[t,11]=B.iloc[fun.find_I(7,42,7,57,D2,B),3].sum()
Z[t,12]=B.iloc[fun.find_I(8,0,8,0,D2,B),3].sum()
np.save('Z',Z)
三、建模
根据附件一中已完成的任务对应的特征和定价建模,未完成的任务根据特征预测出优化后的价格是多少
1、空值处理
import numpy as np
import pandas as pd
Z=np.load('Z.npy')
Data=pd.DataFrame(Z[:,1:])
Data=Data.fillna(0)
R=Data.corr()
2、数据标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
data=Data.as_matrix() #数据框转化为数组形式
scaler.fit(data)
data=scaler.transform(data)
3、特征之间的相关性分析
上面构造的特征之间可能存在这相关性,如果存在,我们是不能直接拿来建模的,需要使用主成分分析消除相关性。
R=Data.corr()
从数据来看存在着很强的相关性,所以我们要做主成分分析,用新的特征来代替原来的12个特征。在保证90%特征不变的情况下,新的特征只需要6个就可以了
from sklearn.decomposition import PCA
pca=PCA(n_components=0.9) #累计贡献率提取90%以上
pca.fit(data)
x=pca.transform(data) #返回主成分
tzxl=pca.components_ #特征向量
tz=pca.explained_variance_ #特征值
gxl=pca.explained_variance_ratio_ #累计贡献率
4、线性回归分析试探
我们首先使用线性回归分析特征和定价之间的关系,但发现它的判定系数Slr只有0.5,属于线性关系很弱,所以不适合使用线性回归模型进行建模。
A=pd.read_excel('附件一:已结束项目任务数据.xls')
A4=A.iloc[:,4].values
x_0=x[A4==0,:] #未执行任务主成分数据
x_1=x[A4==1,:] #执行任务主成分数据
y=A.iloc[:,3].values
y=y.reshape(len(y),1)
y_0=y[A4==0]#未执行任务定价数据
y_1=y[A4==1]#执行任务定价数据
from sklearn.linear_model import LinearRegression as LR
lr = LR() #创建线性回归模型类
lr.fit(x_1, y_1) #拟合
Slr=lr.score(x_1,y_1) # 判定系数 R^2
c_x=lr.coef_ # x对应的回归系数
c_b=lr.intercept_ # 回归系数常数项
print('判定系数: ',Slr)
5、使用神经网路建模
使用神经网路建模和已经完成的任务数据进行建模,并对未完成的任务,根据特征预测出他们的优化定价值。拟合优度是0.7,虽不是特别好,但比线性回归的0.5要强一些。
from sklearn.neural_network import MLPRegressor
#两个隐含层300*5
clf = MLPRegressor(solver='lbfgs', alpha=1e-5,hidden_layer_sizes=(300,5), random_state=1)
clf.fit(x_1, y_1);
rv1=clf.score(x_1,y_1)
y_0r=clf.predict(x_0)
print('拟合优度: ',rv1)
6、方案评估
使用神经网路建模我们得到了未完成任务新的定价。那这个新的定价方案好不好呢?
第一个,未完成的任务,原始定价和新的定价总额是增加了,还是减少了。我们优化后,站在公司的角度,当然是希望钱少了。
R2=sum(y_0r)-sum(y_0) #成本增加额
print('成本增加额: ',R2)
R2=-42,未完成任务总开销变少了
第二个,重新定价后,那些未完成的任务,在新的定价下,是否有希望能被完成呢?我们通过使用支持向量机建模,预测
xx=pd.concat((Data,A.iloc[:,[3]]),axis=1) #12个指标+任务定价,自变量
xx=xx.as_matrix() #转化为数组
yy=A4.reshape(len(A4),1) #任务执行情况,因变量
#对自变量与因变量按训练80%、测试20%随机拆分
from sklearn.model_selection import train_test_split
xx_train, xx_test, yy_train, yy_test = train_test_split(xx, yy, test_size=0.2, random_state=4)
from sklearn import svm
#用高斯核,训练数据类别标签作平衡策略
clf = svm.SVC(kernel='rbf',class_weight='balanced')
clf.fit(xx_train, yy_train)
rv2=clf.score(xx_train, yy_train);#模型准确率
yy1=clf.predict(xx_test)
yy1=yy1.reshape(len(yy1),1)
r=yy_test-yy1
rv3=len(r[r==0])/len(r) #预测准确率
print('模型准确率: ',rv2)
print('预测准确率: ',rv3)
xx_0=np.hstack((Z[A4==0,1:],y_0r.reshape(len(y_0r),1)))#预测自变量
P=clf.predict(xx_0) #预测结果,1-执行,0-未被执行
R1=len(P[P==1]) #预测被执行的个数
R1=int(R1*rv3) #任务完成增加量
print('任务完成增加量: ',R1)
发现任务完成增加了52项。
所以经过优化定价后,未完成任务在新的定价机制下能更多的会被完成,所需的金额反而少了。优化方案起到了积极的效果。