我们知道机器学习是利用大量的数据资料进行学习的,而这些资料不存在明显的函数关系,更多是相关关系,所以利用机器学习来研究高精度的问题是一个巨大的挑战,日常生活中,我们知道经纬度这个数据一般都需要精确到小数点6,7位,属于高精度的范畴,那么怎么利用机器学习来研究高精度的问题呢?我们利用机器学习方法来牛刀小试,研究背景是,将wgs84坐标系转gcj02坐标系,并且使得转换精度足够高,原数据的天地图是wgs84坐标系,幢号是gcj02坐标系,现在的任务是找一个精度足够高的算法,将wgs84转到gcj02上面去。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
data = pd.read_excel("幢号地址验证数据.xlsx") #读取数据
gcj_lon, gcj_lat = data["幢号经度"], data["幢号纬度"]
wgs_lon, wgs_lat = data["天地图经度"], data["天地图纬度"]
plt.figure(figsize = (9, 9))
plt.scatter(gcj_lon, gcj_lat, marker = 'x',color = 'orange', label = 'gcj02')
plt.scatter(wgs_lon, wgs_lat, marker = 'x', color = 'blue',label = "wgs84")
plt.xlim([np.min(gcj_lon) - 0.005, np.max(gcj_lon) + 0.005])
plt.ylim([np.min(gcj_lat) - 0.005, np.max(gcj_lat) + 0.005])
plt.legend()
plt.show()
从两个坐标系的对比可以发现gcj02在wgs84的右下角一些,也就是说经度要大一些,纬度要小一些
特征映射主要讲把原来的经度,纬度转更高维的特征,研究发现,当指数为1的时候拟合度最高。
X = np.array(data[["天地图经度","天地图纬度"]])
X = np.insert(X, 0, 1, axis =1)
y1, y2 = np.array(gcj_lon), np.array(gcj_lat) #gcj经度,gcj纬度
def generateFunction(x1, x2): #定义生成多项式
power = 1
out = np.ones((x1.shape[0],1))
for i in range(1, power +1):
for j in range(0, i+1):
term1 = x1**(i-j)
term2 = x2**(j)
term = (term1*term2).reshape(term1.shape[0], 1)
out = np.hstack((out, term))
return out
X_mapped = generateFunction(X[:,1], X[:,2]) #(1855, 6)
因为经度纬度是两个标签,因变量,所以,需要分别训练。
from scipy import optimize
def h(mytheta, myx): #定义假设函数
return np.dot(myx, mytheta)
def costFunction(mytheta, myx, myy): #定义损失函数
return 1/(2*len(myx))*np.dot((h(mytheta, myx)- myy).T, (h(mytheta, myx)-myy))
def optimizeTheta(mytheta, myx, myy): #定义最优化参数函数
result = optimize.minimize(costFunction, mytheta, args = (myx, myy), method = "TNC", options = {"maxiter": 50000, "disp": False})
return np.array([result.x]), result.fun
initial_theta1 = np.array([0, 0, -1]).T
#initial_theta1 = np.random.randint(-1, 1,(X_mapped.shape[1], 1))
theta1, mincost1 = optimizeTheta(initial_theta1, X_mapped, y1)
print(theta1, mincost1)
def predict_lon(x1, x2): #定义预测函数
X = generateFunction(x1, x2) #1855*6
pred_lon = h(theta1.T, X)
return pred_lon
pred_lon = pd.Series(predict_lon(X[:,1], X[:,2]).reshape(-1))
data1 = pd.concat([data, pred_lon], axis = 1)
data1.columns = list(data.columns) + ["预测经度"]
print(data1.head())
data1.to_excel("带预测经度.xlsx")
[[0.00818154 0.99357317 0.02479023]] 7.416383108455166e-08
经度训练精度 1 0 − 8 10^{-8} 10−8。
from scipy import optimize
def h(mytheta, myx): #定义假设函数
return np.dot(myx, mytheta)
def costFunction(mytheta, myx, myy): #定义损失函数
return 1/(2*len(myx))*np.dot((h(mytheta, myx)- myy).T, (h(mytheta, myx)-myy))
def optimizeTheta(mytheta, myx, myy): #定义最优化参数函数
result = optimize.minimize(costFunction, mytheta, args = (myx, myy), method = "BFGS", options = {"maxiter": 50000, "disp": False}) #TNC,Powell
return np.array([result.x]), result.fun
#initial_theta2 = np.random.randint(-1, 10,(X_mapped.shape[1], 1))
initial_theta2 = np.array([0, -1, 0]).T
print(initial_theta2)
theta2, mincost2 = optimizeTheta(initial_theta2, X_mapped, y2)
print(theta2, mincost2)
def predict_lat(x1, x2): #定义预测函数
X = generateFunction(x1, x2) #1855*6
pred_lat = h(theta2.T, X)
return pred_lat
pred_lat = pd.Series(predict_lat(X[:,1], X[:,2]).reshape(-1))
data2 = pd.concat([data, pred_lat], axis = 1)
data2.columns = list(data.columns) + ["预测纬度"]
#print(data2.head())
data2.to_excel("带预测纬度.xlsx")
[ 0 -1 0]
[[0.0244514 0.03245597 0.8733089 ]] 1.7107261219293713e-06
纬度训练精度 1 0 − 6 10^{-6} 10−6。
本次只是用机器学习做一个高精度的试探,如果有感兴趣的朋友可以联系我。