Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

画像クラスタリングのコードを書いてる際のエラーを助けていただきたいです。

解決したいこと

現在顕微鏡画像をクラスタリングするようなソースコードを書いています。
その際に発生したエラー(UnboundLocalError)の解決方法をご教授いただきたいです。

使用環境は
jupyetr notebook
python
になっています。
他に必要な情報があれば追記いたします。
よろしくお願いいたします。

この方の記事を参考にさせていただいております。
https://noleff.hatenablog.com/entry/2021/02/22/004156

発生している問題・エラー

UnboundLocalError                         Traceback (most recent call last)
Cell In[1], line 122
    118     plot_scatter3d(pca_df)
    121 if __name__ == "__main__":
--> 122     main()

Cell In[1], line 100, in main()
     97 CSV_PATH = r'C:/Users/kuror/image1/microscope_pca.csv'
     99 try:
--> 100     pca_df.to_csv(CSV_PATH, index=False)
    101 except FileNotFoundError:
    102     npy_image_list = load_image(LOAD_PATH)

UnboundLocalError: cannot access local variable 'pca_df' where it is not associated with a value

該当するソースコード

import glob as gb
import shutil
import cv2
import os
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
from mpl_toolkits.mplot3d import Axes3D


# 画像の読み込み
def load_image(path):
    image_list = []
    npy_image_list = []
    image_path_list = gb.glob(f"{path}/*")  # 画像の保存先次第で変更

    for i, image in enumerate(image_path_list):
        image_path = image.replace(chr(92), '/')  # Windows特有の問題を修正
        if i % 100 == 0:
            print(i)
        
        img_npy = cv2.imread(image_path, cv2.IMREAD_COLOR)
        img_npy = cv2.cvtColor(img_npy, cv2.COLOR_BGR2RGB)
        img_npy = cv2.resize(img_npy, (64, 64))
        img_npy = img_npy.flatten()
        npy_image_list.append(img_npy / 255)

    return npy_image_list


def build_kmeans(df, cluster_num):
    kmeans = KMeans(n_clusters=cluster_num, random_state=2021)
    kmeans.fit(df)
    return kmeans


def build_pca(df):
    pca = PCA()
    pca.fit(df)
    return pca


def plot_contribution_rate(pca):
    fig = plt.figure()
    plt.gca().get_xaxis().set_major_locator(ticker.MaxNLocator(integer=True))
    plt.plot([0] + list(np.cumsum(pca.explained_variance_ratio_)), "-o")
    plt.xlabel("Number of principal components")
    plt.ylabel("Cumulative contribution rate")
    plt.grid()
    plt.show()


def plot_scatter2d(df):
    fig = plt.figure()
    sns.scatterplot(data=df, x='PC1', y='PC2', hue='label', palette='bright', legend='full')
    plt.show()


def plot_scatter3d(df):
    fig = plt.figure()
    ax = Axes3D(fig)
    ax.set_xlabel("PC1")
    ax.set_ylabel("PC2")
    ax.set_zlabel("PC3")

    for label in df['label'].values:
        ax.plot(df.loc[df['label'] == label, 'PC1'],
                df.loc[df['label'] == label, 'PC2'],
                df.loc[df['label'] == label, 'PC3'],
                alpha=0.8, marker=".", linestyle='None')
    plt.show()


def make_cluster_dir(load_path, save_path, kmeans):
    shutil.rmtree(save_path, ignore_errors=True)
    os.makedirs(save_path, exist_ok=True)

    for i in range(kmeans.n_clusters):
        cluster_dir = os.path.join(save_path, f"cluster{i}")
        os.makedirs(cluster_dir, exist_ok=True)

    image_path_list = gb.glob(os.path.join(load_path, '*'))
    for label, path in zip(kmeans.labels_, image_path_list):
        shutil.copyfile(path, os.path.join(save_path, f'cluster{label}', os.path.basename(path)))

    print('クラスタごとにファイル作成完了')


def main():
    LOAD_PATH = 'C:/Users/kuror/image1/microscope'
    SAVE_PATH = 'C:/Users/kuror/image1/microscope_clustering'
    CSV_PATH = r'C:/Users/kuror/image1/microscope_pca.csv'
    
    try:
        pca_df.to_csv(CSV_PATH, index=False)
    except FileNotFoundError:
        npy_image_list = load_image(LOAD_PATH)
        df = pd.DataFrame(npy_image_list)
        print(df.shape)
        
        pca = build_pca(df)
        pca_df = pd.DataFrame(pca.transform(df), columns=[f"PC{x + 1}" for x in range(len(df.columns))])
        plot_contribution_rate(pca)
        pca_df.to_csv(CSV_PATH, index=False)
    
    train_df = pca_df.iloc[:, :1200]
    cluster_num = int(input('cluster_num > '))
    kmeans = build_kmeans(train_df, cluster_num)
    make_cluster_dir(LOAD_PATH, SAVE_PATH, kmeans)

    pca_df['label'] = kmeans.labels_
    plot_scatter2d(pca_df)
    plot_scatter3d(pca_df)


if __name__ == "__main__":
    main()
0 likes

4Answer

pca_df 変数に代入する前に変数を使っているからです。
参考サイトでは try の中で最初に pca_df = pd.read_csv(CSV_PATH) を行ってます。

1Like

元々の100行目はpca_df = pd.read_csv(CSV_PATH)でしたが、pca_df.to_csv(CSV_PATH, index=False)に変更されています。これがUnboundLocalErrorの原因だと思います。

一つ前の質問で回答済みです。

1Like

Comments

  1. @kurosoccer0515

    Questioner

    返信ありがとうございます。
    確かに元々100行目はpca_df = pd.read_csv(CSV_PATH)でした。こちらで実行した場合は一つ前の質問であるPermissionErrorが発生し、それの修正としてpca_df.to_csv(CSV_PATH, index=False)に変更したところ今回のエラーが発生しました。定義されていないとのことでしたので100行目をpca_df = pd.read_csv(CSV_PATH)に修正いたしましたが、PermissionErrorはどのように解決したらよろしいのでしょうか。ご教授お願いいたします。

  2. PermissionErrorなのでファイルを読む権限がないのではありませんか?
    単純にファイルを読むだけのプログラムを作って確認してはいかがでしょう?

  3. @kurosoccer0515

    Questioner

    ファイルを読むだけのプログラムを作って同じファイルを読ませてみましたが、同様のエラーでした。
    プロパティからファイルの読み取り専用を外しても修正されません。サイトなどで解決を探し試しましたが改善されませんでした。ほかに考えられる原因はありますでしょうか?

  4. テキストエディタでは開けるのですか?
    同じディレクトリの存在しないファイルを指定すれば FileNotFoundError 例外が発生しますか?

  5. 確かに元々100行目はpca_df = pd.read_csv(CSV_PATH)でした。こちらで実行した場合は一つ前の質問であるPermissionErrorが発生し、それの修正としてpca_df.to_csv(CSV_PATH, index=False)に変更したところ今回のエラーが発生しました。
    定義されていないとのことでしたので100行目をpca_df = pd.read_csv(CSV_PATH)に修正いたしましたが、PermissionErrorはどのように解決したらよろしいのでしょうか。ご教授お願いいたします。

    それを前回の質問で回答しましたが、理解されていなかったようですね。
    @megchandesu さんが指摘されている「質問者さんはPythonの知識が不足しているようなので入門書を一読された方が良いかと思います。その方が結局は近道になると思います。」です。

Comments

  1. @kurosoccer0515

    Questioner

    返信ありがとうございます。
    元々100行目にpca_df = pd.read_csv(CSV_PATH)という宣言をしていたのですが、CSV_PATH=r'C:/Users/kuror/image1/microscope_pca.csv'という部分でPermissionErrorに陥ってしまっている現状です。

直接的な回答はshiracamusさんやnak435さんがされていますので一つアドバイスをいたします。
質問者さんはPythonの知識が不足しているようなので入門書を一読された方が良いかと思います。その方が結局は近道になると思います。

ところで他にも質問を投稿されていますが、未だ未解決でしょうか?解決されたのであれば質問のクローズ処理をしましょう。放置を続けていると新しい質問にも回答が付きずらくなるかもしれません。未だ解決されていないなら現状の追記を行うと有識者から回答が付くかもしれません。

0Like

Your answer might help someone💌