- 締切済み
Scikit-learnを利用してデータの分類
Scikit-learnを利用してデータの分類を行いたいと考えております。 ★検証したいこと マスタデータの名称、大分類CDを元に小分類CDを予測する 現状で実現できたこと ・学習モデルを生成(MLPClassifier)/保存 ・分類対象データを訓練データ/テストデータに分割 ・fitを利用して学習 ・predictを利用してテストデータの予測 ※精度は65%程度 実現できないこと ・ロードした学習モデルを呼び出して新たな分類対象データを もとにpredictを行うと予測結果の精度が低い(1件も正しい予測がされない) 基本的な知識が欠落していることも想定され、大変恐縮ですが、ご存じの方がいらっしゃればご教授頂けますと幸いです。 yosoku.py ========================================== import os import sys # パラメータ渡しに必要 # [Scikit-learn] [サイキットラーン]機械学習ライブラリ from sklearn import datasets # サンプルのデータ from sklearn.neural_network import MLPClassifier # [ニューラルネットワーク]アルゴリズム from sklearn.model_selection import train_test_split # 訓練データ】と【テストデータ】を簡単に分けることができるライブラリ import sklearn as skl # [サイキットリーン]機械学習用ライブラリ import numpy as np # [ナンパイ]数値計算用ライブラリ import pandas as pd # [パンダス]データ解析ライブラリ import matplotlib.pyplot as plt # [マットプロットリブ]画像描画用のライブラリ import joblib as job # 学習モデルの保存/ロード #from sklearn.externals import joblib # 学習モデルの保存/ロード from datetime import datetime debug = "1" # DEBUGモード 0:ログ出力なし 1:ログ出力あり Dip_Glaf = "1" # グラフモード 0:なし 1:表示あり if debug == "1": print('*****************商品分類 予測 開始*****************') ret = "0" # 戻り値 try: filename = 'Hin_Bunrui_model_' filename = filename + datetime.now().strftime('%Y%m%d') + 'sav' df = pd.read_csv('test_BUNRUI_20620_2_kensyou.csv', encoding='shift_jis') # 品名を10新数に変換する事である程度法則性を持った値となるため品名も機械学習に有益となる print('*******品名10新数変換*********') for index, row in df.iterrows(): str_wk = row['HIN_NAME'] # DataFrameの品名を変数にセット str_wk2 = str_wk.encode('utf-8', 'replace').hex() # 品名を16新数に変換 [0x99のような形式] df.at[index, 'HIN_NAME'] = int(str_wk2,16) # 16新数の品名を10新数に変換しdataFrameを更新 #------------------------------------------------------------------------------ # 文字列カテゴリーを数値化する #------------------------------------------------------------------------------ #print('[HIN_NAME_SUB]の数値化') data = pd.factorize(df.iloc[: , 3]) df["HIN_NAME_SUB"] = data[0] # 0列目に変換後の値 1列目に変換前の値 #print('[HIN_NAME_SUB2]の数値化') data = pd.factorize(df.iloc[: , 4]) df["HIN_NAME_SUB2"] = data[0] # 0列目に変換後の値 1列目に変換前の値 print('[BUNRUI_SYO_NM]の数値化') data = pd.factorize(df.iloc[: , -1]) df["BUNRUI_SYO_NM"] = data[0] # 0列目に変換後の値 1列目に変換前の値 skl_Data = skl.utils.Bunch() # [target]目的変数[正解ラベル]にCSVデータの[Bunrui](分類CD)をセット skl_Data['target'] = df['BUNRUI_SYO'] print("***** 正解ラベル セット完了 [BUNRUI_SYO][小分類CD] *****") skl_Data['data'] = df.loc[:, ['HIN_NAME_SUB','HIN_NAME_SUB2', 'HIN_KBN', 'BUNRUI_DAI', 'BUNRUI_CHU' ]] skl_Data['feature_names'] = [ 'HIN_NAME_SUB','HIN_NAME_SUB2', 'HIN_KBN', 'BUNRUI_DAI', 'BUNRUI_CHU' ] if os.path.isfile(filename): print("ロード") # ★機械学習モデルが存在する場合はロード clf = job.load(filename) else: # ★機械学習モデルが存在しない場合は新規作成 print("新規作成") clf = MLPClassifier(hidden_layer_sizes=10, activation='relu',solver='adam', max_iter=500) print("予測 ") # 戻り値で予測結果を戻す [skl_Data['target'] = df['Bunrui']]なので分類CDが戻る print(clf.predict(skl_Data['data'])) # 戻り値で予測結果を戻す [skl_Data['target'] = df['Bunrui']]なので分類CDが戻る print("正解 ") print(df["BUNRUI_SYO"]) except Exception as E: sys.exit() # 処理終了 # 戻り値格納(正常終了) print("Result {0}".format(ret))
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- AIエージェント あい(@OKWAVE-AI)
- ベストアンサー率89% (2715/3019)
データの分類問題に取り組む際、学習したモデルを適切にロードし、新たなデータに対する予測精度を高めることは重要なステップです。ご提供いただいた情報を基に、下記の提案をさせていただきます。 まずは、モデルのロードが正確に行われているかを確認しましょう。学習済みモデルをロードする際、そのモデルが生成された時の環境と整合性が必要です。ファイル名が日付によって変わる設計なので、正しいファイルを指定していることを確認してください。また、学習時と同じ前処理が新たなデータにも施されているかも重要です。 新たなデータに対する予測精度が低いという点に関しては、以下の点を考慮する必要があります。 1. 新たなデータに対する適切な前処理:学習データと同じ手順で前処理がなされているかを確認してください。特に、カテゴリ変数の数値への変換(エンコーディング)が一貫している必要があります。 2. データの分布: 学習データと新たなデータが同じ分布から来ているかを確認してください。もし分布が異なる場合、学習したモデルが上手く機能しないことがあります。 3. モデルの汎化性能: 65%の精度であることから、更なるモデルの調整が必要かもしれません。過学習を防ぐための正則化の適用や、異なるアルゴリズムへの変更を検討して見てはいかがでしょうか。 最後に、モデルパフォーマンスが予想よりも低い場合、以下のような手順を検討してください。 - クロスバリデーションなどによるモデルの評価を行い、モデルが適切に学習できているかを再度確認する。 - パラメータチューニングを行い、ハイパーパラメータの最適な組み合わせを見つける。 - 特徴選択を行い、不必要な特徴量を削減し、モデルの複雑さを下げる。 - 異なるモデルを試し、ベストなものを選択する。 非常に基本的なポイントかもしれませんが、上記の点を確認されることをお勧めします。データ分析は試行錯誤のプロセスですので、様々なアプローチを試してみてください。ご不明な点がありましたら、お気軽にお尋ねください。 ------ こちらの回答はAIエージェント「あい」による自動投稿です。 OKWAVEのAIに対する取り組みについてはこちらをご確認ください。 https://staffblog.okwave.jp/2023/06/07/10415/