ดึงข้อมูลเชิงลึกจากสถานี WiFi สาธารณะ…

ทุก ๆ วินาที การเปลี่ยนแปลงมากมายเกิดขึ้นในโลกเทคโนโลยี อุปกรณ์อัจฉริยะ แกดเจ็ตใหม่ๆ กำลังออกสู่ตลาดที่มีสเปคแตกต่างกัน ดังนั้นจึงมีการพูดคุยกันมากมายเกี่ยวกับวิธีใช้อุปกรณ์ที่มีอยู่เหล่านี้เพื่อรวบรวมข้อมูลเชิงลึกที่ซ่อนอยู่ การจดจำกิจกรรมของมนุษย์โดยใช้สัญญาณ WiFi กลายเป็นประเด็นร้อนในปัจจุบัน ด้วยเทคนิคการเรียนรู้ของเครื่องที่กำลังเผ็ดร้อนและสมจริงมากขึ้น

ดังนั้นในบทความสั้นๆ นี้ เราจะสร้างแอปพลิเคชันง่ายๆ เพื่อตรวจสอบความพร้อมของบุคคลภายในพื้นที่ที่เลือก

มาหารือเกี่ยวกับแนวคิดที่เกี่ยวข้องกับหัวข้อสำคัญต่อไปนี้กัน

  1. เรียนรู้เกี่ยวกับสถาปัตยกรรมและแนวคิด
  2. การเก็บเกี่ยวข้อมูล + การเร่งความเร็ว
  3. การฝึกอบรมโมเดล ML และผลลัพธ์
  4. การคาดการณ์ข้อมูลแบบเรียลไทม์

เยี่ยมมาก! รัดเข็มขัดเพื่อดำดิ่งลึกลงไป

1. สถาปัตยกรรม

ปัญหา : ในโครงการนี้ เรามุ่งเน้นไปที่การระบุความแตกต่างระหว่าง

  • พื้นที่ว่างเทียบกับมีคนอยู่และเคลื่อนไหวไปมา
  • พื้นที่ว่างเทียบกับคน 5 คนที่อยู่และเคลื่อนไหวไปมา

ในพื้นที่เฉพาะ RSSI ของจุดเข้าใช้งาน WiFi ต่างๆ ที่ได้ยินในพื้นที่นี้จะถูกรวบรวม และข้อมูลจะถูกนำไปใช้กับเทคนิคการจำแนกประเภทเพื่อให้ได้ผลลัพธ์ที่ต้องการ จากนั้นเราพยายามคาดการณ์ข้อมูลแบบเรียลไทม์

วิธีการ : เราต้องการส่วนประกอบบางอย่างเพื่อสร้างระบบ คุณอาจเคยได้ยินหรือใช้งานมาแล้ว ใช่!

  • ESP8266 - สแกนหา SSID และ RSSI (การรวบรวมข้อมูล)
  • เซิร์ฟเวอร์กลาง MQTT (iot.eclipse.org)
  • ไคลเอนต์ Python MQTT — สมัครสมาชิกหัวข้อที่เกี่ยวข้องเพื่อรับข้อมูล

NodeMCU สแกนหา WiFi SSID ที่มีอยู่และรวบรวมข้อมูล RSSI จากนั้นไคลเอ็นต์ MQTT ของ NodeMCU จะส่งข้อมูลไปยังเซิร์ฟเวอร์ MQTT ในกรณีของเรา เราจะใช้ iot.eclipse.orgสำหรับการลองครั้งแรก กระบวนการ python ที่แยกต่างหากของไคลเอ็นต์ MQTT ได้รับการตั้งค่าให้อ่าน que และบันทึกลงในไฟล์ Excel ซึ่งใช้ในการป้อนเข้าสู่โมเดล ML ในภายหลัง

นี่คือแนวคิดพื้นฐานของระบบของเรา นี่เป็นการแสดงให้เห็นว่าแนวคิดของเราเป็นไปได้สำหรับแอปพลิเคชันนี้ แต่ในแอปพลิเคชันระดับการผลิต เราสามารถใช้บริการระบบคลาวด์ เช่น GCP หรือ Azure สำหรับบริการ MQTT ฝึกอบรมโมเดล ML และโฮสต์แดชบอร์ดแบบเรียลไทม์เพื่อดูความพร้อมของผู้คนในพื้นที่ทำงานขนาดใหญ่ ความเป็นไปได้อื่นๆ ก็คือหากคุณจะใช้งานในพื้นที่ขนาดเล็ก ให้ติดตั้งทุกอย่างในเครื่อง เรียบง่าย!.

<แข็งแกร่ง>2. การเก็บเกี่ยวข้อมูล

เมื่อระบบของคุณเริ่มทำงานแล้วก็ถึงเวลารวบรวมข้อมูลในจำนวนที่เพียงพอ อันดับแรก ให้ระบุ SSID ที่มีอยู่ และติดป้ายกำกับข้อมูลที่รวบรวมไว้ ในกรณีของเรา เราสามารถได้ยินเครือข่ายไร้สาย UoM_Wireless, UNIC-wifi, Beacon_wireless, FGS_office, Eduroam ในการตรวจสอบครั้งแรก และรวบรวมข้อมูลโดยมีป้ายกำกับดังนี้

  • 0 :ไม่มีคนอยู่ในห้อง
  • 1 :มีคนหนึ่งอยู่ในห้องและเคลื่อนไหวไปมา
  • 2 :ห้าคนอยู่ในห้องและเคลื่อนไหวไปมา

แต่ข้อมูลนี้ไม่สามารถใช้โดยตรงได้ เราใช้เวลามากมายในการประมวลผลข้อมูลล่วงหน้าเนื่องจากเราประสบปัญหาต่อไปนี้ และเราสามารถแก้ไขบางส่วนได้

  1. SSID บางส่วนไม่สามารถใช้งานได้อย่างต่อเนื่อง ดังนั้นเราจึงลบ SSID ชั่วคราว (คอลัมน์) และดำเนินการต่อด้วย SSID แบบถาวร
  2. จุดข้อมูลน้อยลง — ประมาณ 350 ตัวอย่างสำหรับแต่ละเหตุการณ์ แต่เราใช้การเพิ่มข้อมูล
  3. บางฟิลด์ว่างเปล่า ดังนั้นเราจึงเติมฟิลด์ที่ขาดหายไปด้วยค่าที่คล้ายกันจากตัวอย่างอื่นๆ
  4. การทำให้ชุดข้อมูลเป็นมาตรฐานอาจช่วยปรับปรุงประสิทธิภาพได้

ตัวอย่างฟิลด์ว่างแทนที่โค้ด



ในส่วนการรวบรวมข้อมูลการส่งข้อมูลไปยังเซิร์ฟเวอร์ eclipse mqtt อาจเพิ่มเวลาแฝง เนื่องจากเราต้องการเร่งกระบวนการ เราจึงโฮสต์เซิร์ฟเวอร์ MQTT ในเครื่องโดยใช้ Docker

ตรวจสอบ https://www.docker.com/get-started จากนั้นคุณสามารถดึงอิมเมจนักเทียบท่าและเพิ่มเซิร์ฟเวอร์ MQTT mosquitto ได้อย่างง่ายดายโดยเรียกใช้การติดตามใน PowerShell

docker run -it -p 1883:1883 -p 9001:9001 -v mosquitto.conf:/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto

3. โมเดลการเรียนรู้ของเครื่องฝึกอบรม

ที่นี่เราลองใช้โมเดลไม่กี่โมเดล แต่ไม่ได้เจาะลึกการเรียนรู้ของเครื่องมากเกินไป เราตรวจสอบผลลัพธ์ของรุ่นต่อไปนี้

  1. รองรับเครื่องเวกเตอร์ (SVM)
  2. Gaussian Naive Bayes (เกาส์เซียน NB)
  3. การถดถอยโลจิสติกหลายเส้น
  4. ลักษณนามต้นไม้การตัดสินใจ
  5. K เพื่อนบ้านลักษณนาม

ลองดู :)

# 1. Importing libraries
import json
import csv
import os
import pandas as pd
import numpy as np 
import pickle 

from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier

from sklearn.model_selection import train_test_split  
from sklearn.metrics import classification_report, confusion_matrix 

# 2. Importing the dataset
#Download the dataset from database as a CSV file and store in the local directory. 
#To read data from CSV file, the simplest way is to use read_csv method of the pandas library. 
wifidata = pd.read_csv("./final-data-set.csv")   #change your file name

# 3. Exploratory Data Analysis
#check the dimensions of the data and see first few records
print("Dimensions of the data:")
print(wifidata.shape)
print("\nFirst few records:")
print(wifidata.head())

# 4. Data Preprocessing
# To divide the data into attributes and labels
X = wifidata.drop('id', axis=1)  #contains attributes
y = wifidata['id'] # contains corresponding labels

#divide data into training and test sets 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20)

# 5. Training the Algorithm
models=[]
models.append(('SVC',SVC(kernel='linear')))
models.append(('GNB',GaussianNB()))
models.append(('LR',LogisticRegression(C=1e5, solver='lbfgs',multi_class='multinomial')))
models.append(('DTC',DecisionTreeClassifier(random_state=0)))
models.append(('KNN',KNeighborsClassifier(n_neighbors=3)))

for name,model in models:
    print(name+" : Training starting")
    classifier = model  
    classifier.fit(X_train, y_train) # train the algorithm on the training data

    # 6. Making Predictions
    y_pred = classifier.predict(X_test)

    # 7. Evaluating the Algorithm
    #Confusion matrix, precision, recall, and F1 measures are the most commonly used metrics for classification tasks.
    print("\nConfusion Matrix:")
    print(confusion_matrix(y_test,y_pred))
    print("\nClassification Report:")
    print(classification_report(y_test,y_pred))

    # 8.save the model to disk
    filename =name+'_finalized_model.pkl'
    pickle.dump(classifier, open(filename, 'wb'))

เมื่อคุณรันโปรแกรมการฝึกโมเดล เราจะได้รับความแม่นยำ การเรียกคืน และคะแนน F1 ของโมเดลที่ได้รับการฝึกแต่ละโมเดล ดังนั้นเราจึงสามารถเลือกอันที่ดีกว่าเพื่อให้เหมาะกับการใช้งานของเรา

การแสดงชุดข้อมูลยังช่วยให้เราระบุปัจจัยสำคัญในชุดข้อมูลได้อีกด้วย

การกระจายข้อมูล

จุดข้อมูลทั้งหมดของจุดเชื่อมต่อไร้สายแต่ละจุดจะถูกพล็อตในระดับเดียวกัน รัศมีของแต่ละจุดเป็นสัดส่วนกับความถี่ของค่า RSSI ที่เกี่ยวข้อง สิ่งนี้ช่วยให้เข้าใจพฤติกรรมของข้อมูล

ข้อสังเกต :

  • ค่า RSSI บางค่ามีความถี่สูงกว่า (จุดที่มีรัศมีสูงกว่า)
  • คะแนนที่มีความถี่สูงกว่าของแต่ละ AP จะไม่อยู่ในรูปแบบเดียวกัน

โครงเรื่อง 3 มิติ (พิจารณาจุดเข้าใช้งาน 3 จุด)

พล็อต 3 มิติต่อไปนี้ได้รับการพัฒนาโดยอิงจากชุดข้อมูลของจุดเชื่อมต่อไร้สายสามจุด ชามิดี, นิปูนาเอ็ม, อิซูรูอาป.

ข้อสังเกต:

  • 3 กลุ่มสำหรับกิจกรรมที่ไม่มีบุคคล สองคน ห้าคน

พล็อต 5D (พิจารณา 5 AP)

ที่นี่เรากำลังพยายามพล็อตจุดข้อมูลทั้งหมดในการแสดง 5D

X — ค่า Chamidi1

Y — ค่า NipunaM6

Z — ค่า IsuruAp6

สี — ค่า UNIC-wifi11

ขนาด — ค่า UoM_Wireless11

Marker — คลาสของจุดข้อมูล

เครื่องหมาย ',' สำหรับ 0 คลาส, เครื่องหมาย 'o' สำหรับ 1 คลาส และเครื่องหมาย 'x' สำหรับจุดข้อมูล 2 คลาส เราสามารถระบุสามคลัสเตอร์แยกกันซึ่งคาดว่าจะระบุโดยอัลกอริทึม SVM

รหัสสำหรับแปลงเหล่านี้ในฐานรหัสโครงการ

ยอดเยี่ยม!!!

ตอนนี้เรามีระบบที่ดีกว่าพร้อมรุ่นที่ดีกว่า

4. การทำนายข้อมูลแบบเรียลไทม์

บันทึกโมเดลลงในผักดอง เพื่อที่เราจะได้โหลดใหม่ในโปรแกรมอื่นได้ ไคลเอ็นต์ python mqqt จะฟังหัวข้อและข้อมูลขาเข้าจะถูกส่งไปยังโมเดลที่สร้างการคาดการณ์ว่าไม่มีบุคคล/1 คน/5 คนในพื้นที่นั้น

import pickle
import datetime
import pandas as pd
import paho.mqtt.client as mqtt
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
import ast
# Starting.
print("###### Welcome to wifi person detector ######")
# callback for connecting to the server
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("entc/wifipd")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    try:
        print("-----------------------------")
        print(msg.topic+" "+str(msg.payload))
        data1=msg.payload
        dic = ast.literal_eval(data1.decode("utf-8"))
        #print(dic)
        p = [dic.setdefault("Chamidi1",-100),dic.setdefault("NipunaM1",-100),dic.setdefault("IsuruAp6",-100),dic.setdefault("UoM_Wireless1",-100),dic.setdefault("UNIC-wifi11",-100)]
        p=list(map(int,p))
        print("p",p)
        # Making Predictions
        y_pred = model.predict([p])
        person = 0
        if y_pred[0] == 1:
            person = 1
        elif y_pred[0] == 2:
            person = 5
        
        print(datetime.datetime.now())
        print(str(person) + " person/s detected.")
    except Exception as e:
        print(e)
# Load the model from disk
filename = 'finalized_model.pkl'
file = open(filename, 'rb')
model = pickle.load(file)
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("iot.eclipse.org", 1883, 120)
client.loop_forever()

บูม ตอนนี้คุณมีเครื่องตรวจจับบุคคลที่สมบูรณ์โดยใช้ WiFi แล้ว หากคุณยังคงอ่านอยู่ ก็คุ้มค่าที่จะดูที่ฐานโค้ด



ขอให้มีความสุขในการเขียนโค้ด!!!