文章目录
- 前言
- 一、前期准备
- 开发环境:
- 二、Python KNN深度学习 算法
- 1.库引用
- 附录:训练数据
- 2.读入数据
- 3.预处理数据
- 三、Sklearn算法 创建模型
- 1.调整模型参数
- 2.训练模型
- 3.为C#窗口应用铺路
- 三、C#窗口应用
- 1.引用命名空间
- 2.框体设计
- 后续优化计划
前言
学校布置了WIFI室内定位相关作业,在网上查资料时候发现和自己有所了解的Python机器学习不谋而合。
网上很多介绍关于KNN最近邻Python机器学习的算法,但没有一个综合的解决方案,在篇文章意在记录与分享。谢谢大家了😊在这里求求一个赞!这对我真的很重要!❤️
实验中我负责的是上位机相关的开发 关于RSSI安卓开发可以参考其他程序。Android端可以通过/bin文件夹下offlinedatebase.txt进行操作 实现对接。
一、前期准备
Python对于深度学习可谓是轻车熟路,有很多相关的类可以进行机器学习。通过学习不同的视频与文章。还是选择了B站UP主帅器学习的视频为模板进行“二创” 加入C#进行可显示操作的Windows窗体工程。
代码主要会分为两块 : Python深度学习和C#窗口工程开发 并有一丢丢批处理文件(不足挂齿)
开发环境:
Visual Studio 2022 C# 窗体应用
Pycharm python 3.9环境
二、Python KNN深度学习 算法
1.库引用
引用 pandas标准化数据 尽量取消数据大小带来的差值
引用numpy进行txt文本处理 导入程序并处理
引用sklearn sklearn为深度学习模型 是一个python自带库可以直接引用 非常方便 用于处理一些小型的深度学习算法
代码如下:
import pandas as pd
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn import metrics
附录:训练数据
2.读入数据
在训练数据中 1-98表示进入模型训练的点,而99则表示“未知” 即我们所求的位置
相关代码:
#导入数据集 读进data.txt文件中的内容 间隔符为一个TAB
train_set = pd.read_csv('offlinedatebase.txt',sep = '\t')
由当前文件夹下的offlinedatebase.txt导入数据
3.预处理数据
#对数据进行分类 截提取数据特征
train = pd.concat([train_set['RSSI1'], train_set['RSSI2'], train_set['RSSI3'], train_set['RSSI4']],axis = 1)
#将特征数据转化成数组形式
train = np.array(train)
#将特征数据转标准化 train 储存特征
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
train = scaler.fit_transform(train)
print(train)
#将类别标签存入数组label
label = np.array(train_set['Label'])
我们将所有数据先分为两大部分
①标签部分(label)
②数据部分(RSSI 1~~4)并将这部分数据进行“训练模型标准化”(同时将未知的RSSI和训练数据一起标准化 确保模型训练后的结果准确性)
由于咱们的99位置位置也在数据部分中 我们需要把它们过滤出来⬇️
#将所求强度label与训练数据分离
ls = list(label)
for i in range(len(ls)):
if label[i] == 99:
del ls[i]
print(ls)
label = np.array(ls)
print(label)
过滤label 99 数据储存为numpy.array类型的数据 等待处理
#将所求强度 与训练数据分离
len_train = len(train)
X_exam = train[len_train-1,:]
X_exam_r = X_exam.reshape(1,4)
print(X_exam_r)
f_train = np.delete(train,len_train-1,0)
train = f_train
过滤RSSI数据 将最后一行的位置RSSI数据提取并保存 为X_exam_r
另一部分为训练数据 将送入模型学习
三、Sklearn算法 创建模型
1.调整模型参数
#分割数据集 既要测试既要模型 比率为0.9 0.1(可调)
X_train,X_test,y_train,y_test = train_test_split(f_train,label,train_size = 0.9,random_state=1)
#创建模型,放入训练数据 在这里 KNN 算法临近值设为5 关键参数为distance距离 根据场景不同可以适量调节
knn = KNeighborsClassifier(n_neighbors=5,weights = 'distance')
knn.fit(X_train,y_train)
#训练KNN算法模型
y_pred = knn.predict(X_test)#测试
print('model accuracy:',metrics.accuracy_score(y_test,y_pred))
print('数据训练完毕')
应用Sklearn算法模型 因为既要兼顾 训练 与 测试 我们将训练数据分为 90%训练 10%测试
KNN 算法距离设为5 关键参数为distance距离
2.训练模型
根据场景不同可以适量调节
ans = knn.predict(X_exam_r)
strans = str(ans)
strans = strans[1]
print(f"点的位置是{strans}")
3.为C#窗口应用铺路
将 位置的点送入 训练好的KNN算法模型 得到ANS
with open('ans.txt','w') as fff :
fff.write(str(ans))
with open('model accuracy.txt','w') as ggg:
ggg.write(str(metrics.accuracy_score(y_test,y_pred)))
# 按行读入,删除最后一行
file_old = open('offlinedatebase.txt', 'r', encoding="utf-8")
lines = [i for i in file_old]
del lines[-1]
file_old.close()
# 再覆盖写入
file_new = open('offlinedatebase.txt', 'w', encoding="utf-8")
file_new .write(''.join(lines))
file_new .close()
将ans答案写入ans.txt文本中存储
将model accuracy算法准确度
编辑offlinedatebase.txt将最后一行未知位置删除 保持数据库干净
三、C#窗口应用
窗口做的比较简朴 后续会对UI优化
预计增加TABLE可视化数据
1.引用命名空间
using System;
using System.IO;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
2.框体设计
保有设计完整性 解释性代码作为注释写在程序里
namespace KNN_WindowsForm
{
public partial class KNN : Form
{
//标题格式
public static string beginning = "Label\tRSSI1\tRSSI2\tRSSI3\tRSSI4\t\n";
class FileWriteAndOutput
{
//文件初始化函数
public void FileWhitePaper()
{
StreamWriter sw = File.AppendText("offlinedatebase.txt");
sw.Close();
File.Delete("offlinedatebase.txt");
FileStream F = File.Create("offlinedatebase.txt");
F.Close();
System.IO.File.WriteAllText("offlinedatebase.txt", beginning);
sw = File.AppendText("offlinedatebase.txt");
sw.Close();
}
//文件写入函数
public void FileWrite(string n)
{
StreamWriter sw = File.AppendText("offlinedatebase.txt");
sw.Close();
sw = File.AppendText("offlinedatebase.txt");
sw.WriteLine(n);
sw.Close();
}
//文件读取函数
public void FileRead()
{
Process processtemp = new Process();
processtemp = System.Diagnostics.Process.Start("notepad.exe", "offlinedatebase.txt");
processtemp.WaitForExit();
processtemp.Close();
}
}
//file write and output 类
FileWriteAndOutput fwao = new FileWriteAndOutput();
//初始化按下时候表示初始化offlinedatebase
private void button4_Click(object sender, EventArgs e)
{
fwao.FileWhitePaper();
}
public KNN()
{
InitializeComponent();
}
//添加数据库按钮按下时 在offlinedatebase添加一条记录
private void button1_Click(object sender, EventArgs e)
{
string StrOutput = "";
if (LabelNum.Text!=""&& BRSSI1.Text.ToString()!= ""&& BRSSI2.Text.ToString() != ""&& BRSSI3.Text.ToString() != "" &&BRSSI4.Text.ToString() != "")
{
StrOutput = LabelNum.Text.ToString() + '\t' + BRSSI1.Text.ToString() + '\t' + BRSSI2.Text.ToString() + '\t' + BRSSI3.Text.ToString() + '\t' + BRSSI4.Text.ToString();
fwao.FileWrite(StrOutput);
BRSSI1.Clear();
BRSSI2.Clear();
BRSSI3.Clear();
BRSSI4.Clear();
LabelNum.Clear();
}
}
//查看文件按钮按下时 用记事本只读方式打开offlinedatebase
private void button3_Click(object sender, EventArgs e)
{
fwao.FileRead();
}
//运行python KNN算法处理
private void button5_Click(object sender, EventArgs e)
{
this.RUNBAT();
}
public void RUNBAT()
{
Process proc = new Process();
proc.StartInfo.FileName = @"RUNpython.bat";
proc.StartInfo.Arguments = string.Format("10");//this is argument
proc.StartInfo.CreateNoWindow = false;
proc.Start();
proc.WaitForExit();
proc.Close();
}
//每一个计时器周期 更新位置id和算法准确率
private void timer1_Tick(object sender, EventArgs e)
{
try
{
StreamReader reader = new StreamReader(@"ans.txt");
label8.Text = reader.ReadToEnd();
reader.Close();
}
catch (Exception)
{
label8.Text = "Unknow";
}
try
{
StreamReader reader2 = new StreamReader(@"model accuracy.txt");
label10.Text = reader2.ReadToEnd();
reader2.Close();
}
catch (Exception)
{
label10.Text = "Unknow";
}
}
}
}
后续优化计划
更新 添加 KNNsf.py 参数可调功能
更新 使用SQL数据库 进行数据IO
更新 Android通过网络一键添加数据库
更新 优化窗口UI 增加table控件 使查看数据库更加直观