[
  {
    "path": ".gitignore",
    "content": ".ipynb_checkpoints/\r\n*.mat"
  },
  {
    "path": "IP_raytracing/generate_radio_map.m",
    "content": "function fingerprint = generate_radio_map(grid_size)\r\n% ɡRSS滷ݼ\r\n% صfingerprintһά飬¼RSSֵһά͵ڶάǷĳߴ磬άͬAP\r\n    %% \r\n    if nargin == 0\r\n        grid_size = 0.01;\r\n    end\r\n    room_x = 20;\r\n    room_y = 15;\r\n    room_z = 4;\r\n    f = 2400; %źƵ\r\n    % APλ\r\n    APs = [\r\n        1, 1\r\n        10, 1\r\n        19, 1\r\n        1, 14\r\n        10, 14\r\n        19, 14\r\n    ];\r\n    %% fingerprint\r\n    fingerprint = zeros(room_x / grid_size - 1, room_y / grid_size - 1, size(APs, 1));\r\n    for i = 1 : size(APs, 1)\r\n        source_x = APs(i, 1);\r\n        source_y = APs(i, 2);\r\n        source_z = 1; %ĬźԴĸ߶Ϊ1m\r\n        rss = get_rss_by_ray_tracing(room_x, room_y, room_z, source_x, source_y, source_z, grid_size, f); %߸ټRSS\r\n        fingerprint(:, :, i) = rss;\r\n%         figure;\r\n%         mesh(fingerprint(:, :, i));\r\n    end\r\n    save('radio_map_20_15', 'fingerprint');\r\nend\r\n\r\n"
  },
  {
    "path": "IP_raytracing/get_offline_data.m",
    "content": "function fp = get_offline_data(fingerprint)\r\n%ģݲɼ򵥵ķֱӾȼ\r\n    fp = fingerprint(10:10:end, 10:10:end, :);\r\nend\r\n\r\n"
  },
  {
    "path": "IP_raytracing/get_offline_data_random.m",
    "content": "function [data, labels] = get_offline_data_random(fingerprint, data_num)\r\n%ģݲɼ\r\n    if nargin == 1\r\n        data_num = 30000;  %Ĭ30000\r\n    end\r\n    [size_x, size_y, size_ap] = size(fingerprint);\r\n    data = reshape(fingerprint, [], size_ap);\r\n    [x, y] = meshgrid(1:size_x, 1:size_y);\r\n    x = x';\r\n    y = y';\r\n    labels = [x(:), y(:)];\r\n    \r\n    %ѡһ\r\n    idx = randperm(size(data, 1), data_num);\r\n    data = data(idx, :);\r\n    labels = labels(idx, :);\r\nend"
  },
  {
    "path": "IP_raytracing/get_offline_data_uniform.m",
    "content": "function [data, labels] = get_offline_data_uniform(fingerprint, grid_size)\r\n%ģݲɼȼ\r\n    if nargin == 1\r\n        grid_size = 10;  %Ĭ10 --> 1m\r\n    end\r\n    [size_x, size_y, size_ap] = size(fingerprint);\r\n    fp = fingerprint(grid_size:grid_size:size_x, grid_size:grid_size:size_y, :);\r\n    data = reshape(fp, [], size_ap);\r\n    [x, y] = meshgrid(grid_size:grid_size:size_x, grid_size:grid_size:size_y);\r\n    x = x';\r\n    y = y';\r\n    labels = [x(:), y(:)];\r\nend"
  },
  {
    "path": "IP_raytracing/get_online_data.m",
    "content": "function [ trace, rss ] = get_online_data( fingerprint, gridSize, roomLength, roomWidth, t )\r\n%õλָƷ\r\n%룺rss滷ݼݼgridSizeߴ磬ݵĸ\r\n%λõ켣Լ켣ÿϵrss\r\n    trace = get_random_trace(roomLength, roomWidth, t);\r\n    rss = zeros(size(trace, 1), size(fingerprint, 3));\r\n    for i = 1 : size(trace, 1);\r\n        x = round(trace(i, 1) / gridSize);\r\n        y = round(trace(i, 2) / gridSize);\r\n        if x < 1\r\n            x = 1;\r\n        elseif x > size(fingerprint, 1)\r\n            x = size(fingerprint, 1);\r\n        end\r\n        if y < 1\r\n            x = 1;\r\n        elseif y > size(fingerprint, 2)\r\n            y = size(fingerprint, 2);\r\n        end\r\n        rss(i, :) = fingerprint(x, y, :);\r\n        trace(i, :) = [x, y];\r\n    end\r\nend\r\n\r\n"
  },
  {
    "path": "IP_raytracing/get_random_trace.m",
    "content": "function trace = get_random_trace(roomLength, roomWidth, t)\r\n%getRandomTrace: get a random trace of an object in a room\r\n    path_length = zeros(t, 1) + normrnd(0.6, 0.05);\r\n    path_angle = rand(t, 1) * 2 * pi;\r\n    sigma_angle = 10;\r\n    trace = zeros(t, 2);\r\n    trace(1, :) = [randi(roomLength - 1), randi(roomWidth - 1)];\r\n    for i = 2 : t\r\n        trace(i, 1) = trace(i - 1, 1) + path_length(i - 1) .* cos(path_angle(i - 1));\r\n        trace(i, 2) = trace(i - 1, 2) + path_length(i - 1) .* sin(path_angle(i - 1));\r\n        while (trace(i, 1) < 1 || trace(i, 1) > roomLength - 1 || trace(i, 2) < 1 || (trace(i, 2) > roomWidth - 1))\r\n            path_angle(i - 1) = rand() * 2 * pi;\r\n            trace(i, 1) = trace(i - 1, 1) + path_length(i - 1) .* cos(path_angle(i - 1));\r\n            trace(i, 2) = trace(i - 1, 2) + path_length(i - 1) .* sin(path_angle(i - 1));\r\n        end\r\n        path_angle(i) = path_angle(i - 1) + normrnd(0, sigma_angle * pi / 180);\r\n    end\r\nend\r\n\r\n"
  },
  {
    "path": "IP_raytracing/get_rss_by_ray_tracing.m",
    "content": "function Power_all = get_rss_by_ray_tracing(room_x, room_y, room_z, source_x, source_y, source_z, grid_size, f)\r\n% ߸٣ 뷿СźԴ꣬СźƵʣÿϽյźǿ\r\n% ֱΪߴx y zźԴߣ꣨x y zСݵܶȣλmźŵķƵʣλMHz\r\n\r\n    if nargin == 0 %ʱĬ\r\n        room_x = 20;\r\n        room_y = 15;\r\n        room_z = 4;\r\n        source_x = 10;\r\n        source_y = 7.5;\r\n        source_z = 1;\r\n        grid_size = 0.1;\r\n        f = 2400;\r\n    end\r\n\r\n    room_x = 1000 * room_x;\r\n    room_y = 1000 * room_y;\r\n    room_z = 1000 * room_z;\r\n    source_x = 1000 * source_x;\r\n    source_y = 1000 * source_y;\r\n    source_z = 1000 * source_z;\r\n    grid_size = 1000 * grid_size;\r\n    \r\n    %糣͵ϵο߸ص\r\n    epsilon_c=10-1.2j;\r\n    epsilon_w=6.1-1.2j;\r\n    % epsilon_c=7.9-0.89j;\r\n    % epsilon_w=6.2-0.69j;\r\n\r\n    if room_x * room_y / grid_size^2 > 100000000\r\n        disp('ʾʹôͬʱλõϵźǿȣλõõĹܵڴ治㣬matlabܻῨ');\r\n        input('س˳ctrl+c');\r\n    end\r\n\r\n    T = 1 / (f * 10^6);\r\n    c = 3.0e8;\r\n    lambda=c / (f * 10^6);\r\n\r\n    %õռеλ,z̶źԴһ߶\r\n    [X, Y] = meshgrid(grid_size:grid_size:(room_x-grid_size), grid_size:grid_size:(room_y-grid_size));\r\n    L = [X(:), Y(:)];\r\n    L = [L, zeros(size(X(:))) + source_z];\r\n    \r\n    %% ֱ·\r\n    %λ仯糡Eļ档ע˵λֻھλ\r\n    d_direct = sqrt((L(:,1) - source_x).^2 + (L(:,2)-source_y).^2 + (L(:,3) - source_z).^2);%ÿ෢Դŷʽ\r\n    t_direct_0 = d_direct./1000./c;%ֱʱ\r\n    p_direct = mod(t_direct_0*2*pi/T,2*pi);%ֱλ\r\n    E_direct = (lambda./(4.*pi.*d_direct./1000));%EһǳǿСͳǿ\r\n    E0=E_direct.* exp(1i.*(-p_direct));\r\n\r\n    %%\r\n    %LΪꡣÿΪһꡣ\r\n    %LiӦΪӦľ\r\n    %鷴·ֱ\r\n\r\n    %% ǰƽ淴·ǰµ˼ǣվУ泯yᣬʱֱΪǰ£\r\n    Li=[L(:,1) , 2.*room_y-L(:,2) , L(:,3)]; %㾵\r\n    d_reflect = sqrt((Li(:,1)-source_x).^2+(Li(:,2)-source_y).^2+(Li(:,3)-source_z).^2);%·ܳ\r\n    t_reflect_1 = d_reflect./1000./c;%ʱ\r\n    p_reflect = mod(t_reflect_1*2*pi/T,2*pi);%λ\r\n    thet = abs(atan((Li(:,2)-source_y)./(Li(:,1)-source_x)));%\r\n    reflect_coefficient = (sin(thet)-sqrt(epsilon_w-(cos(thet)).^2))./(sin(thet)+sqrt(epsilon_w-(cos(thet)).^2));%ϵҲǾ\r\n    E_reflect = (lambda./(4.*pi.*d_reflect./1000)) .*  reflect_coefficient;\r\n    E1=E_reflect .* exp(1i.*(-p_reflect));%ӳٵλӽ뷴ɵ˥λ仯һ\r\n\r\n    %% ƽ淴·\r\n    Li=[L(:,1) , -L(:,2) , L(:,3)]; %㾵\r\n    d_reflect = sqrt((Li(:,1)-source_x).^2+(Li(:,2)-source_y).^2+(Li(:,3)-source_z).^2);%·ܳ\r\n    t_reflect_2 = d_reflect./1000./c;%ʱ\r\n    p_reflect = mod(t_reflect_2*2*pi/T,2*pi);%λ\r\n    thet = abs(atan((Li(:,2)-source_y)./(Li(:,1)-source_x)));%\r\n    reflect_coefficient = (sin(thet)-sqrt(epsilon_w-(cos(thet)).^2))./(sin(thet)+sqrt(epsilon_w-(cos(thet)).^2));\r\n    E_reflect = (lambda./(4.*pi.*d_reflect./1000)) .*  reflect_coefficient;\r\n    E2=E_reflect .* exp(1i.*(-p_reflect));%ӳٵλӽ뷴ɵ˥λ仯һ\r\n\r\n    %% ƽ淴·\r\n    Li=[-L(:,1) , L(:,2) , L(:,3)]; %㾵\r\n    d_reflect = sqrt((Li(:,1)-source_x).^2+(Li(:,2)-source_y).^2+(Li(:,3)-source_z).^2);%·ܳ\r\n    t_reflect_3 = d_reflect./1000./c;%ʱ\r\n    p_reflect = mod(t_reflect_3*2*pi/T,2*pi);%λ\r\n    thet = abs(atan((Li(:,1)-source_x)./(Li(:,2)-source_y)));%\r\n    reflect_coefficient = (sin(thet)-sqrt(epsilon_w-(cos(thet)).^2))./(sin(thet)+sqrt(epsilon_w-(cos(thet)).^2));\r\n    E_reflect = (lambda./(4.*pi.*d_reflect./1000)) .*  reflect_coefficient;\r\n    E3=E_reflect .* exp(1i.*(-p_reflect));%ӳٵλӽ뷴ɵ˥λ仯һ\r\n\r\n    %% ƽ淴·\r\n    Li=[2*room_x-L(:,1) , L(:,2) , L(:,3)]; %㾵\r\n    d_reflect = sqrt((Li(:,1)-source_x).^2+(Li(:,2)-source_y).^2+(Li(:,3)-source_z).^2);%·ܳ\r\n    t_reflect_4 = d_reflect./1000./c;%ʱ\r\n    p_reflect = mod(t_reflect_4*2*pi/T,2*pi);%λ\r\n    thet = abs(atan((Li(:,1)-source_x)./(Li(:,2)-source_y)));%\r\n    reflect_coefficient = (sin(thet)-sqrt(epsilon_w-(cos(thet)).^2))./(sin(thet)+sqrt(epsilon_w-(cos(thet)).^2));\r\n    E_reflect = (lambda./(4.*pi.*d_reflect./1000)) .*  reflect_coefficient;\r\n    E4=E_reflect .* exp(1i.*(-p_reflect));%ӳٵλӽ뷴ɵ˥λ仯һ\r\n\r\n    %% ƽ淴·\r\n    %%%2014.12.5ƽķ·޸ģֱбʱ򰡣ڷͼСһЩȻڷֽΪֱĵ糡ҪС\r\n    Li=[L(:,1) , L(:,2) , 2*room_z-L(:,3)]; %㾵\r\n    d_reflect = sqrt((Li(:,1)-source_x).^2+(Li(:,2)-source_y).^2+(Li(:,3)-source_z).^2);%·ܳ\r\n    t_reflect_5 = d_reflect./1000./c;%ʱ\r\n    p_reflect = mod(t_reflect_5*2*pi/T,2*pi);%λ\r\n    thet = abs(atan((Li(:,3)-source_z)./sqrt((Li(:,1)-source_x).^2+(Li(:,2)-source_y).^2)));%\r\n    reflect_coefficient = (-sin(thet).*epsilon_c+sqrt(epsilon_c-(cos(thet)).^2))./(epsilon_c.*sin(thet)+sqrt(epsilon_c-(cos(thet)).^2));%ڵķϵҲǾ\r\n    E_reflect = (lambda./(4.*pi.*d_reflect./1000)) .*  reflect_coefficient;\r\n    E5=E_reflect .* exp(1i.*(-p_reflect));%ӳٵλӽ뷴ɵ˥λ仯һ\r\n    E5=E5  .*   cos(pi*sin(thet)/2)./(cos(thet)+0.00001)  .*  cos(thet); %ƽĵ糡ڷͼԼֱֽҪ\r\n    %% ƽ淴·\r\n    Li=[L(:,1) , L(:,2) , -L(:,3)]; %㾵\r\n    d_reflect = sqrt((Li(:,1)-source_x).^2+(Li(:,2)-source_y).^2+(Li(:,3)-source_z).^2);%·ܳ\r\n    t_reflect_6 = d_reflect./1000./c;%ʱ\r\n    p_reflect = mod(t_reflect_6*2*pi/T,2*pi);%λ\r\n    thet = abs(atan((Li(:,3)-source_z)./sqrt((Li(:,1)-source_x).^2+(Li(:,2)-source_y).^2)));%\r\n    reflect_coefficient = (-sin(thet).*epsilon_c+sqrt(epsilon_c-(cos(thet)).^2))./(epsilon_c.*sin(thet)+sqrt(epsilon_c-(cos(thet)).^2));\r\n    E_reflect = (lambda./(4.*pi.*d_reflect./1000)) .*  reflect_coefficient;\r\n    E6=E_reflect .* exp(1i.*(-p_reflect));%ӳٵλӽ뷴ɵ˥λ仯һ\r\n    E6=E6  .*   cos(pi*sin(thet)/2)./(cos(thet)+0.00001)  .*  cos(thet); %ƽĵ糡ڷͼԼֱֽҪ\r\n\r\n    E = E0 + E1 + E2 + E3 + E4 + E5 + E6;%еĵ糡ǿȴ·ͷı\r\n    Power_all = 20 * log10(abs(E)) + 2 * 2.15;%ϳɵĹʡʵһ˥ϵ˳ڼ棬Ϊ2.15dbi\r\n    \r\n    Power_all = reshape(Power_all, room_y / grid_size - 1, room_x / grid_size - 1)';\r\nend\r\n"
  },
  {
    "path": "IP_raytracing/main_raytracing.m",
    "content": "%ڷ滷Уõָƿ⣬Լ߽׶εĲݣԺĶλԡ\r\n\r\n%% ߸ټɷ滷\r\nif ~exist('radio_map_20_15.mat', 'file') %ûɷ滷\r\n    disp('ģ߸...');\r\n    generate_radio_map(0.01);\r\nend\r\n\r\nclc\r\nclear;\r\nload radio_map_20_15.mat; \r\n%Ϊfingerprint %ĬϳߴΪ20m*15m * 6apСΪ0.01m\r\n%ע⣺ķ滷fingerprintһȺܸߵָƿ⣬滷нȡɼݣڶλָƿ⡣\r\n\r\n%% ȡָƿ\r\n%Ҫоָƿ⹹ϵŻⲿָĽ\r\n[offline_rss, offline_location] = get_offline_data_uniform(fingerprint); %Ȳ\r\nsave('offline_data_uniform', 'offline_rss', 'offline_location');\r\n[offline_rss, offline_location] = get_offline_data_random(fingerprint); %\r\nsave('offline_data_random', 'offline_rss', 'offline_location');\r\n\r\n%% ȡ߶λ׶ε5\r\n%ǰĬϵݼܶ0.01mĻϵͳλСֱΪ0.01mtrace0.01\r\nroomLength = 20;\r\nroomWidth = 15;\r\nt = 10000;\r\n[ trace, rss ] = get_online_data( fingerprint, 0.01, roomLength, roomWidth, t ); %õ켣ӦRSS\r\nsave('online_data', 'trace', 'rss');\r\n%%\r\nclear fingerprint;"
  },
  {
    "path": "IP_raytracing/readme.md",
    "content": "\r\n博客地址：http://www.cnblogs.com/rubbninja/p/6118430.html\r\n\r\n+ main_raytracing.m：主程序，在仿真环境中，得到离线指纹库，以及在线阶段的测试数据，用于以后的定位测试。\r\n+ get_rss_by_ray_tracing.m：简化场景下（空旷房间）的射线跟踪。\r\n+ generate_radio_map.m：生成“RSS仿真环境数据集”。\r\n+ get_random_trace.m：生成一条随机轨迹。\r\n+ get_offline_data_random.m：模拟随机数据采集，生成位置指纹库。\r\n+ get_offline_data_uniform.m：模拟均匀数据采集，生成位置指纹库。\r\n+ get_online_data.m：模拟在线阶段，生成测试数据。\r\n+ radio_map_20_15.mat：生成的“RSS仿真环境数据集”，(1999, 1499, 6)的数组，比如fingerprint(1000, 1000, 2)代表的是仿真环境中位置（100，100）上接收到的第2个AP的RSS。\r\n+ offline_data_rss.mat：离线数据RSS，每行为一个RSS向量\r\n+ offline_data_location.mat：离线数据位置点，每行为一个位置点x，y\r\n+ online_data_trace.mat：生成测试数据的运动轨迹，10000*2的数组，比如trace(10, :)代表的是第10个时刻目标的位置x和y。\r\n+ online_data_rss.mat：生成测试数据中与运行轨迹对应的RSS，10000*6的数组，比如trace(10, :)代表的是第10个时刻时目标测得的各个RSS。"
  },
  {
    "path": "Localization_algorithms/loc_knn_cls.m",
    "content": "function [predictions, model] = loc_knn_cls(data, labels, test_data, k)\r\n    % knn(label֣Ϊֵ)\r\n    labels = round(labels(:, 1)/100)*100 + round(labels(:, 2)/100); %xyתһlabel\r\n    model = ClassificationKNN.fit(data, labels, 'NumNeighbors', k);\r\n    label_predict = predict(model, test_data);\r\n    predictions = [floor(label_predict/100), label_predict - floor(label_predict/100) * 100]; %ԤlabelתΪxy\r\n    predictions = predictions * 100;\r\nend"
  },
  {
    "path": "Localization_algorithms/loc_knn_reg.m",
    "content": "function prediction = loc_knn_reg(data, labels, test_data, k)\r\n%knnĶλع飨lablexyֵ͵ģԽֵȡkƽ\r\n    if nargin == 3\r\n        k = 40;\r\n    end\r\n    %ݶλõķknnklabelȡƽЩϸڿﲢûʹmatlabknn\r\n    distance = sqrt(sum((data - repmat(test_data, size(data, 1), 1)).^2, 2));\r\n    [~, idx] = sort(distance);\r\n    prediction = mean(labels(idx(1:k), :));\r\nend\r\n\r\n"
  },
  {
    "path": "accuracy.m",
    "content": "function acc = accuracy( predictions, labels )\r\n%㶨λ\r\n%labelsʵʵλù켣predictionsǹƵλù켣\r\n    acc = mean(sqrt(sum((predictions - labels).^2, 2)));\r\nend"
  },
  {
    "path": "filters/kf_init.m",
    "content": "function kf_params = kf_init(Px, Py, Vx, Vy)\r\n%% У״̬xΪx y ٶx ٶy۲ֵzΪx y\r\n\r\n    kf_params.B = 0; %ⲿΪ0\r\n    kf_params.u = 0; %ⲿΪ0\r\n    kf_params.K = NaN; %ʼ\r\n    kf_params.z = NaN; %ʼÿʹkf_update֮ǰҪ۲ֵz\r\n    kf_params.P = zeros(4, 4); %ʼPΪ0\r\n\r\n    %% ʼ״̬ⲿṩʼ״̬ʹù۲ֵгʼVxVyʼΪ0\r\n    kf_params.x = [Px; Py; Vx; Vy];\r\n\r\n    %% ״̬תƾA\r\n    kf_params.A = eye(4) + diag(ones(1, 2), 2); % ϵͳԤйأϵͳһ̵λüٶȵڵǰʱ̵λãٶȱֲ\r\n\r\n    %% ԤЭQԤϵһ˹ЭΪQ\r\n    %СȡڶԤ̵γ̶ȡ磬Ϊ˶Ŀyϵٶȿܲ٣ô԰ԽǾһֵʱϣĹ켣ƽ԰С\r\n    kf_params.Q = diag(ones(4, 1) * 0.001); \r\n\r\n    %% ۲Hz = H * x\r\n    kf_params.H = eye(2, 4); % ״̬ǣx y ٶx ٶy۲ֵǣx yH = eye(2, 4)\r\n\r\n    %% ۲ЭR۲ϴһ˹ЭΪR\r\n    kf_params.R = diag(ones(2, 1) * 2); %СȡڶԹ۲̵γ̶ȡ磬۲еxֵ׼ȷôRĵһֵӦñȽС\r\nend"
  },
  {
    "path": "filters/kf_update.m",
    "content": "function kf_params = kf_update(kf_params)\r\n    % Ϊ˲̣裩\r\n    x_ = kf_params.A * kf_params.x + kf_params.B * kf_params.u;\r\n    P_ = kf_params.A * kf_params.P * kf_params.A' + kf_params.Q;\r\n    kf_params.K = P_ * kf_params.H' * (kf_params.H * P_ * kf_params.H' + kf_params.R)^-1;\r\n    kf_params.x = x_ + kf_params.K * (kf_params.z - kf_params.H * x_);\r\n    kf_params.P = P_ - kf_params.K * kf_params.H * P_;\r\nend\r\n\r\n"
  },
  {
    "path": "main_KF_test.m",
    "content": "addpath('./filters');\r\naddpath('./IP_raytracing');\r\n%% ģһ˶켣Ȼϸ˹۲Ϊ۲λù켣Ȼʹÿ˲õ˲Ľ\r\n% ٶΪֵ0.6m׼0.05ĸ˹ֲ\r\n% ۲׼Ϊ2\r\n\r\n%% ʵʵʵ·\r\nroomLength = 1000;\r\nroomWidth = 1000;\r\nt = 500;\r\ntrace_real = get_random_trace(roomLength, roomWidth, t);\r\nfigure; \r\nsubplot(1, 3, 1); plot(trace_real(:, 1), trace_real(:, 2), '.');\r\ntitle('ʵʵʵ·');\r\n\r\n%% й۲ʱ·\r\nnoise = 2; %2mλò\r\ntrace = trace_real + normrnd(0, noise, size(trace_real));\r\nsubplot(1, 3, 2); plot(trace(:, 1), trace(:, 2), '.');\r\ntitle('ʱ·');\r\nfprintf('˲֮ǰĶλȣ %f m\\n', accuracy(trace, trace_real));\r\n\r\n%% ·п˲\r\nkf_params_record = zeros(size(trace, 1), 4);\r\nfor i = 1 : t\r\n    if i == 1\r\n        kf_params = kf_init(trace(i, 1), trace(i, 2), 0, 0); % ʼ\r\n    else\r\n        kf_params.z = trace(i, 1:2)'; %õǰʱ̵Ĺ۲λ\r\n        kf_params = kf_update(kf_params); % ˲\r\n    end\r\n    kf_params_record(i, :) = kf_params.x';\r\nend\r\nkf_trace = kf_params_record(:, 1:2);\r\nsubplot(1, 3, 3); plot(kf_trace(:, 1), kf_trace(:, 2), '.');\r\ntitle('˲Ч');\r\nfprintf('˲֮Ķλȣ %f m\\n', accuracy(kf_trace, trace_real));\r\n"
  },
  {
    "path": "main_loc_test.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### 导入数据\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# 导入数据\\n\",\n    \"import numpy as np\\n\",\n    \"import scipy.io as scio\\n\",\n    \"offline_data = scio.loadmat('offline_data_random.mat')\\n\",\n    \"online_data = scio.loadmat('online_data.mat')\\n\",\n    \"offline_location, offline_rss = offline_data['offline_location'], offline_data['offline_rss']\\n\",\n    \"trace, rss = online_data['trace'][0:1000, :], online_data['rss'][0:1000, :]\\n\",\n    \"del offline_data\\n\",\n    \"del online_data\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# 定位精度\\n\",\n    \"def accuracy(predictions, labels):\\n\",\n    \"    return np.mean(np.sqrt(np.sum((predictions - labels)**2, 1)))\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### knn回归\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 11,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Wall time: 92 ms\\n\",\n      \"Wall time: 182 ms\\n\",\n      \"accuracy:  2.24421479398 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# knn回归\\n\",\n    \"from sklearn import neighbors\\n\",\n    \"knn_reg = neighbors.KNeighborsRegressor(40, weights='uniform', metric='euclidean')\\n\",\n    \"%time knn_reg.fit(offline_rss, offline_location)\\n\",\n    \"%time predictions = knn_reg.predict(rss)\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, \\\"m\\\"\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### knn分类\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 12,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Wall time: 80 ms\\n\",\n      \"Wall time: 251 ms\\n\",\n      \"accuracy:  2.73213398632 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# knn分类，需要把坐标转换成网格标号，预测后将网格标号转换为坐标\\n\",\n    \"labels = np.round(offline_location[:, 0]/100.0) * 100 + np.round(offline_location[:, 1]/100.0)\\n\",\n    \"from sklearn import neighbors\\n\",\n    \"knn_cls = neighbors.KNeighborsClassifier(n_neighbors=40, weights='uniform', metric='euclidean')\\n\",\n    \"%time knn_cls.fit(offline_rss, labels)\\n\",\n    \"%time predict_labels = knn_cls.predict(rss)\\n\",\n    \"x = np.floor(predict_labels/100.0)\\n\",\n    \"y = predict_labels - x * 100\\n\",\n    \"predictions = np.column_stack((x, y)) * 100\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, 'm'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"source\": [\n    \"#### 定位算法分析\\n\",\n    \"\\n\",\n    \"加入数据预处理和交叉验证\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# 预处理，标准化数据(其实RSS数据还算正常，不预处理应该也无所谓，特征选择什么的也都不需要)\\n\",\n    \"from sklearn.preprocessing import StandardScaler\\n\",\n    \"standard_scaler = StandardScaler().fit(offline_rss)\\n\",\n    \"X_train = standard_scaler.transform(offline_rss)\\n\",\n    \"Y_train = offline_location\\n\",\n    \"X_test = standard_scaler.transform(rss)\\n\",\n    \"Y_test = trace\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 44,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# 交叉验证，在knn里用来选择最优的超参数k\\n\",\n    \"from sklearn.model_selection import GridSearchCV\\n\",\n    \"from sklearn import neighbors\\n\",\n    \"parameters = {'n_neighbors':range(1, 50)}\\n\",\n    \"knn_reg = neighbors.KNeighborsRegressor(weights='uniform', metric='euclidean')\\n\",\n    \"clf = GridSearchCV(knn_reg, parameters)\\n\",\n    \"clf.fit(offline_rss, offline_location)\\n\",\n    \"scores = clf.cv_results_['mean_test_score']\\n\",\n    \"k = np.argmax(scores) #选择score最大的k\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 49,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"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\\n\",\n      \"text/plain\": [\n       \"<matplotlib.figure.Figure at 0x580bf90>\"\n      ]\n     },\n     \"metadata\": {},\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"# 绘制超参数k与score的关系曲线\\n\",\n    \"import matplotlib.pyplot as plt\\n\",\n    \"%matplotlib inline\\n\",\n    \"plt.plot(range(1, scores.shape[0] + 1), scores, '-o', linewidth=2.0)\\n\",\n    \"plt.xlabel(\\\"k\\\")\\n\",\n    \"plt.ylabel(\\\"score\\\")\\n\",\n    \"plt.grid(True)\\n\",\n    \"plt.show()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 47,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"accuracy:  2.22455511073 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# 使用最优的k做knn回归\\n\",\n    \"knn_reg = neighbors.KNeighborsRegressor(n_neighbors=k, weights='uniform', metric='euclidean')\\n\",\n    \"predictions = knn_reg.fit(offline_rss, offline_location).predict(rss)\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, \\\"m\\\"\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 66,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# 训练数据量与accuracy\\n\",\n    \"k = 29\\n\",\n    \"data_num = range(100, 30000, 300)\\n\",\n    \"acc = []\\n\",\n    \"for i in data_num:\\n\",\n    \"    knn_reg = neighbors.KNeighborsRegressor(n_neighbors=k, weights='uniform', metric='euclidean')\\n\",\n    \"    predictions = knn_reg.fit(offline_rss[:i, :], offline_location[:i, :]).predict(rss)\\n\",\n    \"    acc.append(accuracy(predictions, trace) / 100)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 65,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"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\\n\",\n      \"text/plain\": [\n       \"<matplotlib.figure.Figure at 0x52a5c90>\"\n      ]\n     },\n     \"metadata\": {},\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"# 绘制训练数据量与accuracy的曲线\\n\",\n    \"import matplotlib.pyplot as plt\\n\",\n    \"%matplotlib inline\\n\",\n    \"plt.plot(data_num, acc, '-o', linewidth=2.0)\\n\",\n    \"plt.xlabel(\\\"data number\\\")\\n\",\n    \"plt.ylabel(\\\"accuracy (m)\\\")\\n\",\n    \"plt.grid(True)\\n\",\n    \"plt.show()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"---\\n\",\n    \"\\n\",\n    \"## 其他分类器\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### 导入数据\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# 导入数据\\n\",\n    \"import numpy as np\\n\",\n    \"import scipy.io as scio\\n\",\n    \"offline_data = scio.loadmat('offline_data_random.mat')\\n\",\n    \"online_data = scio.loadmat('online_data.mat')\\n\",\n    \"offline_location, offline_rss = offline_data['offline_location'], offline_data['offline_rss']\\n\",\n    \"trace, rss = online_data['trace'][0:1000, :], online_data['rss'][0:1000, :]\\n\",\n    \"del offline_data\\n\",\n    \"del online_data\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 169,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# 定位准确度定义\\n\",\n    \"def accuracy(predictions, labels):\\n\",\n    \"    return np.mean(np.sqrt(np.sum((predictions - labels + 0.0)**2, 1)))\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### Logistic regression （逻辑斯蒂回归）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 29,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"accuracy:  3.08581348591 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# 逻辑斯蒂回归是用来分类的\\n\",\n    \"labels = np.round(offline_location[:, 0]/100.0) * 100 + np.round(offline_location[:, 1]/100.0)\\n\",\n    \"from sklearn.linear_model import LogisticRegressionCV\\n\",\n    \"clf_l2_LR_cv = LogisticRegressionCV(Cs=20, penalty='l2', tol=0.001)\\n\",\n    \"predict_labels = clf_l2_LR.fit(offline_rss, labels).predict(rss)\\n\",\n    \"x = np.floor(predict_labels/100.0)\\n\",\n    \"y = predict_labels - x * 100\\n\",\n    \"predictions = np.column_stack((x, y)) * 100\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, 'm'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### Support Vector Machine for Regression （支持向量机）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 10,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Wall time: 9min 27s\\n\",\n      \"Wall time: 12min 42s\\n\",\n      \"Wall time: 1.06 s\\n\",\n      \"Wall time: 1.05 s\\n\",\n      \"accuracy:  2.2468400825 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn import svm\\n\",\n    \"clf_x = svm.SVR(C=1000, gamma=0.01)\\n\",\n    \"clf_y = svm.SVR(C=1000, gamma=0.01)\\n\",\n    \"%time clf_x.fit(offline_rss, offline_location[:, 0])\\n\",\n    \"%time clf_y.fit(offline_rss, offline_location[:, 1])\\n\",\n    \"%time x = clf_x.predict(rss)\\n\",\n    \"%time y = clf_y.predict(rss)\\n\",\n    \"predictions = np.column_stack((x, y))\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, \\\"m\\\"\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"source\": [\n    \"#### Support Vector Machine for Classification （支持向量机）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 18,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Wall time: 1min 16s\\n\",\n      \"Wall time: 15 s\\n\",\n      \"accuracy:  2.50931890608 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn import svm\\n\",\n    \"labels = np.round(offline_location[:, 0]/100.0) * 100 + np.round(offline_location[:, 1]/100.0)\\n\",\n    \"clf_svc = svm.SVC(C=1000, tol=0.01, gamma=0.001)\\n\",\n    \"%time clf_svc.fit(offline_rss, labels)\\n\",\n    \"%time predict_labels = clf_svc.predict(rss)\\n\",\n    \"x = np.floor(predict_labels/100.0)\\n\",\n    \"y = predict_labels - x * 100\\n\",\n    \"predictions = np.column_stack((x, y)) * 100\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, 'm'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### random forest regressor （随机森林）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 30,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Wall time: 58.6 s\\n\",\n      \"Wall time: 196 ms\\n\",\n      \"accuracy:  2.20778352008 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn.ensemble import RandomForestRegressor\\n\",\n    \"estimator = RandomForestRegressor(n_estimators=150)\\n\",\n    \"%time estimator.fit(offline_rss, offline_location)\\n\",\n    \"%time predictions = estimator.predict(rss)\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, 'm'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### random forest classifier （随机森林）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 49,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Wall time: 39.6 s\\n\",\n      \"Wall time: 113 ms\\n\",\n      \"accuracy:  2.56860790666 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn.ensemble import RandomForestClassifier\\n\",\n    \"labels = np.round(offline_location[:, 0]/100.0) * 100 + np.round(offline_location[:, 1]/100.0)\\n\",\n    \"estimator = RandomForestClassifier(n_estimators=20, max_features=None, max_depth=20) # 内存受限，tree的数量有点少\\n\",\n    \"%time estimator.fit(offline_rss, labels)\\n\",\n    \"%time predict_labels = estimator.predict(rss)\\n\",\n    \"x = np.floor(predict_labels/100.0)\\n\",\n    \"y = predict_labels - x * 100\\n\",\n    \"predictions = np.column_stack((x, y)) * 100\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, 'm'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### Linear Regression （线性回归）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 21,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"accuracy:  3.83239841667 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn.linear_model import LinearRegression\\n\",\n    \"predictions = LinearRegression().fit(offline_rss, offline_location).predict(rss)\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, 'm'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### Ridge Regression （岭回归）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 20,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"accuracy:  3.83255676918 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn.linear_model import RidgeCV\\n\",\n    \"clf = RidgeCV(alphas=np.logspace(-4, 4, 10))\\n\",\n    \"predictions = clf.fit(offline_rss, offline_location).predict(rss)\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, 'm'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### Lasso回归\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 18,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"accuracy:  3.83244688001 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn.linear_model import MultiTaskLassoCV\\n\",\n    \"clf = MultiTaskLassoCV(alphas=np.logspace(-4, 4, 10))\\n\",\n    \"predictions = clf.fit(offline_rss, offline_location).predict(rss)\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, 'm'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### Elastic Net （弹性网回归）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 19,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"accuracy:  3.832486036 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn.linear_model import MultiTaskElasticNetCV\\n\",\n    \"clf = MultiTaskElasticNetCV(alphas=np.logspace(-4, 4, 10))\\n\",\n    \"predictions = clf.fit(offline_rss, offline_location).predict(rss)\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, 'm'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### Bayesian Ridge Regression （贝叶斯岭回归）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 17,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"accuracy:  3.83243319129 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn.linear_model import BayesianRidge\\n\",\n    \"from sklearn.multioutput import MultiOutputRegressor\\n\",\n    \"clf = MultiOutputRegressor(BayesianRidge())\\n\",\n    \"predictions = clf.fit(offline_rss, offline_location).predict(rss)\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, \\\"m\\\"\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"source\": [\n    \"#### Gradient Boosting for regression （梯度提升）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 26,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Wall time: 43.4 s\\n\",\n      \"Wall time: 17 ms\\n\",\n      \"accuracy:  2.22100945095 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn import ensemble\\n\",\n    \"from sklearn.multioutput import MultiOutputRegressor\\n\",\n    \"clf = MultiOutputRegressor(ensemble.GradientBoostingRegressor(n_estimators=100, max_depth=10))\\n\",\n    \"%time clf.fit(offline_rss, offline_location)\\n\",\n    \"%time predictions = clf.predict(rss)\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, \\\"m\\\"\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### Multi-layer Perceptron regressor （神经网络多层感知器）\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 22,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Wall time: 1min 1s\\n\",\n      \"Wall time: 6 ms\\n\",\n      \"accuracy:  2.4517504109 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from sklearn.neural_network import MLPRegressor\\n\",\n    \"clf = MLPRegressor(hidden_layer_sizes=(100, 100))\\n\",\n    \"%time clf.fit(offline_rss, offline_location)\\n\",\n    \"%time predictions = clf.predict(rss)\\n\",\n    \"acc = accuracy(predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, \\\"m\\\"\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"---\\n\",\n    \"\\n\",\n    \"## 目标跟踪\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### KNN + Kalman Filter\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"accuracy:  2.24421479398 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# knn回归\\n\",\n    \"from sklearn import neighbors\\n\",\n    \"knn_reg = neighbors.KNeighborsRegressor(40, weights='uniform', metric='euclidean')\\n\",\n    \"knn_reg.fit(offline_rss, offline_location)\\n\",\n    \"knn_predictions = knn_reg.predict(rss)\\n\",\n    \"acc = accuracy(knn_predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, \\\"m\\\"\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# 对knn定位结果进行卡尔曼滤波\\n\",\n    \"\\n\",\n    \"from filterpy.kalman import KalmanFilter\\n\",\n    \"from scipy.linalg import block_diag\\n\",\n    \"from filterpy.common import Q_discrete_white_noise\\n\",\n    \"def kalman_tracker():\\n\",\n    \"    tracker = KalmanFilter(dim_x=4, dim_z=2)\\n\",\n    \"    dt = 1.\\n\",\n    \"    # 状态转移矩阵\\n\",\n    \"    tracker.F = np.array([[1, dt, 0,  0], \\n\",\n    \"                          [0,  1, 0,  0],\\n\",\n    \"                          [0,  0, 1, dt],\\n\",\n    \"                          [0,  0, 0,  1]])\\n\",\n    \"    # 用filterpy计算Q矩阵\\n\",\n    \"    q = Q_discrete_white_noise(dim=2, dt=dt, var=0.001)\\n\",\n    \"    # tracker.Q = block_diag(q, q)\\n\",\n    \"    tracker.Q = np.eye(4) * 0.01\\n\",\n    \"    # tracker.B = 0\\n\",\n    \"    # 观测矩阵\\n\",\n    \"    tracker.H = np.array([[1., 0, 0, 0],\\n\",\n    \"                          [0, 0, 1., 0]])\\n\",\n    \"    # R矩阵\\n\",\n    \"    tracker.R = np.array([[4., 0],\\n\",\n    \"                          [0, 4.]])\\n\",\n    \"    # 初始状态和初始P\\n\",\n    \"    tracker.x = np.array([[7.4, 0, 3.3, 0]]).T \\n\",\n    \"    tracker.P = np.zeros([4, 4])\\n\",\n    \"    return tracker\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"accuracy:  1.76116239607 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"tracker = kalman_tracker()\\n\",\n    \"zs = np.array([np.array([i]).T / 100. for i in knn_predictions]) # 除以100，单位为m\\n\",\n    \"mu, cov, _, _ = tracker.batch_filter(zs) # 这个函数对一串观测值滤波\\n\",\n    \"knn_kf_predictions = mu[:, [0, 2], :].reshape(1000, 2)\\n\",\n    \"acc = accuracy(knn_kf_predictions, trace / 100.)\\n\",\n    \"print \\\"accuracy: \\\", acc, \\\"m\\\"\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### KNN + Particle Filter\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 6,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"accuracy:  2.24421479398 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# knn回归\\n\",\n    \"from sklearn import neighbors\\n\",\n    \"knn_reg = neighbors.KNeighborsRegressor(40, weights='uniform', metric='euclidean')\\n\",\n    \"knn_reg.fit(offline_rss, offline_location)\\n\",\n    \"knn_predictions = knn_reg.predict(rss)\\n\",\n    \"acc = accuracy(knn_predictions, trace)\\n\",\n    \"print \\\"accuracy: \\\", acc/100, \\\"m\\\"\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 7,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# 设计粒子滤波中各个步骤的具体实现\\n\",\n    \"\\n\",\n    \"from numpy.random import uniform, randn, random, seed\\n\",\n    \"from filterpy.monte_carlo import multinomial_resample\\n\",\n    \"import scipy.stats\\n\",\n    \"seed(7)\\n\",\n    \"\\n\",\n    \"def create_particles(x_range, y_range, v_mean, v_std, N):\\n\",\n    \"    \\\"\\\"\\\"这里的粒子状态设置为（坐标x，坐标y，运动方向，运动速度）\\\"\\\"\\\"\\n\",\n    \"    particles = np.empty((N, 4))\\n\",\n    \"    particles[:, 0] = uniform(x_range[0], x_range[1], size=N)\\n\",\n    \"    particles[:, 1] = uniform(y_range[0], y_range[1], size=N)\\n\",\n    \"    particles[:, 2] = uniform(0, 2 * np.pi, size=N)\\n\",\n    \"    particles[:, 3] = v_mean + (randn(N) * v_std)\\n\",\n    \"    return particles\\n\",\n    \"\\n\",\n    \"def predict_particles(particles, std_heading, std_v, x_range, y_range):\\n\",\n    \"    \\\"\\\"\\\"这里的预测规则设置为：粒子根据各自的速度和方向（加噪声）进行运动，如果超出边界则随机改变方向再次尝试，\\\"\\\"\\\"\\n\",\n    \"    idx = np.array([True] * len(particles))\\n\",\n    \"    particles_last = np.copy(particles)\\n\",\n    \"    for i in range(100): # 最多尝试100次\\n\",\n    \"        if i == 0:\\n\",\n    \"            particles[idx, 2] = particles_last[idx, 2] + (randn(np.sum(idx)) * std_heading)\\n\",\n    \"        else:\\n\",\n    \"            particles[idx, 2] = uniform(0, 2 * np.pi, size=np.sum(idx)) # 随机改变方向\\n\",\n    \"        particles[idx, 3] = particles_last[idx, 3] + (randn(np.sum(idx)) * std_v)\\n\",\n    \"        particles[idx, 0] = particles_last[idx, 0] + np.cos(particles[idx, 2] ) * particles[idx, 3]\\n\",\n    \"        particles[idx, 1] = particles_last[idx, 1] + np.sin(particles[idx, 2] ) * particles[idx, 3]\\n\",\n    \"        # 判断超出边界的粒子\\n\",\n    \"        idx = ((particles[:, 0] < x_range[0])\\n\",\n    \"                | (particles[:, 0] > x_range[1])\\n\",\n    \"                | (particles[:, 1] < y_range[0]) \\n\",\n    \"                | (particles[:, 1] > y_range[1]))\\n\",\n    \"        if np.sum(idx) == 0:\\n\",\n    \"            break\\n\",\n    \"            \\n\",\n    \"def update_particles(particles, weights, z, d_std):\\n\",\n    \"    \\\"\\\"\\\"粒子更新，根据观测结果中得到的位置pdf信息来更新权重，这里简单地假设是真实位置到观测位置的距离为高斯分布\\\"\\\"\\\"\\n\",\n    \"    # weights.fill(1.)\\n\",\n    \"    distances = np.linalg.norm(particles[:, 0:2] - z, axis=1)\\n\",\n    \"    weights *= scipy.stats.norm(0, d_std).pdf(distances)\\n\",\n    \"    weights += 1.e-300\\n\",\n    \"    weights /= sum(weights)\\n\",\n    \"\\n\",\n    \"def estimate(particles, weights):\\n\",\n    \"    \\\"\\\"\\\"估计位置\\\"\\\"\\\"\\n\",\n    \"    return np.average(particles, weights=weights, axis=0)\\n\",\n    \"\\n\",\n    \"def neff(weights):\\n\",\n    \"    \\\"\\\"\\\"用来判断当前要不要进行重采样\\\"\\\"\\\"\\n\",\n    \"    return 1. / np.sum(np.square(weights))\\n\",\n    \"\\n\",\n    \"def resample_from_index(particles, weights, indexes):\\n\",\n    \"    \\\"\\\"\\\"根据指定的样本进行重采样\\\"\\\"\\\"\\n\",\n    \"    particles[:] = particles[indexes]\\n\",\n    \"    weights[:] = weights[indexes]\\n\",\n    \"    weights /= np.sum(weights)\\n\",\n    \"    \\n\",\n    \"def run_pf(particles, weights, z, x_range, y_range):\\n\",\n    \"    \\\"\\\"\\\"迭代一次粒子滤波，返回状态估计\\\"\\\"\\\"\\n\",\n    \"    x_range, y_range = [0, 20], [0, 15]\\n\",\n    \"    predict_particles(particles, 0.5, 0.01, x_range, y_range) # 1. 预测\\n\",\n    \"    update_particles(particles, weights, z, 4) # 2. 更新\\n\",\n    \"    if neff(weights) < len(particles) / 2: # 3. 重采样\\n\",\n    \"        indexes = multinomial_resample(weights)\\n\",\n    \"        resample_from_index(particles, weights, indexes)\\n\",\n    \"    return estimate(particles, weights) # 4. 状态估计\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 8,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"final state:  [  8.16137026  12.49569879   4.06952385   0.54954716]\\n\",\n      \"accuracy:  1.80881825483 m\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# 对knn定位结果进行粒子滤波\\n\",\n    \"\\n\",\n    \"knn_pf_predictions = np.empty(knn_predictions.shape)\\n\",\n    \"x_range, y_range = [0, 20], [0, 15]\\n\",\n    \"n_particles = 50000\\n\",\n    \"particles = create_particles(x_range, y_range, 0.6, 0.01, n_particles) # 初始化粒子\\n\",\n    \"weights = np.ones(n_particles) / n_particles # 初始化权重\\n\",\n    \"\\n\",\n    \"for i, pos in enumerate(knn_predictions):\\n\",\n    \"    pos = pos.copy() / 100.\\n\",\n    \"    state = run_pf(particles, weights, pos, x_range, y_range)\\n\",\n    \"    knn_pf_predictions[i, :] = state[0:2]\\n\",\n    \"\\n\",\n    \"acc = accuracy(knn_pf_predictions, trace / 100.)\\n\",\n    \"print \\\"final state: \\\", state\\n\",\n    \"print \\\"accuracy: \\\", acc, \\\"m\\\"\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 19,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"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\\n\",\n      \"text/plain\": [\n       \"<matplotlib.figure.Figure at 0x72e7df0>\"\n      ]\n     },\n     \"metadata\": {},\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"import matplotlib.pyplot as plt\\n\",\n    \"%matplotlib inline\\n\",\n    \"x_i = range(220, 280)\\n\",\n    \"tr, = plt.plot(trace[x_i, 0] / 100., trace[x_i, 1] / 100., 'k-', linewidth=3)\\n\",\n    \"pf, = plt.plot(knn_pf_predictions[x_i, 0], knn_pf_predictions[x_i, 1], 'r-')\\n\",\n    \"kf, = plt.plot(knn_kf_predictions[x_i, 0], knn_kf_predictions[x_i, 1], 'b-')\\n\",\n    \"knn_ = plt.scatter(knn_predictions[x_i, 0] / 100., knn_predictions[x_i, 1] / 100.)\\n\",\n    \"plt.xlabel('x (m)')\\n\",\n    \"plt.ylabel('y (m)')\\n\",\n    \"plt.legend([tr, pf, kf, knn_], [\\\"real trace\\\", \\\"pf\\\", \\\"kf\\\", \\\"knn\\\"])\\n\",\n    \"plt.show()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": []\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 2\",\n   \"language\": \"python\",\n   \"name\": \"python2\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 2\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython2\",\n   \"version\": \"2.7.9\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 0\n}\n"
  },
  {
    "path": "main_loc_test.m",
    "content": "addpath('./IP_raytracing');\r\naddpath('./Localization_algorithms');\r\nmain_raytracing;\r\nload offline_data_random.mat;\r\nload online_data.mat;\r\n\r\nrss = rss(1:1000, :);\r\ntrace = trace(1:1000, :);\r\npredictions = online_loc( offline_rss, offline_location, rss, 'knn_reg');\r\nacc = accuracy(predictions, trace);\r\nfprintf('accuracy%fm\\n', acc / 100);\r\n"
  },
  {
    "path": "online_loc.m",
    "content": "function predictions = online_loc(offline_rss, offline_location, online_rss, type)\r\n%ģ߶λ\r\n%offline_locationoffline_rssָƿ⣬ÿΪһָ\r\n%online_rssΪRSSÿΪһRSS\r\n\r\n    predictions = zeros(size(online_rss, 1), size(offline_location, 2));\r\n    disp(type);\r\n    if type == 'knn_reg'  %õknnλ\r\n        tic;\r\n        lasttime = 0;\r\n        for i = 1:size(online_rss, 1) %ֱÿRSSжλ\r\n            curtime = toc;\r\n            if curtime - lasttime > 1\r\n                fprintf('ȣ%f%%\\n', i / size(online_rss, 1) * 100);\r\n                lasttime = curtime;\r\n            end\r\n            % knnع\r\n            prediction = loc_knn_reg(offline_rss, offline_location, online_rss(i, :));\r\n            predictions(i, :) = prediction;\r\n        end\r\n    end\r\n\r\n    % knn(label֣ΪıţΪֵ)\r\n    if type == 'knn_cls'\r\n        k = 40;\r\n        predictions = loc_knn_cls(offline_rss, offline_location, online_rss, k);\r\n    end\r\nend"
  }
]