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库的机器学习工具,其主要功能包括导入数据集、数据预处理、划分训练集和测试集、选择模型、训练模型、绘制散点图和评价模型等。

  1. 导入数据集

该程序通过filedialog库提供的askopenfilename()方法,弹出文件选择对话框,让用户选择要导入的CSV文件。如果用户选择了文件,则使用pandas库的read_csv()方法读取CSV文件,并将数据存储到类的属性nroot_data中。同时弹出一个新的窗口,显示导入的数据集。

  1. 数据预处理

该程序提供了数据预处理的功能,包括缺失值处理和数据标准化、编码等操作。具体实现过程如下:

(1)使用pandas库的fillna()方法,将缺失值替换为该列的均值;

(2)使用pandas库的select_dtypes()方法,选择数据类型为float64和int64的列,作为数值型数据;

(3)使用Scikit-learn库的StandardScaler()方法,对数值型数据进行标准化处理;

(4)使用pandas库的select_dtypes()方法,选择数据类型为object的列,作为类别型数据;

(5)使用Scikit-learn库的LabelEncoder()方法,对类别型数据进行编码处理。

  1. 划分训练集和测试集

该程序使用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. 选择模型

该程序提供了三种模型选择,分别是线性回归、逻辑回归和高斯贝叶斯。用户选择模型后,程序会根据选择的模型创建相应的模型对象,并调用相应的方法进行训练和评价。具体实现过程如下:

(1)如果类已经有了训练集和测试集(即存在属性'X_train'和'y_train'),则根据用户选择的模型名称,创建相应的模型对象;

(2)使用模型对象的fit()方法对训练集进行训练;

(3)使用模型对象的predict()方法对测试集进行预测,得到预测值;

(4)使用相应的评价指标对模型进行评价,包括准确率和均方误差。

  1. 绘制散点图

该程序提供了绘制散点图的功能,用于展示训练数据集和测试数据集的分布情况。具体实现过程如下:

(1)如果用户选择的是线性回归模型,使用matplotlib库的scatter()方法绘制散点图,并使用plot()方法绘制拟合的直线;

(2)如果用户选择的是逻辑回归模型,使用matplotlib库的scatter()方法绘制散点图,并使用legend()方法添加图例。

  1. 评价模型

该程序提供了评价模型的功能,用于展示训练模型后的评价指

机器学习工具 - 导入数据集、训练模型、评估结果

原文地址: https://www.cveoy.top/t/topic/oPLV 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录