#author("2023-11-13T15:33:44+09:00","default:cmdsadmin","cmdsadmin") [[第7回]] #author("2024-05-07T10:39:55+09:00","default:cmdsadmin","cmdsadmin") * 第7回演習課題 [#w3bb626b] ** 基礎問題 [#e586be99] ''Q7-1 【迷惑メールをみつけよう・次元削減Ver.】'' - 第3回の課題 [[Q3-2【迷惑メールをみつけよう】>第3回/演習#a86c4d07]]を,次元削減を行って解いてみよう. - はじめに,下記のステップに従って,特徴量を2次元に削減し,散布図で可視化しなさい. + データ spam-sample.csv をロードしなさい + 特徴量の列と正解データの列を指定し,特徴量Xと正解データyを取り出しなさい -- 特徴量は第0列~第56列をすべて,正解データは第57列としなさい + 訓練データとテストデータに分割しなさい -- X_train, X_test, y_train, y_test -- random_stateを1234, テスト割合を0.4としなさい + X_trainを標準化し,データフレームX_train_scに入れなさい + X_train_scに主成分分析を適用しなさい. -- X_train_scを変換し,主成分得点を求めてデータフレームX_train_pcaに入れなさい -- 主成分負荷量を入れたデータフレームdf_comp を作成しなさい -- 分散,寄与率,累積寄与率を入れたデータフレーム df_varを作成しなさい + 次の要領にしたがって,散布図を描きなさい -- X_train_pcaから第1主成分,第2主成分のみを取り出し,X_train_dimとしなさい -- X_train_dimにy_trainを列方向(axis=1)に結合し,X_train_dim_testとしなさい -- X_train_dim_testを散布図に書きなさい.x軸を"第1主成分", y軸を"第2主成分", 色付け(hue)を"迷惑メール"とすること #準備(すべてに共通) # PandasとNumpyをインポート import pandas as pd import numpy as np # 日本語化Matplotlibもインポート import matplotlib.pyplot as plt #↓の1行は提出時にはコメントアウトしてください !pip install japanize-matplotlib import japanize_matplotlib # Seabornもインポート import seaborn as sns # pickleをインポート(モデルの保存用) import pickle #データフレームをきれいに表示するメソッド from IPython.display import display #標準化はよく使うのでインポート from sklearn.preprocessing import StandardScaler # Step1: データの取得 # 迷惑メールの取得 spam_data = pd.read_csv("https://www2.cmds.kobe-u.ac.jp/~masa-n/dshandson/spam-sample.csv",encoding="utf8") # 確認 display(spam_data.head(10)) #Step2: 列の選択 #特徴量に指定する列名リスト.データの列名の0~56をスライスで取得 features = spam_data.columns[###:###] #正解データに指定する列名.データの列名の最後のものをスライスで取得 target = spam_data.columns[###:###] #特徴量 X = spam_data[######] #正解データ y = spam_data[######] #Step3: 訓練データ,テストデータの分割 #X, yのそれぞれを訓練データとテストデータに分ける (訓練:テスト=60:40) from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(##, ##, ##############=0.4, #########=1234) #Step4: 標準化 sc = StandardScaler() # 訓練データをフィット sc.###(######) # 変換してデータフレームに入れる X_train_sc = pd.DataFrame(sc.#########(#######), index=#######.index, columns=#######.columns) #確認 display(X_train_sc.head(10)) #Step5: PCAを適用 from sklearn.decomposition import PCA #白色化を有効にする pca = PCA(whiten=True) pca.###(##########) #表示用のラベル labels = [f"第{i+1}主成分" for i in range(#################)] # 主成分得点に変換してをデータフレームに入れる X_train_pca = pd.DataFrame(###############(#########), index=##############, columns=########) display(X_train_pca.head(10)) #主成分負荷量 df_comp = pd.DataFrame(pca.###########, index=labels, columns=#############) #主成分負荷量を表示 print("【主成分負荷量】") display(df_comp.head(10)) #分散,寄与率,累積寄与率 df_var = pd.DataFrame(pca.###############, index=#######, columns=["分散"]) df_var["寄与率"] = pca.################## df_var["累積寄与率"] = pca.#####################.#######() print("【分散・寄与率】") display(df_var.head(10)) #Step6: 散布図の作成 #第1,第2主成分のみを取り出す → 次元を2に削減 X_train_dim = X_train_pca.iloc[:,[0,1]] #正解訓練データを結合 X_train_dim_test = pd.#########([X_train_dim, ########], axis=1) #表示 display(X_train_dim_test.head(10)) #次元削減した訓練データの散布図を描く sns.scatterplot(###############, x="########", y="########", hue="迷惑メール", alpha=0.5) ''Q7-2 【次元削減したデータで分類モデルを作成する】'' - 前問に引き続き,次元削減した特徴量を用いて,迷惑メールを分類するモデルを作成したい.以下のステップに従って,分類モデルを作成しなさい. + ロジスティック回帰モデルでmodelを生成しなさい -- パラメータは,random_state = 1234, C = 0.1, multi_class = 'auto', solver = 'lbfgs' とする + 訓練データX_train_dim, y_trainでモデルを学習しなさい. + 以下の要領で,次元削減したX_test_dimを作成しなさい. -- X_testに標準化を適用して,X_test_scを作成する.ただし,スケーラーは以前に学習したscを使う -- X_test_scにPCAを適用して,主成分得点X_test_pcaを得る.ただし,pcaモデルは以前学習したpcaを使う -- X_test_pcaから第1主成分,第2主成分を取り出して,X_test_dimとする + X_test_dim, y_test でモデルを評価しなさい -- 分類精度を求めて,2次元に削減した特徴量でどの程度の精度が達成できたかを確認しなさい -- 混同行列を作成しなさい -- 分類の評価レポートを表示しなさい ##### Q7-1のコードを↓に貼り付ける ##### ここまで # Step1: ロジスティック回帰モデルを作成 from sklearn.linear_model import LogisticRegression model = LogisticRegression(random_state = 1234, C = 0.1, multi_class = 'auto', solver = 'lbfgs') # Step2: モデルを学習 # アルゴリズムによっては,Warnng: A column-vector y was passed when a # 1d array was expected が出る場合があり,その場合は↓のようにする model.fit(#########, y_train.values.ravel()) # Step3: 次元削減したテストデータを作成 ### X_testに標準化を適用 X_test_sc = pd.DataFrame(###############(X_test), index=X_test.index, columns=X_test.columns) ### PCAを適用.主成分得点を求める X_test_pca = pd.DataFrame(##############(#########), index=############, columns=#######) ### 第1・第2主成分のみを取り出す X_test_dim = X_test_pca.iloc[:, [0,1]] # Step4: モデルを評価する ### 分類精度を求める acc = model.score(###########, ########) print(f"【分類精度】 {acc}") ### 混同行列を作成する from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay ###予測したyの値 y_pred = model.############(###########) cm = confusion_matrix(########, ########) print("混同行列:\n", cm) #混同行列をプロットする(オプショナル) disp = ConfusionMatrixDisplay(confusion_matrix=####, display_labels=model.classes_) disp.plot() #分類レポートを表示する from sklearn.metrics import classification_report report = classification_report(y_pred = ########, y_true = ########, output_dict=True) display(pd.DataFrame(report)) ** 応用問題 [#s5d196b8] ''Q7-3【最適なハイパーパラメータを求めよう】'' - 第6回教師あり学習:分類モデルのハンズオン6-2 ランダムフォレストの最適なハイパーパラメータを求めよ。最適なハイパーパラメータの値を確認したうえで,そのハイパーパラメータを使用し,テストデータを分類した際のaccuracyを表示せよ。 -- 読み込むデータ,欠損値の処理,特徴量や目的変数,ダミー変数化,機械学習アルゴリズムはハンズオン6-2と同様とする。 -- 訓練・検証データと,テストデータは7:3に分割する。 -- GridSearchCVを用いる。 --- 10分割交差検証とする。 --- 探索するハイパーパラメータは、n_estimators(決定木数)、max_depth(木の深さの最大値)とする。範囲は、n_estimatorsは10, 100, 200, 300、max_depthは5, 10, 50とする。 ''作成したところまでのプログラムのipynbファイルを提出しなさい'' ** 発展問題 [#saf97b3d] ''Q7-4【迷惑メール検出のための機械学習APIを作ってみよう】'' - 文書を入力すると,迷惑メールかが検出でき,かつ正解率も出力可能なAPIを実装せよ - 【問い】ヒント1~3を参考し,''2種の.ipynbファイルを提出''せよ -- ① ''server.ipynb'':モデルを学習・評価し,さらにモデルをサーバにデプロイ -- ② ''application.ipynb'':サーバ指定先へデータを送信し,検出結果を受ける - 【ヒント1】モデル構築・評価(※ 以下のコードを深く理解・補充実行) -- Step 1-1: データ読み込み # ライブラリをインポート import pandas as pd from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import CountVectorizer # データの読み込み data=pd.read_csv('https://www.es4.eedept.kobe-u.ac.jp/~chensinan/share/Spam.csv', usecols=[0, 1], encoding='iso-8859-1') data -- Step 1-2: データ前処理 # データセットをランダム化 randomised_data=data.sample(frac=1,random_state=1) # ターゲット(ラベル)を数値特徴量に変換 randomised_data.Label=(randomised_data.Label=="spam").astype(int) # トレーニングデータとテストデータの分割 data_train,data_test=train_test_split(randomised_data,test_size=0.2,random_state=1) y_train=data_train["Label"] y_test=data_test["Label"] # トレーニングおよびテストデータのラベルを削除 del data_train["Label"] del data_test["Label"] # SMSから句読点を削除 data_train["SMS"]=data_train["SMS"].replace("\W", " ", regex=True) data_test["SMS"]=data_test["SMS"].replace("\W", " ", regex=True) # 文字を小文字に変換 data_train["SMS"]=data_train["SMS"].str.lower() data_test["SMS"]=data_test["SMS"].str.lower() # データ変換 vectorizer = CountVectorizer() X_train_encoded = vectorizer.fit_transform(data_train['SMS']) X_test_encoded = vectorizer.transform(data_test['SMS']) -- Step 1-3: モデル学習・評価 --- 学習モデルも評価手法も自選. --- ただし,モデル精度を90%以上に目指したいこと - 【ヒント2】モデルデプロイ -- Step 2-1: 必要なモジュールをインストール(参考:[[7.5 教材内容>https://www2.cmds.kobe-u.ac.jp/wiki/dshandson/?%E7%AC%AC7%E5%9B%9E#r561de67]]) -- Step 2-2: サーバ側のリクエスト body を定義 --- {"message": "Oh k...i'm watching here:)"}のような入力データを受け取る -- Step 2-3: POSTメソッド,かつサーバ受信先を指定 -- Step 2-4: 受信されたデータには,以下の処理をさせる +++ message内容を抽出・リスト化,新規データフレームに入れる +++ データ前処理(小文字へ変換,ベクトル化 ※ 参考:ヒント1) +++ 検出結果 (model.predict) と正解率 (model.predict_proba)を出力 正解データラベルのデフォルトは 値0が非迷惑(ham),値1が迷惑(spam) そのため,適当にif文で区別し,値を代入してください - 【ヒント3】データ送信・検出結果受け -- Step 3-1: 必要なモジュールインストール,POST先を指定 -- Step 3-2: アプリ側では送信するデータを設定 (Step2-2のようなデータ) -- Step 3-3: データPOSTとレスポンス内容の確認 --- 出力例,{"label":"spam","label_probability":0.9754219513602876} ''作成したところまでのプログラムのipynbファイルを提出しなさい''