Как упаковать приложение python в .exe файл?
У меня есть приложение, написанное с помощью PyQt5, которое прогнозирует урожайность. Я использую уже готовые модели машинного обучения и некоторые библиотеки. Мне нужно всё это завернуть в один .exe файл. Как я могу это сделать? Я так понимаю, что мне нужно каким-то образом подгрузить мои модели и библиотеки, но вот как это сделать, я не пойму.
Вот код:
import sys
import numpy as np
import joblib
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QComboBox,
QLineEdit, QPushButton, QVBoxLayout, QMessageBox)
# Загрузка модели
model_path = 'model/random_forest_model.pkl'
model_path2 = 'model/xgb_model.pkl'
rf_model = joblib.load(model_path)
rf_model2 = joblib.load(model_path2)
# Пример данных для выпадающих списков
countries = ['Albania', 'Country2', 'Country3']
items = ['Maize', 'Wheat', 'Crops']
class CropYieldApp(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Прогнозирование урожайности с использованием машинного обучения')
# Создание виджетов
self.country_label = QLabel('Выберите страну:')
self.country_combo = QComboBox()
self.country_combo.addItems(countries)
self.item_label = QLabel('Выберите растение:')
self.item_combo = QComboBox()
self.item_combo.addItems(items)
self.pesticides_label = QLabel('Количество пестицидов:')
self.pesticides_input = QLineEdit()
self.avg_temp_label = QLabel('Средняя температура:')
self.avg_temp_input = QLineEdit()
self.rainfall_label = QLabel('Осадки:')
self.rainfall_input = QLineEdit()
self.predict_button = QPushButton('Получить прогноз')
self.predict_button.clicked.connect(self.get_prediction)
# Установка компоновки
layout = QVBoxLayout()
layout.addWidget(self.country_label)
layout.addWidget(self.country_combo)
layout.addWidget(self.item_label)
layout.addWidget(self.item_combo)
layout.addWidget(self.pesticides_label)
layout.addWidget(self.pesticides_input)
layout.addWidget(self.avg_temp_label)
layout.addWidget(self.avg_temp_input)
layout.addWidget(self.rainfall_label)
layout.addWidget(self.rainfall_input)
layout.addWidget(self.predict_button)
self.setLayout(layout)
def get_prediction(self):
try:
# Получение входных данных
country = self.country_combo.currentText()
item = self.item_combo.currentText()
pesticides = float(self.pesticides_input.text())
avg_temp = float(self.avg_temp_input.text())
rainfall = float(self.rainfall_input.text())
# Кодирование категориальных переменных
country_encoded = countries.index(country)
item_encoded = items.index(item)
# Подготовка входных данных
input_data = np.array([[country_encoded, item_encoded, pesticides, avg_temp, rainfall]])
# Прогноз
prediction_rf = round((rf_model.predict(input_data)[0]) / 10000, 2)
prediction_xgb = round((rf_model2.predict(input_data)[0]) / 10000, 2)
# Отображение результата
result_message = f"Прогноз (Random Forest): {prediction_rf} \n Прогноз (XGBoost): {prediction_xgb}"
QMessageBox.information(self, 'Результаты прогноза', result_message)
except ValueError:
QMessageBox.warning(self, 'Ошибка ввода', 'Пожалуйста, введите корректные числовые значения.')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = CropYieldApp()
window.show()
sys.exit(app.exec_())
В случае с моделями я использовал:
pyinstaller --onefile --windowed --add-data "model/random_forest_model.pkl;model" --add-data "model/xgb_model.pkl;model" my_app.py
Но после запуска ехе'шника вылезла такая ошибка:
Traceback (most recent call last):
File "my_app.py", line 20, in <module>
File "joblib\numpy_pickle.py", line 658, in load
File "joblib\numpy_pickle.py", line 577, in _unpickle
File "pickle.py", line 1213, in load
File "pickle.py", line 1538, in load_stack_global
File "pickle.py", line 1580, in find_class
ModuleNotFoundError: No module named 'sklearn'
Ответы (1 шт):
Проверьте my_app.py, к тому же, как сказал @Fox Fox, в PyQt5 вообще нет такого предмета как sklearn, поэтому советую найти его в коде, и заменить его на что либо, так как ModuleNotFoundError пишет, что в коде впринципе нет значения для модуля sklearn. Поэтому проверьте, установили ли вы значение для sklearn, если нет, то попробуйте проверить my_app.py