บทช่วยสอน Scikit-Learn: วิธีการติดตั้งและตัวอย่าง Scikit-Learn

Scikit-learn คืออะไร?

วิทย์ - เรียน เป็นโอเพ่นซอร์ส Python ไลบรารีสำหรับการเรียนรู้ของเครื่อง รองรับอัลกอริทึมที่ทันสมัย ​​เช่น KNN, XGBoost, Random Forest และ SVM ไลบรารีนี้สร้างขึ้นบน NumPy Scikit-learn ถูกใช้กันอย่างแพร่หลายในการแข่งขัน Kaggle เช่นเดียวกับบริษัทเทคโนโลยีชั้นนำ ไลบรารีนี้ช่วยในการประมวลผลเบื้องต้น การลดมิติ (การเลือกพารามิเตอร์) การจำแนกประเภท การถดถอย การจัดกลุ่ม และการเลือกแบบจำลอง

Scikit-learn มีเอกสารที่ดีที่สุดของไลบรารีโอเพ่นซอร์สทั้งหมด จะให้แผนภูมิเชิงโต้ตอบแก่คุณที่ https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html.

Scikit Learn ทำงานอย่างไร
Scikit Learn ทำงานอย่างไร

Scikit-learn ใช้งานง่ายและให้ผลลัพธ์ที่ยอดเยี่ยม อย่างไรก็ตาม scikit Learn ไม่รองรับการคำนวณแบบคู่ขนาน คุณสามารถใช้อัลกอริธึมการเรียนรู้เชิงลึกได้ แต่ไม่ใช่วิธีแก้ปัญหาที่ดีที่สุด โดยเฉพาะอย่างยิ่งหากคุณรู้วิธีใช้ TensorFlow

วิธีดาวน์โหลดและติดตั้ง Scikit-learn.mq4

ตอนนี้อยู่ในนี้ Python บทช่วยสอน Scikit-learn เราจะเรียนรู้วิธีดาวน์โหลดและติดตั้ง Scikit-learn:

1 ตัวเลือก: AWS

สามารถใช้ scikit-learn บน AWS ได้ โปรด อ้างอิง อิมเมจนักเทียบท่าที่ติดตั้ง scikit-learn ไว้ล่วงหน้า

หากต้องการใช้เวอร์ชันนักพัฒนาให้ใช้คำสั่งใน Jupyter

import sys
!{sys.executable} -m pip install git+git://github.com/scikit-learn/scikit-learn.git

2 ตัวเลือก: แม็กหรือ Windows โดยใช้อนาคอนด้า

หากต้องการเรียนรู้เกี่ยวกับการติดตั้ง Anaconda โปรดดูที่ https://www.guru99.com/download-install-tensorflow.html

เมื่อเร็ว ๆ นี้ ผู้พัฒนา scikit ได้เปิดตัวเวอร์ชันสำหรับการพัฒนาที่จัดการกับปัญหาทั่วไปที่ต้องเผชิญกับเวอร์ชันปัจจุบัน เราพบว่าการใช้เวอร์ชันสำหรับนักพัฒนาซอฟต์แวร์แทนเวอร์ชันปัจจุบันจะสะดวกกว่า

วิธีติดตั้ง scikit-learn ด้วย Conda Environment

หากคุณติดตั้ง scikit-learn ด้วยสภาพแวดล้อม conda โปรดทำตามขั้นตอนเพื่ออัปเดตเป็นเวอร์ชัน 0.20

ขั้นตอน 1) เปิดใช้งานสภาพแวดล้อมเทนเซอร์โฟลว์

source activate hello-tf

ขั้นตอน 2) ลบ scikit แบบลีนโดยใช้คำสั่ง conda

conda remove scikit-learn

ขั้นตอน 3) ติดตั้งเวอร์ชันนักพัฒนาซอฟต์แวร์
ติดตั้งเวอร์ชันสำหรับนักพัฒนาซอฟต์แวร์ scikit เรียนรู้พร้อมกับไลบรารีที่จำเป็น

conda install -c anaconda git
pip install Cython
pip install h5py
pip install git+git://github.com/scikit-learn/scikit-learn.git

หมายเหตุ: Windows ผู้ใช้จะต้องติดตั้ง Microsoft ของ Visual C++ 14. คุณสามารถรับได้จาก Good Farm Animal Welfare Awards

ตัวอย่าง Scikit-เรียนรู้ด้วยการเรียนรู้ของเครื่อง

บทช่วยสอน Scikit นี้แบ่งออกเป็นสองส่วน:

  1. การเรียนรู้ของเครื่องด้วย scikit-learn
  2. วิธีเชื่อถือโมเดลของคุณด้วย LIME

ส่วนแรกจะให้รายละเอียดเกี่ยวกับวิธีสร้างไปป์ไลน์ สร้างแบบจำลอง และปรับแต่งไฮเปอร์พารามิเตอร์ ในขณะที่ส่วนที่สองจะให้ข้อมูลที่ทันสมัยในแง่ของการเลือกแบบจำลอง

ขั้นตอนที่ 1) นำเข้าข้อมูล

ในระหว่างการฝึกสอน Scikit นี้ คุณจะใช้ชุดข้อมูลสำหรับผู้ใหญ่

สำหรับความเป็นมาในชุดข้อมูลนี้ โปรดดูที่ หากคุณสนใจที่จะทราบข้อมูลเพิ่มเติมเกี่ยวกับสถิติเชิงพรรณนา โปรดใช้เครื่องมือ Dive และภาพรวม

แนะนำให้เทรดกับเรา บทช่วยสอนนี้ เรียนรู้เพิ่มเติมเกี่ยวกับการดำน้ำและภาพรวม

คุณนำเข้าชุดข้อมูลด้วย Pandas โปรดทราบว่าคุณต้องแปลงประเภทของตัวแปรต่อเนื่องในรูปแบบทศนิยม

ชุดข้อมูลนี้ประกอบด้วยตัวแปรหมวดหมู่ 8 รายการ:

ตัวแปรหมวดหมู่แสดงอยู่ใน CATE_FEATURES

  • ชั้นเรียน
  • การศึกษา
  • สมรส
  • อาชีพ
  • ความสัมพันธ์
  • แข่ง
  • เพศ
  • พื้นเมือง_ประเทศ

นอกจากนี้ ยังมีตัวแปรต่อเนื่องอีก 6 ตัวแปร ได้แก่

ตัวแปรต่อเนื่องแสดงอยู่ใน CONTI_FEATURES

  • อายุ
  • Fnlwgt
  • การศึกษา_num
  • ทุน_กำไร
  • เงินทุน_ขาดทุน
  • ชั่วโมง_สัปดาห์

โปรดทราบว่าเรากรอกรายการด้วยตนเองเพื่อให้คุณมีความคิดที่ดีขึ้นว่าเราใช้คอลัมน์ใด วิธีที่รวดเร็วกว่าในการสร้างรายการแบบหมวดหมู่หรือแบบต่อเนื่องคือการใช้:

## List Categorical
CATE_FEATURES = df_train.iloc[:,:-1].select_dtypes('object').columns
print(CATE_FEATURES)

## List continuous
CONTI_FEATURES =  df_train._get_numeric_data()
print(CONTI_FEATURES)

นี่คือรหัสสำหรับนำเข้าข้อมูล:

# Import dataset
import pandas as pd

## Define path data
COLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital',
           'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss',
           'hours_week', 'native_country', 'label']
### Define continuous list
CONTI_FEATURES  = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week']
### Define categorical list
CATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country']

## Prepare the data
features = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital',
           'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss',
           'hours_week', 'native_country']

PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"

df_train = pd.read_csv(PATH, skipinitialspace=True, names = COLUMNS, index_col=False)
df_train[CONTI_FEATURES] =df_train[CONTI_FEATURES].astype('float64')
df_train.describe()
อายุ Fnlwgt การศึกษา_num ทุน_กำไร เงินทุน_ขาดทุน ชั่วโมง_สัปดาห์
นับ 32561.000000 3.256100e + 04 32561.000000 32561.000000 32561.000000 32561.000000
หมายความ 38.581647 1.897784e + 05 10.080679 1077.648844 87.303830 40.437456
มาตรฐาน 13.640433 1.055500e + 05 2.572720 7385.292085 402.960219 12.347429
นาที 17.000000 1.228500e + 04 1.000000 0.000000 0.000000 1.000000
25% 28.000000 1.178270e + 05 9.000000 0.000000 0.000000 40.000000
50% 37.000000 1.783560e + 05 10.000000 0.000000 0.000000 40.000000
75% 48.000000 2.370510e + 05 12.000000 0.000000 0.000000 45.000000
แม็กซ์ 90.000000 1.484705e + 06 16.000000 99999.000000 4356.000000 99.000000

คุณสามารถตรวจสอบจำนวนค่าที่ไม่ซ้ำกันของฟีเจอร์ของ Native_country ได้ จะเห็นว่ามีเพียงครัวเรือนเดียวที่มาจากฮอลแลนด์-เนเธอร์แลนด์ ครอบครัวนี้จะไม่ให้ข้อมูลใดๆ แก่เรา แต่จะเกิดข้อผิดพลาดระหว่างการฝึกอบรม

df_train.native_country.value_counts()
United-States                 29170
Mexico                          643
?                               583
Philippines                     198
Germany                         137
Canada                          121
Puerto-Rico                     114
El-Salvador                     106
India                           100
Cuba                             95
England                          90
Jamaica                          81
South                            80
China                            75
Italy                            73
Dominican-Republic               70
Vietnam                          67
Guatemala                        64
Japan                            62
Poland                           60
Columbia                         59
Taiwan                           51
Haiti                            44
Iran                             43
Portugal                         37
Nicaragua                        34
Peru                             31
France                           29
Greece                           29
Ecuador                          28
Ireland                          24
Hong                             20
Cambodia                         19
Trinadad&Tobago                  19
Thailand                         18
Laos                             18
Yugoslavia                       16
Outlying-US(Guam-USVI-etc)       14
Honduras                         13
Hungary                          13
Scotland                         12
Holand-Netherlands                1
Name: native_country, dtype: int64

คุณสามารถแยกแถวที่ไม่ให้ข้อมูลนี้ออกจากชุดข้อมูลได้

## Drop Netherland, because only one row
df_train = df_train[df_train.native_country != "Holand-Netherlands"]

ถัดไป คุณจะจัดเก็บตำแหน่งของคุณลักษณะต่อเนื่องในรายการ คุณจะต้องใช้มันในขั้นตอนถัดไปเพื่อสร้างไปป์ไลน์

โค้ดด้านล่างนี้จะวนซ้ำชื่อคอลัมน์ทั้งหมดใน CONTI_FEATURES และรับตำแหน่ง (เช่น หมายเลข) จากนั้นจึงผนวกเข้ากับรายการที่เรียกว่า conti_features

## Get the column index of the categorical features
conti_features = []
for i in CONTI_FEATURES:
    position = df_train.columns.get_loc(i)
    conti_features.append(position)
print(conti_features)  
[0, 2, 10, 4, 11, 12]

โค้ดด้านล่างนี้ทำงานเหมือนกับข้างบนแต่สำหรับตัวแปรหมวดหมู่ โค้ดด้านล่างจะทำซ้ำสิ่งที่คุณทำก่อนหน้านี้ ยกเว้นคุณลักษณะที่เป็นหมวดหมู่

## Get the column index of the categorical features
categorical_features = []
for i in CATE_FEATURES:
    position = df_train.columns.get_loc(i)
    categorical_features.append(position)
print(categorical_features)  
[1, 3, 5, 6, 7, 8, 9, 13]

คุณสามารถดูชุดข้อมูลได้ โปรดทราบว่าคุณลักษณะแต่ละหมวดหมู่จะเป็นสตริง คุณไม่สามารถป้อนโมเดลด้วยค่าสตริงได้ คุณต้องแปลงชุดข้อมูลโดยใช้ตัวแปรจำลอง

df_train.head(5)

ที่จริงแล้ว คุณต้องสร้างหนึ่งคอลัมน์สำหรับแต่ละกลุ่มในฟีเจอร์นี้ ขั้นแรก คุณสามารถเรียกใช้โค้ดด้านล่างเพื่อคำนวณจำนวนคอลัมน์ทั้งหมดที่ต้องการ

print(df_train[CATE_FEATURES].nunique(),
      'There are',sum(df_train[CATE_FEATURES].nunique()), 'groups in the whole dataset')
workclass          9
education         16
marital            7
occupation        15
relationship       6
race               5
sex                2
native_country    41
dtype: int64 There are 101 groups in the whole dataset

ชุดข้อมูลทั้งหมดประกอบด้วยกลุ่ม 101 กลุ่มดังที่แสดงไว้ด้านบน ตัวอย่างเช่น คุณสมบัติของ workclass มีกลุ่ม XNUMX กลุ่ม คุณสามารถดูชื่อของกลุ่มด้วยโค้ดต่อไปนี้

Unique() ส่งคืนค่าที่ไม่ซ้ำของคุณสมบัติตามหมวดหมู่

for i in CATE_FEATURES:
    print(df_train[i].unique())
['State-gov' 'Self-emp-not-inc' 'Private' 'Federal-gov' 'Local-gov' '?'
 'Self-emp-inc' 'Without-pay' 'Never-worked']
['Bachelors' 'HS-grad' '11th' 'Masters' '9th' 'Some-college' 'Assoc-acdm'
 'Assoc-voc' '7th-8th' 'Doctorate' 'Prof-school' '5th-6th' '10th'
 '1st-4th' 'Preschool' '12th']
['Never-married' 'Married-civ-spouse' 'Divorced' 'Married-spouse-absent'
 'Separated' 'Married-AF-spouse' 'Widowed']
['Adm-clerical' 'Exec-managerial' 'Handlers-cleaners' 'Prof-specialty'
 'Other-service' 'Sales' 'Craft-repair' 'Transport-moving'
 'Farming-fishing' 'Machine-op-inspct' 'Tech-support' '?'
 'Protective-serv' 'Armed-Forces' 'Priv-house-serv']
['Not-in-family' 'Husband' 'Wife' 'Own-child' 'Unmarried' 'Other-relative']
['White' 'Black' 'Asian-Pac-Islander' 'Amer-Indian-Eskimo' 'Other']
['Male' 'Female']
['United-States' 'Cuba' 'Jamaica' 'India' '?' 'Mexico' 'South'
 'Puerto-Rico' 'Honduras' 'England' 'Canada' 'Germany' 'Iran'
 'Philippines' 'Italy' 'Poland' 'Columbia' 'Cambodia' 'Thailand' 'Ecuador'
 'Laos' 'Taiwan' 'Haiti' 'Portugal' 'Dominican-Republic' 'El-Salvador'
 'France' 'Guatemala' 'China' 'Japan' 'Yugoslavia' 'Peru'
 'Outlying-US(Guam-USVI-etc)' 'Scotland' 'Trinadad&Tobago' 'Greece'
 'Nicaragua' 'Vietnam' 'Hong' 'Ireland' 'Hungary']

ดังนั้นชุดข้อมูลการฝึกจะมี 101 + 7 คอลัมน์ เจ็ดคอลัมน์สุดท้ายเป็นคุณลักษณะต่อเนื่อง

Scikit-learn สามารถดูแลการแปลงได้ ทำได้สองขั้นตอน:

  • ขั้นแรก คุณต้องแปลงสตริงเป็น ID ตัวอย่างเช่น รัฐ-gov จะมี ID 1, Self-emp-not-inc ID 2 และอื่นๆ ฟังก์ชัน LabelEncoder ทำสิ่งนี้เพื่อคุณ
  • ย้าย ID แต่ละรายการไปยังคอลัมน์ใหม่ ดังที่กล่าวไว้ก่อนหน้านี้ ชุดข้อมูลมี ID ของกลุ่ม 101 กลุ่ม ดังนั้นจะมี 101 คอลัมน์ที่รวบรวมกลุ่มคุณลักษณะตามหมวดหมู่ทั้งหมด Scikit-learn มีฟังก์ชันที่เรียกว่า OneHotEncoder ซึ่งดำเนินการนี้

ขั้นตอนที่ 2) สร้างชุดฝึก/ชุดทดสอบ

เมื่อชุดข้อมูลพร้อมแล้ว เราก็สามารถแบ่งได้ 80/20

80 เปอร์เซ็นต์สำหรับชุดฝึกอบรมและ 20 เปอร์เซ็นต์สำหรับชุดทดสอบ

คุณสามารถใช้ train_test_split อาร์กิวเมนต์แรกคือ dataframe คือคุณสมบัติและอาร์กิวเมนต์ที่สองคือ dataframe ป้ายกำกับ คุณสามารถระบุขนาดของชุดทดสอบด้วย test_size

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df_train[features],
                                                    df_train.label,
                                                    test_size = 0.2,
                                                    random_state=0)
X_train.head(5)
print(X_train.shape, X_test.shape)
(26048, 14) (6512, 14)

ขั้นตอนที่ 3) สร้างไปป์ไลน์

ไปป์ไลน์ช่วยให้ป้อนโมเดลด้วยข้อมูลที่สอดคล้องกันได้ง่ายขึ้น

แนวคิดเบื้องหลังคือการใส่ข้อมูลดิบไว้ใน 'ท่อ' เพื่อดำเนินการต่างๆ

ตัวอย่างเช่น ด้วยชุดข้อมูลปัจจุบัน คุณต้องทำให้ตัวแปรต่อเนื่องเป็นมาตรฐานและแปลงข้อมูลแบบหมวดหมู่ โปรดทราบว่าคุณสามารถดำเนินการใดๆ ภายในไปป์ไลน์ได้ ตัวอย่างเช่น หากคุณมี "NA" ในชุดข้อมูล คุณสามารถแทนที่ค่าเหล่านั้นด้วยค่าเฉลี่ยหรือค่ามัธยฐานได้ นอกจากนี้ คุณยังสามารถสร้างตัวแปรใหม่ได้อีกด้วย

คุณมีทางเลือก ฮาร์ดโค้ดทั้งสองกระบวนการหรือสร้างไปป์ไลน์ ตัวเลือกแรกอาจนำไปสู่การรั่วไหลของข้อมูลและสร้างความไม่สอดคล้องกันเมื่อเวลาผ่านไป ตัวเลือกที่ดีกว่าคือการใช้ไปป์ไลน์

from sklearn.preprocessing import StandardScaler, OneHotEncoder, LabelEncoder
from sklearn.compose import ColumnTransformer, make_column_transformer
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LogisticRegression

ไปป์ไลน์จะดำเนินการสองอย่างก่อนที่จะป้อนตัวจำแนกโลจิสติกส์:

  1. สร้างมาตรฐานให้กับตัวแปร: `StandardScaler()“
  2. แปลงคุณลักษณะตามหมวดหมู่: OneHotEncoder(sparse=False)

คุณสามารถดำเนินการสองขั้นตอนได้โดยใช้ make_column_transformer ฟังก์ชั่นนี้ไม่สามารถใช้งานได้ใน scikit-learn เวอร์ชันปัจจุบัน (0.19) เวอร์ชันปัจจุบันไม่สามารถดำเนินการตัวเข้ารหัสฉลากและตัวเข้ารหัสแบบร้อนหนึ่งตัวในไปป์ไลน์ได้ นี่เป็นเหตุผลหนึ่งที่เราตัดสินใจใช้เวอร์ชันสำหรับนักพัฒนาซอฟต์แวร์

make_column_transformer ใช้งานง่าย คุณต้องกำหนดว่าจะใช้การแปลงคอลัมน์ใดและจะดำเนินการแปลงใด ตัวอย่างเช่น หากต้องการทำให้ฟีเจอร์ต่อเนื่องเป็นมาตรฐาน คุณสามารถทำได้ดังนี้:

  • conti_features, StandardScaler() ภายใน make_column_transformer
    • conti_features: รายการที่มีตัวแปรต่อเนื่อง
    • StandardScaler: สร้างมาตรฐานให้กับตัวแปร

วัตถุ OneHotEncoder ภายใน make_column_transformer จะเข้ารหัสป้ายกำกับโดยอัตโนมัติ

preprocess = make_column_transformer(
    (conti_features, StandardScaler()),
    ### Need to be numeric not string to specify columns name 
    (categorical_features, OneHotEncoder(sparse=False))
)

คุณสามารถทดสอบว่าไปป์ไลน์ทำงานได้หรือไม่ด้วย fit_transform ชุดข้อมูลควรมีรูปร่างดังต่อไปนี้: 26048, 107

preprocess.fit_transform(X_train).shape
(26048, 107)

หม้อแปลงข้อมูลพร้อมใช้งานแล้ว คุณสามารถสร้างไปป์ไลน์ด้วย make_pipeline เมื่อข้อมูลถูกแปลงแล้ว คุณสามารถป้อนข้อมูลการถดถอยโลจิสติกได้

model = make_pipeline(
    preprocess,
    LogisticRegression())

การฝึกโมเดลด้วย scikit-learn เป็นเรื่องเล็กน้อย คุณต้องใช้วัตถุที่พอดีซึ่งอยู่หน้าไปป์ไลน์ เช่น โมเดล คุณสามารถพิมพ์ความแม่นยำด้วยวัตถุคะแนนจากห้องสมุด scikit-learn

model.fit(X_train, y_train)
print("logistic regression score: %f" % model.score(X_test, y_test))
logistic regression score: 0.850891

สุดท้าย คุณสามารถทำนายคลาสด้วย Predict_proba มันจะคืนค่าความน่าจะเป็นสำหรับแต่ละคลาส โปรดทราบว่ามันรวมเป็นหนึ่ง

model.predict_proba(X_test)
array([[0.83576663, 0.16423337],
       [0.94582765, 0.05417235],
       [0.64760587, 0.35239413],
       ...,
       [0.99639252, 0.00360748],
       [0.02072181, 0.97927819],
       [0.56781353, 0.43218647]])

ขั้นตอนที่ 4) การใช้ไปป์ไลน์ของเราในการค้นหากริด

การปรับแต่งไฮเปอร์พารามิเตอร์ (ตัวแปรที่กำหนดโครงสร้างเครือข่าย เช่น หน่วยที่ซ่อนอยู่) อาจเป็นเรื่องที่น่าเบื่อและน่าเบื่อหน่าย

วิธีหนึ่งในการประเมินแบบจำลองคือการเปลี่ยนขนาดของชุดการฝึกและประเมินประสิทธิภาพ

คุณสามารถทำซ้ำวิธีนี้ได้สิบครั้งเพื่อดูเกณฑ์ชี้วัดคะแนน อย่างไรก็ตาม มันเป็นงานที่มากเกินไป

แต่ scikit-learn มีฟังก์ชันสำหรับดำเนินการปรับพารามิเตอร์และการตรวจสอบความถูกต้องข้ามแทน

การตรวจสอบข้าม

การตรวจสอบข้ามหมายถึงในระหว่างการฝึก ชุดการฝึกจะสลิปจำนวนครั้งเป็นพับ จากนั้นประเมินโมเดลและเวลา ตัวอย่างเช่น หากตั้งค่า cv เป็น 10 ชุดการฝึกจะได้รับการฝึกและประเมินผลสิบครั้ง ในแต่ละรอบ ตัวแยกประเภทจะสุ่มพับเก้าพับเพื่อฝึกแบบจำลอง และพับที่ 10 มีไว้เพื่อการประเมิน

ค้นหากริด

ตัวแยกประเภทแต่ละตัวมีไฮเปอร์พารามิเตอร์ที่ต้องปรับแต่ง คุณสามารถลองใช้ค่าอื่นหรือตั้งค่าตารางพารามิเตอร์ก็ได้ หากคุณไปที่เว็บไซต์อย่างเป็นทางการของ scikit-learn คุณจะเห็นตัวแยกประเภทลอจิสติกมีพารามิเตอร์ที่แตกต่างกันในการปรับแต่ง เพื่อให้การฝึกเร็วขึ้น คุณเลือกที่จะปรับพารามิเตอร์ C ควบคุมพารามิเตอร์การทำให้เป็นมาตรฐาน มันควรจะเป็นบวก ค่าเล็กน้อยจะให้น้ำหนักแก่ตัวทำให้สม่ำเสมอมากขึ้น

คุณสามารถใช้วัตถุ GridSearchCV คุณต้องสร้างพจนานุกรมที่มีไฮเปอร์พารามิเตอร์เพื่อปรับแต่ง

คุณแสดงรายการไฮเปอร์พารามิเตอร์ตามด้วยค่าที่คุณต้องการลอง ตัวอย่างเช่น หากต้องการปรับแต่งพารามิเตอร์ C คุณใช้:

  • 'logisticregression__C': [0.1, 1.0, 1.0]: พารามิเตอร์นำหน้าด้วยชื่อของตัวแยกประเภทและขีดล่างสองตัว ในกรณีตัวพิมพ์เล็ก

โมเดลจะลองใช้ค่าที่แตกต่างกันสี่ค่า: 0.001, 0.01, 0.1 และ 1

คุณฝึกโมเดลโดยใช้ 10 เท่า: cv=10

from sklearn.model_selection import GridSearchCV
# Construct the parameter grid
param_grid = {
    'logisticregression__C': [0.001, 0.01,0.1, 1.0],
    }

คุณสามารถฝึกโมเดลโดยใช้ GridSearchCV ด้วยพารามิเตอร์ gri และ cv

# Train the model
grid_clf = GridSearchCV(model,
                        param_grid,
                        cv=10,
                        iid=False)
grid_clf.fit(X_train, y_train)

เอาท์พุท

GridSearchCV(cv=10, error_score='raise-deprecating',
       estimator=Pipeline(memory=None,
     steps=[('columntransformer', ColumnTransformer(n_jobs=1, remainder='drop', transformer_weights=None,
         transformers=[('standardscaler', StandardScaler(copy=True, with_mean=True, with_std=True), [0, 2, 10, 4, 11, 12]), ('onehotencoder', OneHotEncoder(categorical_features=None, categories=None,...ty='l2', random_state=None, solver='liblinear', tol=0.0001,
          verbose=0, warm_start=False))]),
       fit_params=None, iid=False, n_jobs=1,
       param_grid={'logisticregression__C': [0.001, 0.01, 0.1, 1.0]},
       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',
       scoring=None, verbose=0)

หากต้องการเข้าถึงพารามิเตอร์ที่ดีที่สุด คุณใช้ best_params_

grid_clf.best_params_

เอาท์พุท

{'logisticregression__C': 1.0}

หลังจากฝึกโมเดลด้วยค่าการทำให้เป็นมาตรฐานที่แตกต่างกันสี่ค่าแล้ว พารามิเตอร์ที่เหมาะสมที่สุดก็คือ

print("best logistic regression from grid search: %f" % grid_clf.best_estimator_.score(X_test, y_test))

การถดถอยโลจิสติกที่ดีที่สุดจากการค้นหากริด: 0.850891

วิธีเข้าถึงความน่าจะเป็นที่คาดการณ์ไว้:

grid_clf.best_estimator_.predict_proba(X_test)
array([[0.83576677, 0.16423323],
       [0.9458291 , 0.0541709 ],
       [0.64760416, 0.35239584],
       ...,
       [0.99639224, 0.00360776],
       [0.02072033, 0.97927967],
       [0.56782222, 0.43217778]])

โมเดล XGBoost พร้อม scikit-learn

เรามาลองใช้ตัวอย่าง Scikit-learn เพื่อฝึกหนึ่งในตัวแยกประเภทที่ดีที่สุดในตลาด XGBoost เป็นการปรับปรุงเหนือฟอเรสต์แบบสุ่ม พื้นหลังทางทฤษฎีของลักษณนามอยู่นอกขอบเขตนี้ Python กวดวิชา Scikit โปรดทราบว่า XGBoost ชนะการแข่งขัน kaggle มากมาย ด้วยขนาดชุดข้อมูลโดยเฉลี่ย จึงสามารถทำงานได้ดีพอๆ กับอัลกอริธึมการเรียนรู้เชิงลึกหรือดียิ่งขึ้นไปอีก

ตัวแยกประเภทเป็นสิ่งที่ท้าทายในการฝึกเนื่องจากมีพารามิเตอร์ที่ต้องปรับแต่งเป็นจำนวนมาก แน่นอนคุณสามารถใช้ GridSearchCV เพื่อเลือกพารามิเตอร์สำหรับคุณได้

เรามาดูวิธีใช้วิธีที่ดีกว่าในการค้นหาพารามิเตอร์ที่เหมาะสมที่สุดกันดีกว่า GridSearchCV อาจเป็นเรื่องที่น่าเบื่อและใช้เวลานานมากหากคุณผ่านค่าหลายค่า พื้นที่การค้นหาจะขยายตามจำนวนพารามิเตอร์ วิธีแก้ปัญหาที่ดีกว่าคือใช้ RandomizedSearchCV วิธีนี้ประกอบด้วยการเลือกค่าของไฮเปอร์พารามิเตอร์แต่ละตัวหลังจากการวนซ้ำแต่ละครั้งแบบสุ่ม ตัวอย่างเช่น หากตัวแยกประเภทได้รับการฝึกมากกว่า 1000 รอบ จะมีการประเมินชุดค่าผสม 1000 ชุด มันใช้งานได้มากหรือน้อยเหมือนกัน GridSearchCV

คุณต้องนำเข้า xgboost หากไม่ได้ติดตั้งไลบรารี่ โปรดใช้ pip3 ติดตั้ง xgboost หรือ

use import sys
!{sys.executable} -m pip install xgboost

In Jupyter สิ่งแวดล้อม

ถัดไป

import xgboost
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import StratifiedKFold

ก้าวต่อไปใน Scikit นี้ Python กวดวิชารวมถึงการระบุพารามิเตอร์ที่จะปรับแต่ง คุณสามารถดูเอกสารประกอบอย่างเป็นทางการเพื่อดูพารามิเตอร์ทั้งหมดที่ต้องปรับแต่ง เพื่อประโยชน์ของการ Python บทช่วยสอน Sklearn คุณเลือกไฮเปอร์พารามิเตอร์เพียงสองตัวโดยแต่ละค่ามีสองค่า XGBoost ใช้เวลามากในการฝึกฝน ยิ่งมีไฮเปอร์พารามิเตอร์ในตารางมากเท่าไร คุณก็ยิ่งต้องรอนานขึ้นเท่านั้น

params = {
        'xgbclassifier__gamma': [0.5, 1],
        'xgbclassifier__max_depth': [3, 4]
        }

คุณสร้างไปป์ไลน์ใหม่โดยใช้ตัวจำแนก XGBoost คุณเลือกที่จะกำหนดค่าประมาณค่า 600 ตัว โปรดทราบว่า n_estimators เป็นพารามิเตอร์ที่คุณปรับแต่งได้ ค่าที่สูงอาจทำให้เกิดการโอเวอร์ฟิตติ้ง คุณสามารถลองใช้ค่าต่างๆ ด้วยตัวเองได้ แต่โปรดทราบว่าอาจใช้เวลาหลายชั่วโมง คุณใช้ค่าเริ่มต้นสำหรับพารามิเตอร์อื่นๆ

model_xgb = make_pipeline(
    preprocess,
    xgboost.XGBClassifier(
                          n_estimators=600,
                          objective='binary:logistic',
                          silent=True,
                          nthread=1)
)

คุณสามารถปรับปรุงการตรวจสอบความถูกต้องข้ามได้ด้วยเครื่องมือตรวจสอบข้าม Stratified K-Folds คุณสร้างเพียงสามเท่าเพื่อให้การคำนวณเร็วขึ้นแต่ลดคุณภาพลง เพิ่มค่านี้เป็น 5 หรือ 10 ที่บ้านเพื่อปรับปรุงผลลัพธ์

คุณเลือกที่จะฝึกโมเดลผ่านการวนซ้ำสี่ครั้ง

skf = StratifiedKFold(n_splits=3,
                      shuffle = True,
                      random_state = 1001)

random_search = RandomizedSearchCV(model_xgb,
                                   param_distributions=params,
                                   n_iter=4,
                                   scoring='accuracy',
                                   n_jobs=4,
                                   cv=skf.split(X_train, y_train),
                                   verbose=3,
                                   random_state=1001)

การค้นหาแบบสุ่มพร้อมใช้งานแล้ว คุณสามารถฝึกโมเดลได้

#grid_xgb = GridSearchCV(model_xgb, params, cv=10, iid=False)
random_search.fit(X_train, y_train)
Fitting 3 folds for each of 4 candidates, totalling 12 fits
[CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5 ............
[CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5 ............
[CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5 ............
[CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5 ............
[CV]  xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5, score=0.8759645283888057, total= 1.0min
[CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5 ............
[CV]  xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5, score=0.8729701715996775, total= 1.0min
[CV]  xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5, score=0.8706519235199263, total= 1.0min
[CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5 ............
[CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=1 ..............
[CV]  xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5, score=0.8735460094437406, total= 1.3min
[CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=1 ..............
[CV]  xgbclassifier__max_depth=3, xgbclassifier__gamma=1, score=0.8722791661868018, total=  57.7s
[CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=1 ..............
[CV]  xgbclassifier__max_depth=3, xgbclassifier__gamma=1, score=0.8753886905447426, total= 1.0min
[CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=1 ..............
[CV]  xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5, score=0.8697304768486523, total= 1.3min
[CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=1 ..............
[CV]  xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5, score=0.8740066797189912, total= 1.4min
[CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=1 ..............
[CV]  xgbclassifier__max_depth=3, xgbclassifier__gamma=1, score=0.8707671043538355, total= 1.0min
[CV]  xgbclassifier__max_depth=4, xgbclassifier__gamma=1, score=0.8729701715996775, total= 1.2min
[Parallel(n_jobs=4)]: Done  10 out of  12 | elapsed:  3.6min remaining:   43.5s
[CV]  xgbclassifier__max_depth=4, xgbclassifier__gamma=1, score=0.8736611770125533, total= 1.2min
[CV]  xgbclassifier__max_depth=4, xgbclassifier__gamma=1, score=0.8692697535130154, total= 1.2min
[Parallel(n_jobs=4)]: Done  12 out of  12 | elapsed:  3.6min finished
/Users/Thomas/anaconda3/envs/hello-tf/lib/python3.6/site-packages/sklearn/model_selection/_search.py:737: DeprecationWarning: The default of the `iid` parameter will change from True to False in version 0.22 and will be removed in 0.24. This will change numeric results when test-set sizes are unequal. DeprecationWarning)
RandomizedSearchCV(cv=<generator object _BaseKFold.split at 0x1101eb830>,
          error_score='raise-deprecating',
          estimator=Pipeline(memory=None,
     steps=[('columntransformer', ColumnTransformer(n_jobs=1, remainder='drop', transformer_weights=None,
         transformers=[('standardscaler', StandardScaler(copy=True, with_mean=True, with_std=True), [0, 2, 10, 4, 11, 12]), ('onehotencoder', OneHotEncoder(categorical_features=None, categories=None,...
       reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None,
       silent=True, subsample=1))]),
          fit_params=None, iid='warn', n_iter=4, n_jobs=4,
          param_distributions={'xgbclassifier__gamma': [0.5, 1], 'xgbclassifier__max_depth': [3, 4]},
          pre_dispatch='2*n_jobs', random_state=1001, refit=True,
          return_train_score='warn', scoring='accuracy', verbose=3)

อย่างที่คุณเห็น XGBoost มีคะแนนดีกว่าการถดถอยลอจิซิตก่อนหน้า

print("Best parameter", random_search.best_params_)
print("best logistic regression from grid search: %f" % random_search.best_estimator_.score(X_test, y_test))
Best parameter {'xgbclassifier__max_depth': 3, 'xgbclassifier__gamma': 0.5}
best logistic regression from grid search: 0.873157
random_search.best_estimator_.predict(X_test)
array(['<=50K', '<=50K', '<=50K', ..., '<=50K', '>50K', '<=50K'],      dtype=object)

สร้าง DNN ด้วย MLPClassifier ใน scikit-learn

สุดท้ายนี้ คุณสามารถฝึกฝนอัลกอริธึมการเรียนรู้เชิงลึกด้วย scikit-learn ได้ วิธีการนี้เหมือนกับตัวแยกประเภทอื่น ตัวแยกประเภทมีอยู่ที่ MLPClassifier

from sklearn.neural_network import MLPClassifier

คุณกำหนดอัลกอริทึมการเรียนรู้เชิงลึกดังต่อไปนี้:

  • อดัม นักแก้ปัญหา
  • ฟังก์ชั่นการเปิดใช้งาน Relu
  • อัลฟ่า = 0.0001
  • ขนาดชุด 150
  • สองชั้นที่ซ่อนอยู่ซึ่งมีเซลล์ประสาท 100 และ 50 เซลล์ตามลำดับ
model_dnn = make_pipeline(
    preprocess,
    MLPClassifier(solver='adam',
                  alpha=0.0001,
                  activation='relu',
                    batch_size=150,
                    hidden_layer_sizes=(200, 100),
                    random_state=1))

คุณสามารถเปลี่ยนจำนวนเลเยอร์เพื่อปรับปรุงโมเดลได้

model_dnn.fit(X_train, y_train)
  print("DNN regression score: %f" % model_dnn.score(X_test, y_test))

คะแนนการถดถอย DNN: 0.821253

LIME: เชื่อถือโมเดลของคุณ

ตอนนี้คุณมีโมเดลที่ดีแล้ว คุณต้องมีเครื่องมือที่จะเชื่อถือโมเดลนั้นได้ การเรียนรู้เครื่อง อัลกอริทึม โดยเฉพาะแรนดอมฟอเรสต์และเครือข่ายประสาทเทียม เป็นที่ทราบกันว่าเป็นอัลกอริทึมกล่องดำ พูดอีกอย่างก็คือ มันใช้งานได้ แต่ไม่มีใครรู้ว่าทำไม

นักวิจัยสามคนได้คิดค้นเครื่องมือที่ยอดเยี่ยมเพื่อดูว่าคอมพิวเตอร์ทำนายได้อย่างไร บทความนี้มีชื่อว่า Why should I Trust You?

พวกเขาพัฒนาอัลกอริธึมชื่อ คำอธิบายผู้ไม่เชื่อเรื่องพระเจ้าแบบจำลองที่ตีความได้ในท้องถิ่น (LIME).

ยกตัวอย่าง:

บางครั้งคุณไม่รู้ว่าคุณสามารถเชื่อถือการทำนายของแมชชีนเลิร์นนิงได้หรือไม่:

ตัวอย่างเช่น แพทย์ไม่สามารถเชื่อถือการวินิจฉัยเพียงเพราะคอมพิวเตอร์พูดเช่นนั้น คุณต้องรู้ด้วยว่าคุณสามารถเชื่อถือโมเดลได้หรือไม่ก่อนที่จะนำไปใช้จริง

ลองนึกภาพว่าเราสามารถเข้าใจได้ว่าทำไมตัวแยกประเภทจึงทำการทำนายแม้กระทั่งโมเดลที่ซับซ้อนอย่างเหลือเชื่อ เช่น โครงข่ายประสาทเทียม ฟอเรสต์แบบสุ่ม หรือ svms ด้วยเคอร์เนลใดๆ

จะเข้าถึงได้ง่ายขึ้นเพื่อเชื่อถือคำทำนายหากเราเข้าใจเหตุผลเบื้องหลังคำทำนายนั้นได้ จากตัวอย่างกับแพทย์ หากแบบจำลองบอกเขาว่าอาการใดที่สำคัญที่คุณจะเชื่อถือได้ ก็จะง่ายกว่าที่จะพิจารณาว่าคุณไม่ควรเชื่อถือแบบจำลองนั้นหรือไม่

Lime สามารถบอกคุณได้ว่าฟีเจอร์ใดที่ส่งผลต่อการตัดสินใจของลักษณนาม

การเตรียมข้อมูล

มีสองสิ่งที่คุณต้องเปลี่ยนเพื่อรัน LIME หลาม- ก่อนอื่นคุณต้องติดตั้ง lime ในเทอร์มินัล คุณสามารถใช้ pip install lime ได้

Lime ใช้วัตถุ LimeTabularExplainer เพื่อประมาณโมเดลในเครื่อง วัตถุนี้ต้องการ:

  • ชุดข้อมูลในรูปแบบตัวเลข
  • ชื่อของคุณสมบัติ: Feature_names
  • ชื่อของคลาส: class_names
  • ดัชนีของคอลัมน์คุณลักษณะตามหมวดหมู่: categorical_features
  • ชื่อกลุ่มสำหรับคุณลักษณะแต่ละหมวดหมู่: categorical_names

สร้างชุดรถไฟจำนวนมาก

คุณสามารถคัดลอกและแปลง df_train จาก pandas เป็น มึน ง่ายมาก

df_train.head(5)
# Create numpy data
df_lime = df_train
df_lime.head(3)

รับชื่อชั้นเรียน ป้ายกำกับสามารถเข้าถึงได้ด้วยวัตถุเฉพาะ () คุณควรเห็น:

  • '<=50K'
  • '>50K'
# Get the class name
class_names = df_lime.label.unique()
class_names
array(['<=50K', '>50K'], dtype=object)

ดัชนีของคอลัมน์คุณลักษณะหมวดหมู่

คุณสามารถใช้เมธอดที่คุณเคยศึกษาไว้ก่อนหน้านี้เพื่อรับชื่อของกลุ่มได้ คุณเข้ารหัสป้ายกำกับด้วย LabelEncoder คุณทำซ้ำการดำเนินการกับฟีเจอร์เชิงหมวดหมู่ทั้งหมด

## 
import sklearn.preprocessing as preprocessing
categorical_names = {}
for feature in CATE_FEATURES:
    le = preprocessing.LabelEncoder()
    le.fit(df_lime[feature])
    df_lime[feature] = le.transform(df_lime[feature])
    categorical_names[feature] = le.classes_
print(categorical_names)    
{'workclass': array(['?', 'Federal-gov', 'Local-gov', 'Never-worked', 'Private',
       'Self-emp-inc', 'Self-emp-not-inc', 'State-gov', 'Without-pay'],
      dtype=object), 'education': array(['10th', '11th', '12th', '1st-4th', '5th-6th', '7th-8th', '9th',
       'Assoc-acdm', 'Assoc-voc', 'Bachelors', 'Doctorate', 'HS-grad',
       'Masters', 'Preschool', 'Prof-school', 'Some-college'],
      dtype=object), 'marital': array(['Divorced', 'Married-AF-spouse', 'Married-civ-spouse',
       'Married-spouse-absent', 'Never-married', 'Separated', 'Widowed'],
      dtype=object), 'occupation': array(['?', 'Adm-clerical', 'Armed-Forces', 'Craft-repair',
       'Exec-managerial', 'Farming-fishing', 'Handlers-cleaners',
       'Machine-op-inspct', 'Other-service', 'Priv-house-serv',
       'Prof-specialty', 'Protective-serv', 'Sales', 'Tech-support',
       'Transport-moving'], dtype=object), 'relationship': array(['Husband', 'Not-in-family', 'Other-relative', 'Own-child',
       'Unmarried', 'Wife'], dtype=object), 'race': array(['Amer-Indian-Eskimo', 'Asian-Pac-Islander', 'Black', 'Other',
       'White'], dtype=object), 'sex': array(['Female', 'Male'], dtype=object), 'native_country': array(['?', 'Cambodia', 'Canada', 'China', 'Columbia', 'Cuba',
       'Dominican-Republic', 'Ecuador', 'El-Salvador', 'England',
       'France', 'Germany', 'Greece', 'Guatemala', 'Haiti', 'Honduras',
       'Hong', 'Hungary', 'India', 'Iran', 'Ireland', 'Italy', 'Jamaica',
       'Japan', 'Laos', 'Mexico', 'Nicaragua',
       'Outlying-US(Guam-USVI-etc)', 'Peru', 'Philippines', 'Poland',
       'Portugal', 'Puerto-Rico', 'Scotland', 'South', 'Taiwan',
       'Thailand', 'Trinadad&Tobago', 'United-States', 'Vietnam',
       'Yugoslavia'], dtype=object)}

df_lime.dtypes
age               float64
workclass           int64
fnlwgt            float64
education           int64
education_num     float64
marital             int64
occupation          int64
relationship        int64
race                int64
sex                 int64
capital_gain      float64
capital_loss      float64
hours_week        float64
native_country      int64
label              object
dtype: object

เมื่อชุดข้อมูลพร้อมแล้ว คุณสามารถสร้างชุดข้อมูลต่างๆ ได้ตามที่แสดงในตัวอย่างการเรียนรู้ Scikit ด้านล่าง คุณแปลงข้อมูลภายนอกไปป์ไลน์จริง ๆ แล้วเพื่อหลีกเลี่ยงข้อผิดพลาดกับ LIME ชุดการฝึกใน LimeTabularExplainer ควรเป็นอาร์เรย์ที่ไม่มีสตริง ด้วยวิธีการข้างต้น คุณจะแปลงชุดข้อมูลการฝึกอบรมแล้ว

from sklearn.model_selection import train_test_split
X_train_lime, X_test_lime, y_train_lime, y_test_lime = train_test_split(df_lime[features],
                                                    df_lime.label,
                                                    test_size = 0.2,
                                                    random_state=0)
X_train_lime.head(5)

คุณสามารถสร้างไปป์ไลน์ด้วยพารามิเตอร์ที่เหมาะสมที่สุดจาก XGBoost

model_xgb = make_pipeline(
    preprocess,
    xgboost.XGBClassifier(max_depth = 3,
                          gamma = 0.5,
                          n_estimators=600,
                          objective='binary:logistic',
                          silent=True,
                          nthread=1))

model_xgb.fit(X_train_lime, y_train_lime)
/Users/Thomas/anaconda3/envs/hello-tf/lib/python3.6/site-packages/sklearn/preprocessing/_encoders.py:351: FutureWarning: The handling of integer data will change in version 0.22. Currently, the categories are determined based on the range [0, max(values)], while in the future they will be determined based on the unique values.
If you want the future behavior and silence this warning, you can specify "categories='auto'."In case you used a LabelEncoder before this OneHotEncoder to convert the categories to integers, then you can now use the OneHotEncoder directly.
  warnings.warn(msg, FutureWarning)
Pipeline(memory=None,
     steps=[('columntransformer', ColumnTransformer(n_jobs=1, remainder='drop', transformer_weights=None,
         transformers=[('standardscaler', StandardScaler(copy=True, with_mean=True, with_std=True), [0, 2, 10, 4, 11, 12]), ('onehotencoder', OneHotEncoder(categorical_features=None, categories=None,...
       reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None,
       silent=True, subsample=1))])

คุณจะได้รับคำเตือน คำเตือนดังกล่าวจะอธิบายว่าคุณไม่จำเป็นต้องสร้างตัวเข้ารหัสป้ายกำกับก่อนขั้นตอนการประมวลผล หากคุณไม่ต้องการใช้ LIME คุณสามารถใช้เมธอดจากส่วนแรกของบทช่วยสอน Machine Learning with Scikit-learn ได้ มิฉะนั้น คุณสามารถใช้เมธอดนี้ต่อไปได้ โดยสร้างชุดข้อมูลที่เข้ารหัสก่อน จากนั้นตั้งค่าให้รับตัวเข้ารหัสแบบฮอตภายในขั้นตอนการประมวลผล

print("best logistic regression from grid search: %f" % model_xgb.score(X_test_lime, y_test_lime))
best logistic regression from grid search: 0.873157
model_xgb.predict_proba(X_test_lime)
array([[7.9646105e-01, 2.0353897e-01],
       [9.5173013e-01, 4.8269872e-02],
       [7.9344827e-01, 2.0655173e-01],
       ...,
       [9.9031430e-01, 9.6856682e-03],
       [6.4581633e-04, 9.9935418e-01],
       [9.7104281e-01, 2.8957171e-02]], dtype=float32)

ก่อนที่จะใช้ LIME ในการทำงาน เรามาสร้างอาร์เรย์ numpy ที่มีคุณลักษณะของการจำแนกประเภทที่ไม่ถูกต้องกันก่อน คุณสามารถใช้รายการนั้นในภายหลังเพื่อดูว่าสิ่งใดที่ทำให้การจำแนกประเภทเข้าใจผิด

temp = pd.concat([X_test_lime, y_test_lime], axis= 1)
temp['predicted'] = model_xgb.predict(X_test_lime)
temp['wrong']=  temp['label'] != temp['predicted']
temp = temp.query('wrong==True').drop('wrong', axis=1)
temp= temp.sort_values(by=['label'])
temp.shape

(826, 16)

คุณสร้างฟังก์ชันแลมบ์ดาเพื่อดึงข้อมูลการคาดการณ์จากโมเดลด้วยข้อมูลใหม่ คุณจะต้องการมันในไม่ช้า

predict_fn = lambda x: model_xgb.predict_proba(x).astype(float)
X_test_lime.dtypes
age               float64
workclass           int64
fnlwgt            float64
education           int64
education_num     float64
marital             int64
occupation          int64
relationship        int64
race                int64
sex                 int64
capital_gain      float64
capital_loss      float64
hours_week        float64
native_country      int64
dtype: object
predict_fn(X_test_lime)
array([[7.96461046e-01, 2.03538969e-01],
       [9.51730132e-01, 4.82698716e-02],
       [7.93448269e-01, 2.06551731e-01],
       ...,
       [9.90314305e-01, 9.68566816e-03],
       [6.45816326e-04, 9.99354184e-01],
       [9.71042812e-01, 2.89571714e-02]])

คุณแปลง dataframe ของ pandas เป็นอาร์เรย์จำนวนมาก

X_train_lime = X_train_lime.values
X_test_lime = X_test_lime.values
X_test_lime
array([[4.00000e+01, 5.00000e+00, 1.93524e+05, ..., 0.00000e+00,
        4.00000e+01, 3.80000e+01],
       [2.70000e+01, 4.00000e+00, 2.16481e+05, ..., 0.00000e+00,
        4.00000e+01, 3.80000e+01],
       [2.50000e+01, 4.00000e+00, 2.56263e+05, ..., 0.00000e+00,
        4.00000e+01, 3.80000e+01],
       ...,
       [2.80000e+01, 6.00000e+00, 2.11032e+05, ..., 0.00000e+00,
        4.00000e+01, 2.50000e+01],
       [4.40000e+01, 4.00000e+00, 1.67005e+05, ..., 0.00000e+00,
        6.00000e+01, 3.80000e+01],
       [5.30000e+01, 4.00000e+00, 2.57940e+05, ..., 0.00000e+00,
        4.00000e+01, 3.80000e+01]])
model_xgb.predict_proba(X_test_lime)
array([[7.9646105e-01, 2.0353897e-01],
       [9.5173013e-01, 4.8269872e-02],
       [7.9344827e-01, 2.0655173e-01],
       ...,
       [9.9031430e-01, 9.6856682e-03],
       [6.4581633e-04, 9.9935418e-01],
       [9.7104281e-01, 2.8957171e-02]], dtype=float32)
print(features,
      class_names,
      categorical_features,
      categorical_names)
['age', 'workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country'] ['<=50K' '>50K'] [1, 3, 5, 6, 7, 8, 9, 13] {'workclass': array(['?', 'Federal-gov', 'Local-gov', 'Never-worked', 'Private',
       'Self-emp-inc', 'Self-emp-not-inc', 'State-gov', 'Without-pay'],
      dtype=object), 'education': array(['10th', '11th', '12th', '1st-4th', '5th-6th', '7th-8th', '9th',
       'Assoc-acdm', 'Assoc-voc', 'Bachelors', 'Doctorate', 'HS-grad',
       'Masters', 'Preschool', 'Prof-school', 'Some-college'],
      dtype=object), 'marital': array(['Divorced', 'Married-AF-spouse', 'Married-civ-spouse',
       'Married-spouse-absent', 'Never-married', 'Separated', 'Widowed'],
      dtype=object), 'occupation': array(['?', 'Adm-clerical', 'Armed-Forces', 'Craft-repair',
       'Exec-managerial', 'Farming-fishing', 'Handlers-cleaners',
       'Machine-op-inspct', 'Other-service', 'Priv-house-serv',
       'Prof-specialty', 'Protective-serv', 'Sales', 'Tech-support',
       'Transport-moving'], dtype=object), 'relationship': array(['Husband', 'Not-in-family', 'Other-relative', 'Own-child',
       'Unmarried', 'Wife'], dtype=object), 'race': array(['Amer-Indian-Eskimo', 'Asian-Pac-Islander', 'Black', 'Other',
       'White'], dtype=object), 'sex': array(['Female', 'Male'], dtype=object), 'native_country': array(['?', 'Cambodia', 'Canada', 'China', 'Columbia', 'Cuba',
       'Dominican-Republic', 'Ecuador', 'El-Salvador', 'England',
       'France', 'Germany', 'Greece', 'Guatemala', 'Haiti', 'Honduras',
       'Hong', 'Hungary', 'India', 'Iran', 'Ireland', 'Italy', 'Jamaica',
       'Japan', 'Laos', 'Mexico', 'Nicaragua',
       'Outlying-US(Guam-USVI-etc)', 'Peru', 'Philippines', 'Poland',
       'Portugal', 'Puerto-Rico', 'Scotland', 'South', 'Taiwan',
       'Thailand', 'Trinadad&Tobago', 'United-States', 'Vietnam',
       'Yugoslavia'], dtype=object)}
import lime
import lime.lime_tabular
### Train should be label encoded not one hot encoded
explainer = lime.lime_tabular.LimeTabularExplainer(X_train_lime ,
                                                   feature_names = features,
                                                   class_names=class_names,
                                                   categorical_features=categorical_features, 
                                                   categorical_names=categorical_names,
                                                   kernel_width=3)

ให้เราเลือกครัวเรือนแบบสุ่มจากชุดทดสอบและดูการทำนายแบบจำลองและวิธีที่คอมพิวเตอร์ตัดสินใจเลือก

import numpy as np
np.random.seed(1)
i = 100
print(y_test_lime.iloc[i])
>50K
X_test_lime[i]
array([4.20000e+01, 4.00000e+00, 1.76286e+05, 7.00000e+00, 1.20000e+01,
       2.00000e+00, 4.00000e+00, 0.00000e+00, 4.00000e+00, 1.00000e+00,
       0.00000e+00, 0.00000e+00, 4.00000e+01, 3.80000e+01])

คุณสามารถใช้ตัวอธิบายกับ expl_instance เพื่อตรวจสอบคำอธิบายเบื้องหลังโมเดล

exp = explainer.explain_instance(X_test_lime[i], predict_fn, num_features=6)
exp.show_in_notebook(show_all=False)

การเตรียมข้อมูล

เราจะเห็นว่าตัวแยกประเภททำนายครัวเรือนได้ถูกต้อง รายได้เกิน 50 จริงๆ

สิ่งแรกที่เราสามารถพูดได้คือตัวจำแนกประเภทไม่แน่ใจเกี่ยวกับความน่าจะเป็นที่คาดการณ์ไว้ เครื่องทำนายว่าครัวเรือนจะมีรายได้มากกว่า 50 ดอลลาร์ด้วยความน่าจะเป็น 64% ซึ่ง 64% นี้ประกอบด้วยกำไรจากทุนและการแต่งงาน สีน้ำเงินส่งผลเชิงลบต่อชนชั้นเชิงบวก และเส้นสีส้มส่งผลเชิงบวก

ตัวจำแนกประเภทสับสนเนื่องจากกำไรจากทุนของครัวเรือนนี้เป็นศูนย์ ในขณะที่กำไรจากทุนมักจะเป็นตัวทำนายความมั่งคั่งได้ดี นอกจากนี้ ครัวเรือนทำงานน้อยกว่า 40 ชั่วโมงต่อสัปดาห์ อายุ อาชีพ และเพศมีส่วนสนับสนุนในเชิงบวกต่อตัวจำแนกประเภท

หากสถานภาพสมรสเป็นโสด ผู้จำแนกประเภทจะคาดการณ์รายได้ต่ำกว่า 50 (0.64-0.18 = 0.46)

เราสามารถลองกับครัวเรือนอื่นที่จัดประเภทผิดได้

temp.head(3)
temp.iloc[1,:-2]
age                  58
workclass             4
fnlwgt            68624
education            11
education_num         9
marital               2
occupation            4
relationship          0
race                  4
sex                   1
capital_gain          0
capital_loss          0
hours_week           45
native_country       38
Name: 20931, dtype: object
i = 1
print('This observation is', temp.iloc[i,-2:])
This observation is label        <=50K
predicted     >50K
Name: 20931, dtype: object
exp = explainer.explain_instance(temp.iloc[1,:-2], predict_fn, num_features=6)
exp.show_in_notebook(show_all=False)

การเตรียมข้อมูล

ตัวแยกประเภทคาดการณ์รายได้ที่ต่ำกว่า 50 ในขณะที่ไม่เป็นความจริง บ้านนี้ดูแปลกๆ ไม่มีการเพิ่มทุนหรือการสูญเสียเงินทุน เขาหย่าร้างและอายุ 60 ปี และเป็นคนมีการศึกษา เช่น education_num > 12 ตามรูปแบบโดยรวม ครัวเรือนนี้ควรมีรายได้ต่ำกว่า 50 ตามที่ตัวแยกประเภทอธิบายไว้

คุณพยายามเล่นกับ LIME คุณจะสังเกตเห็นข้อผิดพลาดร้ายแรงจากตัวแยกประเภท

คุณสามารถตรวจสอบ GitHub ของเจ้าของห้องสมุดได้ มีเอกสารประกอบเพิ่มเติมสำหรับการจำแนกรูปภาพและข้อความ

สรุป

ด้านล่างนี้คือรายการคำสั่งที่มีประโยชน์พร้อม scikit learn version >=0.20

สร้างชุดข้อมูลรถไฟ/ทดสอบ ผู้เข้ารับการฝึกอบรมแตกแยก
สร้างท่อส่งน้ำ
เลือกคอลัมน์และใช้การแปลง makecolumntransformer
ประเภทของการเปลี่ยนแปลง
วางมาตรฐาน เครื่องชั่งน้ำหนักมาตราฐาน
ขั้นต่ำสูงสุด MinMaxScaler
ปกติ นอร์มัลไลเซอร์
ระบุค่าที่ขาดหายไป ผู้ใส่ร้าย
แปลงเด็ดขาด OneHotEncoder
พอดีและแปลงข้อมูล พอดี_แปลงร่าง
ทำท่อ make_ไปป์ไลน์
แบบจำลองพื้นฐาน
การถดถอยโลจิสติก การถดถอยโลจิสติก
XGBoost XGBคลาสซิฟายเออร์
โครงข่ายประสาท MLPลักษณนาม
ค้นหากริด GridSearchCV
การค้นหาแบบสุ่ม สุ่มค้นหาCV