Вопрос или проблема
import os
import joblib
import numpy as np
import pandas as pd
from sklearn.metrics import accuracy_score, classification_report
from tqdm import tqdm
from PIL import Image
from sklearn.cluster import KMeans
# Функция для загрузки обученной модели
def load_trained_model(model_file_path):
try:
model = joblib.load(model_file_path)
print(f”Модель загружена из {model_file_path}”)
return model
except Exception as e:
print(f”Ошибка загрузки модели: {e}”)
return None
def extract_features(image_path):
“””
Извлекает признаки из одного изображения.
Аргументы:
image_path (str): Путь к файлу изображения.
Возвращает:
NumPy массив, содержащий извлеченные признаки.
“””
try:
# Открыть изображение с помощью Pillow
img = Image.open(image_path)
# Преобразовать изображение в оттенки серого
img = img.convert(“L”)
# Изменить размер изображения
img = img.resize((128, 128))
# Преобразовать изображение в NumPy массив
img_array = np.array(img)
# Уплощение массива изображения для кластеризации
img_flat = img_array.flatten() # Форма будет (16384,)
# — ИЗВЛЕЧЕНИЕ ПРИЗНАКОВ —
mean_intensity = img_array.mean()
std_intensity = img_array.std()
# Кластеризация
kmeans = KMeans(n_clusters=2, random_state=0, n_init=10)
kmeans.fit(img_flat.reshape(-1, 1)) # Изменение формы для KMeans
cluster_centers = kmeans.cluster_centers_
labels = kmeans.labels_ # Сохранить как одномерный массив
# Вычислить стандартное отклонение внутри каждого кластера, используя уплощенное изображение
cluster_0_std = img_flat[labels == 0].std() if np.any(labels == 0) else 0
cluster_1_std = img_flat[labels == 1].std() if np.any(labels == 1) else 0
# Присвоить средние значения кластеров
cluster_0_mean = cluster_centers[0][0]
cluster_1_mean = cluster_centers[1][0]
features = np.array([mean_intensity, std_intensity, cluster_0_mean, cluster_1_mean, cluster_0_std, cluster_1_std])
return features.reshape(1, -1)
except Exception as e:
print(f”Ошибка обработки изображения {image_path}: {e}”)
return None
# Функция для загрузки и предварительной обработки данных изображений из директории
def load_image_data_from_directory(data_dir):
data = []
labels = []
filenames = []
label_mapping = {‘normal’: 0, ‘cancer’: 1, ‘PCOS’: 2, ‘cyst’: 3}
for subfolder in tqdm(os.listdir(data_dir), desc=”Обработка подпапок”):
subfolder_path = os.path.join(data_dir, subfolder)
if os.path.isdir(subfolder_path):
for filename in tqdm(os.listdir(subfolder_path), desc=f”Обработка {subfolder}”):
if filename.lower().endswith((“.png”, “.jpg”, “.jpeg”, “.tif”, “.tiff”, “.bmp”)):
file_path = os.path.join(subfolder_path, filename)
features = extract_features(file_path)
if features is not None:
data.append(features)
filenames.append(filename)
# Извлечь метку из имени файла
label_name = filename.split(“_”)[0]
if label_name == ‘abnormal’:
if ‘cancer’ in filename:
label_name=”cancer”
elif ‘PCOS’ in filename:
label_name=”PCOS”
elif ‘cyst’ in filename:
label_name=”cyst”
labels.append(label_mapping.get(label_name, -1))
if not data:
print(“Данные не найдены для обработки. Проверьте вашу директорию данных и форматы файлов.”)
return None, None, None
X = np.concatenate(data, axis=0)
y = np.array(labels)
print(“Форма X:”, X.shape)
print(“Форма y:”, y.shape)
return X, y, filenames
# Функция для оценки модели
def evaluate_model(model, X_new, y_new=None):
y_pred = model.predict(X_new)
if y_new is not None:
accuracy = accuracy_score(y_new, y_pred)
report = classification_report(y_new, y_pred)
print(f”Точность: {accuracy}”)
print(“Отчет о классификации:\n”, report)
else:
print(“Истинные метки не предоставлены для оценки.”)
return y_pred
# Функция для сохранения предсказаний в файл Excel
def save_predictions_to_excel(predictions, filenames, y_true, output_dir, output_file_name=”test_predictions.xlsx”):
df = pd.DataFrame({
‘Имя файла’: filenames,
‘Предсказание’: predictions,
‘Истинная метка’: y_true
})
label_mapping = {0: ‘normal’, 1: ‘cancer’, 2: ‘PCOS’, 3: ‘cyst’, -1: ‘unknown’}
df[‘Предсказание’] = df[‘Предсказание’].map(label_mapping)
df[‘Истинная метка’] = df[‘Истинная метка’].map(label_mapping)
if y_true is not None:
accuracy = accuracy_score(y_true, predictions)
accuracy_df = pd.DataFrame({‘Метрика’: [‘Точность’], ‘Значение’: [accuracy]})
else:
accuracy_df = pd.DataFrame()
output_path = os.path.join(output_dir, output_file_name)
writer = pd.ExcelWriter(output_path, engine=”xlsxwriter”)
df.to_excel(writer, sheet_name=”Предсказания”, index=False)
accuracy_df.to_excel(writer, sheet_name=”Точность”, index=False)
writer.close()
print(f”Предсказания сохранены в {output_path}”)
# Главная функция
def main():
model_path = “C:\\OVARIAN DISEASES(LATEST)\\OVARIAN DISEASES\\RANDOM_FOREST\\random_forest_model.joblib”
test_data_dir_relative = os.path.join(“OVARIAN DISEASES”, “Segmented_Datasets”, “Test”)
output_dir_relative = “OVARIAN DISEASES”
current_dir = os.getcwd()
test_data_dir = os.path.join(current_dir, test_data_dir_relative)
output_dir = os.path.join(current_dir, output_dir_relative)
os.makedirs(output_dir, exist_ok=True)
model = load_trained_model(model_path)
if model is None:
print(“Ошибка загрузки модели. Завершение работы.”)
return
X_new, y_new, filenames = load_image_data_from_directory(test_data_dir)
if X_new is None:
print(“Ошибка загрузки новых тестовых данных. Завершение работы.”)
return
predictions = evaluate_model(model, X_new, y_new)
save_predictions_to_excel(predictions, filenames, y_new, output_dir)
if __name__ == “__main__”:
main()
вывод:
Модель загружена из C:\OVARIAN DISEASES(LATEST)\OVARIAN DISEASES\RANDOM_FOREST\random_forest_model.joblib
Обработка подпапок: 0%| | 0/2 [00:00<?, ?it/s]Ошибка обработки изображения C:\OVARIAN DISEASES(LATEST)\OVARIAN DISEASES\Segmented_Datasets\Test\Cluster_1_Normal\Normal2288.jpeg: не удается идентифицировать файл изображения ‘C:\\OVARIAN DISEASES(LATEST)\\OVARIAN DISEASES\\Segmented_Datasets\\Test\\Cluster_1_Normal\\Normal2288.jpeg’
Обработка Cluster_1_Normal: 100%|██████████| 457/457 [00:20<00:00, 22.12it/s]
Обработка Cluster_2_Abnormal: 100%|██████████| 467/467 [00:22<00:00, 20.36it/s]
Обработка подпапок: 100%|██████████| 2/2 [00:43<00:00, 21.80s/it]
c:\Users\batri\AppData\Local\Programs\Python\Python39\lib\site-packages\sklearn\metrics\_classification.py:1531: UndefinedMetricWarning: Точность неопределена и устанавливается в 0.0 для меток без предсказанных образцов. Используйте параметр `zero_division` для управления этим поведением.
_warn_prf(average, modifier, f”{metric.capitalize()} is”, len(result))
c:\Users\batri\AppData\Local\Programs\Python\Python39\lib\site-packages\sklearn\metrics\_classification.py:1531: UndefinedMetricWarning: Полнота неопределена и устанавливается в 0.0 для меток без истинных образцов. Используйте параметр `zero_division` для управления этим поведением.
_warn_prf(average, modifier, f”{metric.capitalize()} is”, len(result))
c:\Users\batri\AppData\Local\Programs\Python\Python39\lib\site-packages\sklearn\metrics\_classification.py:1531: UndefinedMetricWarning: Точность неопределена и устанавливается в 0.0 для меток без предсказанных образцов. Используйте параметр `zero_division` для управления этим поведением.
_warn_prf(average, modifier, f”{metric.capitalize()} is”, len(result))
c:\Users\batri\AppData\Local\Programs\Python\Python39\lib\site-packages\sklearn\metrics\_classification.py:1531: UndefinedMetricWarning: Полнота неопределена и устанавливается в 0.0 для меток без истинных образцов. Используйте параметр `zero_division` для управления этим поведением.
_warn_prf(average, modifier, f”{metric.capitalize()} is”, len(result))
c:\Users\batri\AppData\Local\Programs\Python\Python39\lib\site-packages\sklearn\metrics\_classification.py:1531: UndefinedMetricWarning: Точность неопределена и устанавливается в 0.0 для меток без предсказанных образцов. Используйте параметр `zero_division` для управления этим поведением.
_warn_prf(average, modifier, f”{metric.capitalize()} is”, len(result))
c:\Users\batri\AppData\Local\Programs\Python\Python39\lib\site-packages\sklearn\metrics\_classification.py:1531: UndefinedMetricWarning: Полнота неопределена и устанавливается в 0.0 для меток без истинных образцов. Используйте параметр `zero_division` для управления этим поведением.
_warn_prf(average, modifier, f”{metric.capitalize()} is”, len(result))
Форма X: (923, 6)
Форма y: (923,)
Точность: 0.0
Отчет о классификации:
precision recall f1-score support
-1 0.00 0.00 0.00 923.0
1 0.00 0.00 0.00 0.0
точность 0.00 923.0
макро ср. 0.00 0.00 0.00 923.0
взвешенный ср. 0.00 0.00 0.00 923.0
Предсказания сохранены в C:\OVARIAN DISEASES(LATEST)\OVARIAN DISEASES\test_predictions.xlsx
Ответ или решение
Давайте тщательно разберемся с вопросом, связанным с нулевой точностью модели случайного леса в вашем коде. Причины, по которым модель может выдавать нулевую точность, могут быть разнообразными и включают как ошибки в загрузке и предобработке данных, так и особенности самой модели.
1. Проблемы с загружаемыми изображениями
Согласно выведенному сообщению об ошибке:
Error processing image C:\OVARIAN DISEASES(LATEST)\OVARIAN DISEASES\Segmented_Datasets\Test\Cluster_1_Normal\Normal2288.jpeg: cannot identify image file
Это указывает на то, что одна или несколько изображений не могут быть обработаны из-за несоответствий в формате файла или его повреждения. Это может привести к тому, что часть ваших данных будет недоступна для модели, что, в свою очередь, может снижать эффективность обучения и оценки.
Решение:
Убедитесь, что все изображения в директории корректные и могут быть открыты. Вы можете добавить проверку или какой-то механизм фильтрации для таких случаев, чтобы избежать добавления недействительных данных в выборку.
2. Пометка классов
Ваш код использует следующие метки для классов: normal (0)
, cancer (1)
, PCOS (2)
, cyst (3)
. Однако в вашем окончательном выводе в отчетах оказывается, что существуют и другие метки, такие как -1
(неизвестный). При этом если нет объектов с метками 1 и 2 (cancer или PCOS), это приведет к тому, что модель не сможет предсказать ни одного правильного результата, что является причиной получения точности равной 0.
Решение:
Проверьте входные данные для наличия классов, которые вы собираетесь классифицировать. Если у вас нет экземпляров некоторых классов (например, ‘cancer’), модель не сможет их предсказать, и точность будет нулевой. Убедитесь, что выборка содержит пример каждого класса.
3. Статистика классов
Ваш отчет показывает, что модель в основном предсказывает класс -1
. Это может произойти, если модель "заблокировалась" на этом классе из-за отсутствия данных других классов.
Решение:
- Убедитесь, что ваши данные сбалансированы. Если какой-либо класс слишком мал по количеству, рассмотрите возможность использования методов аугментации типов данных или увеличения выборки.
- Проведите анализ данных перед обучением, чтобы удостовериться в наличии достаточного количества примеров каждого класса.
4. Оценка модели
Так как вам не удалось получить никаких успешных предсказаний, это приводит к предупреждениям о недопустимых метриках UndefinedMetricWarning
. Это указывает на то, что в вашем наборе предсказаний отсутствуют экземпляры, относящиеся к некоторым классам.
Решение:
Пересмотрите параметры вашей модели или используйте более сложные гиперпараметры при обучении. Обратите внимание на качество и количество обучающего набора.
5. Отладка и Логирование
Добавьте больше логирования на ключевых этапах вашего кода. Это поможет вам лучше понять, где могут возникать проблемы. Например, вы можете сообщать о количестве загруженных изображений, размерах входных данных и частоте классов перед обучением модели.
Заключение
Модель случайного леса, возвращающая точность 0, обычно сигнализирует о серьезных проблемах с данными или обучением. Тщательно проверьте загрузку и обработку данных, а также наличие и распределение классов. Проведение этих шагов поможет вам идентифицировать проблемы и улучшить качество работы модели.