机器学习工具 - 导入数据集、训练模型、评估结果
import tkinter as tk from tkinter import *
from tkinter import filedialog from tkinter import scrolledtext import pandas as pd from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression, LogisticRegression from sklearn.naive_bayes import GaussianNB from sklearn.preprocessing import StandardScaler, LabelEncoder from sklearn.metrics import accuracy_score, mean_squared_error import matplotlib.pyplot as plt %matplotlib inline
class App: def init(self, root): self.root = root self.root.title('机器学习工具') self.root.geometry('800x400+10+10')
self.scr = scrolledtext.ScrolledText(self.root, width=65, height=20, font=('隶书', 12)) # 滚动文本框(宽,高(这里的高应该是以行数为单位),字体样式)
self.scr.place(x=200, y=10)
self.load_data_button = tk.Button(self.root, text='导入数据集', command=self.load_data, width=20)
self.load_data_button.place(x=20, y=10)
self.preprocess_button = tk.Button(self.root, text='数据预处理', command=self.preprocess_data, width=20)
self.preprocess_button.place(x=20, y=50)
self.split_data_button = tk.Button(self.root, text='划分训练集和测试集', command=self.split_data, width=20)
self.split_data_button.place(x=20, y=90)
self.model_var = tk.StringVar(self.root)
self.model_var.set('选择模型')
self.model_menu = tk.OptionMenu(self.root, self.model_var, '线性回归', '逻辑回归', command=self.select_model)
# self.model_menu = tk.OptionMenu(self.root, self.model_var, '线性回归', '逻辑回归', '高斯贝叶斯', command=self.select_model)
self.model_menu.config(width=15)
self.model_menu.place(x=20, y=130)
self.plot_button = tk.Button(self.root, text='显示散点图', command=self.drawPLT, width=20)
self.plot_button.place(x=20, y=170)
self.metric_var = tk.StringVar(self.root)
self.metric_var.set('选择评价指标')
# self.metric_menu = tk.OptionMenu(self.root, self.metric_var, '均方误差', command=self.evaluate_model)
self.metric_menu = tk.OptionMenu(self.root, self.metric_var, '准确率', '均方误差', command=self.evaluate_model)
self.metric_menu.config(width=15)
self.metric_menu.place(x=20, y=210)
def load_data(self):
file_path = filedialog.askopenfilename(filetypes=[('CSV Files', '*.csv')])
print(file_path)
if file_path:
self.nroot_data = pd.read_csv(file_path, encoding='gbk')
self.nroot = tk.Tk()
self.nroot.geometry('600x400+400+50')
self.nroot.resizable(True, True)
self.nroot.title('导入数据集')
self.nroot_model_val = tk.StringVar(self.nroot)
self.nscr = scrolledtext.ScrolledText(self.nroot, width=65, height=20,font=('隶书', 12)) # 滚动文本框(宽,高(这里的高应该是以行数为单位),字体样式)
self.nscr.place(x=20, y=10)
self.nroot_button = tk.Button(self.nroot, text='确定', command=self.nroot_getdata, width=20)
self.nroot_button.place(x=20, y=360)
self.nroot_button = tk.Button(self.nroot, text='取消', command=self.nroot_close, width=20)
self.nroot_button.place(x=180, y=360)
f = open(file_path, 'r', encoding='gbk')
for item in f.readlines():
self.nscr.insert(END, item)
self.nroot.mainloop()
def preprocess_data(self):
if hasattr(self, 'data'):
# 缺失值处理
self.data.fillna(self.data.mean(), inplace=True)
# 数值型数据标准化
num_cols = self.data.select_dtypes(include=['float64', 'int64']).columns
scaler = StandardScaler()
self.data[num_cols] = self.data[num_cols]
# 类别型数据编码
cat_cols = self.data.select_dtypes(include=['object']).columns
encoder = LabelEncoder()
for col in cat_cols:
self.data[col] = encoder.fit_transform(self.data[col])
self.scr.insert(END, '数据预处理完成\n')
else:
self.scr.insert(END, '请先导入数据集\n')
def nroot_getdata(self):
self.data = self.nroot_data
self.scr.insert(END, '数据集已导入\n')
self.nroot.destroy()
def nroot_close(self):
self.nroot.destroy()
self.scr.insert(END, '已取消导入数据集\n')
def split_data(self):
if hasattr(self, 'data'):
self.X_train, self.X_test, self.y_train, self.y_test = train_test_split(self.data.iloc[:, 2]/self.data.iloc[:, 3], self.data.iloc[:, 4], test_size=0.3, random_state=42)
self.train_logi, self.test_logi = train_test_split(self.data.iloc[:, 0:6], test_size=0.3, random_state=42)
self.scr.insert(END, '训练集和测试集划分完成\n')
else:
self.scr.insert(END, '请先导入数据集\n')
#这段代码是一个类的方法,用于将数据集划分为训练集和测试集。如果该类已经有了数据集(即存在属性'data'),
#则将'data'中的第2列除以第3列作为自变量X_train,
#第4列作为因变量y_train,将数据集划分为训练集和测试集,测试集占总数据集的30%。同时,将数据集中的前6列作为自变量train_l
def plot_data(self):
if hasattr(self, 'data'):
if self.model_var.get() == '线性回归':
self.trainDataLinear()
if self.model_var.get() == '逻辑回归':
self.trainDataLogistic()
else:
self.scr.insert(END, '请先导入数据集\n')
def trainDataLinear(self):
self.X_arr = []
for x in self.X_train:
self.X_arr.append([x])
self.Y_arr = []
for Y in self.y_train:
self.Y_arr.append(Y)
self.model.fit(self.X_arr, self.Y_arr)
self.X_tarr = []
for x in self.X_test:
self.X_tarr.append([x])
self.Y_tarr = []
for Y in self.y_test:
self.Y_tarr.append(Y)
self.y_pred = self.model.predict(self.X_tarr)
self.score = mean_squared_error(self.Y_tarr, self.y_pred)
#线性回归模型的训练过程,首先,将训练数据和测试数据分别转换为X_arr和Y_arr,其中X_arr是一个二维数组,每个子数组只包含一个特征值。
#然后,使用fit()方法将X_arr和Y_arr传递给线性回归模型进行训练。接着,将测试数据X_test转换为二维数组X_tarr,
#用predict()方法对X_tarr进行预测,得到y_pred。最后,使用mean_squared_error()方法计算预测值y_pred和真实值Y_tarr之间的均方误差得分。
def drawPLT(self):
if self.model_var.get() == '线性回归':
self.drawLinner()
if self.model_var.get() == '逻辑回归':
self.drawLogistic()
def drawLinner(self):
k = self.model.coef_ # 获取斜率w1,w2,w3,...,wn
b = self.model.intercept_ # 获取截距w0
x0 = pd.np.arange(0, 700, 1)
y0 = k * x0 + b
plt.scatter(self.X_tarr, self.Y_tarr, s=2)
plt.xlabel('单价')
plt.ylabel('周边学校个数')
plt.plot(x0, y0)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['figure.figsize'] = [12, 8]
plt.show()
#1.获取线性回归模型的斜率k和截距b。 #2.设置x轴范围为0到700,步长为1,生成x轴数据x0。 #3.根据直线方程y=kx+b,将x0代入,得到对应的y轴数据y0。 #4.以散点图的形式绘制训练数据集X_tarr和Y_tarr。 #5.设置x轴标签为“单价”,y轴标签为“周边学校个数”。 #6.绘制直线图,x轴为x0,y轴为y0。 #7.设置字体为中文,图像大小为12*8
def trainDataLogistic(self):
self.X_arr = []
self.Y_arr = []
for i, X in self.train_logi.iterrows():
self.X_arr.append([X['价格']/X['面积'], X['周边学校个数']])
self.Y_arr.append(X['城市'])
self.X_tarr = []
self.Y_tarr = []
for i, Y in self.test_logi.iterrows():
self.X_tarr.append([Y['价格'] / Y['面积'], Y['周边学校个数']])
self.Y_tarr.append(Y['城市'])
self.model.fit(self.X_arr, self.Y_arr)
self.X_pred = self.model.predict(self.X_tarr)
self.score = accuracy_score(self.Y_tarr, self.X_pred)
def drawLogistic(self):
tarrm = {
0.0: {'x': [], 'y': []},
1.0: {'x': [], 'y': []},
2.0: {'x': [], 'y': []}
}
idx = 0
for tarr in self.X_tarr:
if(tarr[0]>400):
continue
tarrm[self.X_pred[idx]]['x'].append(tarr[0])
tarrm[self.X_pred[idx]]['y'].append(tarr[1])
idx += 1
plt.scatter(tarrm[0.0]['x'], tarrm[0.0]['y'], s=4, c='#130ee7', label='北京', marker='o')
plt.scatter(tarrm[1.0]['x'], tarrm[1.0]['y'], s=8, c='#e605ff', label='上海', marker='d')
plt.scatter(tarrm[2.0]['x'], tarrm[2.0]['y'], s=4, c='#e99900', label='深圳', marker='^')
plt.xlabel('单价')
plt.ylabel('周边学校个数')
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['figure.figsize'] = [12, 8]
plt.legend()
plt.show()
#这段代码定义了一个名为drawLogistic的函数,用于绘制三种城市(北京、上海、深圳)的房价与周边学校个数的散点图。函数接受一个self参数,
#表示该函数是类的一个方法。函数中定义了一个字典tarrm,用于保存三种城市的房价和周边学校个数的坐标信息。
#然后遍历self.X_tarr,并将坐标信息存入tarrm中。最后使用matplotlib库绘制散点图,并加上相应的标签和图例。
def select_model(self, model_name):
if hasattr(self, 'X_train') and hasattr(self, 'y_train'):
if model_name == '线性回归':
self.model = LinearRegression()
elif model_name == '逻辑回归':
self.model = LogisticRegression()
elif model_name == '高斯贝叶斯':
self.model = GaussianNB()
self.plot_data()
self.scr.insert(END, f'{model_name}模型训练完成\n')
else:
self.scr.insert(END, '请先划分训练集和测试集\n')
def evaluate_model(self, metric_name):
if hasattr(self, 'model') and hasattr(self, 'X_test') and hasattr(self, 'y_test'):
if metric_name == '准确率':
self.scr.insert(END, f'{metric_name} : {self.score:.4f}\n')
elif metric_name == '均方误差':
self.scr.insert(END, f'{metric_name} : {self.score:.4f}\n')
else:
self.scr.insert(END, '请先训练模型\n')
if name == 'main': root = tk.Tk() app = App(root) root.mainloop() 详细讲解以上代码各部分功能及对应的程序内容:该程序是一个基于Tkinter和Scikit-learn库的机器学习工具,其主要功能包括导入数据集、数据预处理、划分训练集和测试集、选择模型、训练模型、绘制散点图和评价模型等。
- 导入数据集
该程序通过filedialog库提供的askopenfilename()方法,弹出文件选择对话框,让用户选择要导入的CSV文件。如果用户选择了文件,则使用pandas库的read_csv()方法读取CSV文件,并将数据存储到类的属性nroot_data中。同时弹出一个新的窗口,显示导入的数据集。
- 数据预处理
该程序提供了数据预处理的功能,包括缺失值处理和数据标准化、编码等操作。具体实现过程如下:
(1)使用pandas库的fillna()方法,将缺失值替换为该列的均值;
(2)使用pandas库的select_dtypes()方法,选择数据类型为float64和int64的列,作为数值型数据;
(3)使用Scikit-learn库的StandardScaler()方法,对数值型数据进行标准化处理;
(4)使用pandas库的select_dtypes()方法,选择数据类型为object的列,作为类别型数据;
(5)使用Scikit-learn库的LabelEncoder()方法,对类别型数据进行编码处理。
- 划分训练集和测试集
该程序使用Scikit-learn库的train_test_split()方法,将数据集划分为训练集和测试集。具体实现过程如下:
(1)如果类已经有了数据集(即存在属性'data'),则将'data'中的第2列除以第3列作为自变量X_train,第4列作为因变量y_train;
(2)使用train_test_split()方法将数据集划分为训练集和测试集,测试集占总数据集的30%;
(3)同时,将数据集中的前6列作为自变量train_logi。
- 选择模型
该程序提供了三种模型选择,分别是线性回归、逻辑回归和高斯贝叶斯。用户选择模型后,程序会根据选择的模型创建相应的模型对象,并调用相应的方法进行训练和评价。具体实现过程如下:
(1)如果类已经有了训练集和测试集(即存在属性'X_train'和'y_train'),则根据用户选择的模型名称,创建相应的模型对象;
(2)使用模型对象的fit()方法对训练集进行训练;
(3)使用模型对象的predict()方法对测试集进行预测,得到预测值;
(4)使用相应的评价指标对模型进行评价,包括准确率和均方误差。
- 绘制散点图
该程序提供了绘制散点图的功能,用于展示训练数据集和测试数据集的分布情况。具体实现过程如下:
(1)如果用户选择的是线性回归模型,使用matplotlib库的scatter()方法绘制散点图,并使用plot()方法绘制拟合的直线;
(2)如果用户选择的是逻辑回归模型,使用matplotlib库的scatter()方法绘制散点图,并使用legend()方法添加图例。
- 评价模型
该程序提供了评价模型的功能,用于展示训练模型后的评价指
原文地址: https://www.cveoy.top/t/topic/oPLV 著作权归作者所有。请勿转载和采集!