145 lecturi

Regresie logistică pentru clasificarea binară cu API-uri de bază

de hacker-xn6cm3221m2025/06/14
Read on Terminal Reader

Prea lung; A citi

Acest ghid arată cum să utilizați API-urile TensorFlow Core pentru a construi, instrui și evalua un model de regresie logistică pentru clasificarea tumorilor binare utilizând Setul de date privind cancerul mamar din Wisconsin.
featured image - Regresie logistică pentru clasificarea binară cu API-uri de bază
undefined HackerNoon profile picture
0-item

Conținut Overview

  • setare
  • Încărcați datele
  • Preprocesarea datelor
  • Regresie logistică
  • Fundamentele regresiei logistice
  • Funcția Log Loss
  • Regula de actualizare a gradului de coborâre
  • Train the model
  • Evaluarea performanței
  • Salvează modelul
  • Concluzie


Acest ghid demonstrează modul de utilizare a API-urilor de nivel scăzut TensorFlow Core pentru a efectua clasificarea binară cu regresie logistică.Wisconsin Cancerul de sân Datasetpentru clasificarea tumorilor.

Regresie logisticăDatorită unui set de exemple cu caracteristici, obiectivul regresiei logistice este de a produce valori între 0 și 1, care pot fi interpretate ca probabilitățile fiecărui exemplu aparținând unei anumite clase.


setare

Tutorialul utilizeazăpandăPentru a citi un fișier CSV în aDataframe,Seaborn for plotting a pairwise relationship in a dataset, Învățațipentru calcularea unei matrice de confuzie şiMatplotlibPentru a crea vizualizări.


pip install -q seaborn


import tensorflow as tf
import pandas as pd
import matplotlib
from matplotlib import pyplot as plt
import seaborn as sns
import sklearn.metrics as sk_metrics
import tempfile
import os

# Preset matplotlib figure sizes.
matplotlib.rcParams['figure.figsize'] = [9, 6]

print(tf.__version__)
# To make the results reproducible, set the random seed value.
tf.random.set_seed(22)


2024-08-15 02:45:41.468739: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:485] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered
2024-08-15 02:45:41.489749: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:8454] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered
2024-08-15 02:45:41.496228: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1452] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered
2.17.0


Încărcați datele

Apoi, încărcațiWisconsin Cancerul de sân DatasetDe laUCI Machine Learning Repository (Repositorie de învățare automată)Acest set de date conține diferite caracteristici, cum ar fi raza, textura și concavitatea unei tumori.


url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data'

features = ['radius', 'texture', 'perimeter', 'area', 'smoothness', 'compactness',
            'concavity', 'concave_poinits', 'symmetry', 'fractal_dimension']
column_names = ['id', 'diagnosis']

for attr in ['mean', 'ste', 'largest']:
  for feature in features:
    column_names.append(feature + "_" + attr)

Citiți setul de date într-o pandăDataframeUtilizareapandas.read_csv:


dataset = pd.read_csv(url, names=column_names)


dataset.info()


<class 'pandas.core.frame.DataFrame'>
RangeIndex: 569 entries, 0 to 568
Data columns (total 32 columns):
 #   Column                     Non-Null Count  Dtype  
---  ------                     --------------  -----  
 0   id                         569 non-null    int64  
 1   diagnosis                  569 non-null    object 
 2   radius_mean                569 non-null    float64
 3   texture_mean               569 non-null    float64
 4   perimeter_mean             569 non-null    float64
 5   area_mean                  569 non-null    float64
 6   smoothness_mean            569 non-null    float64
 7   compactness_mean           569 non-null    float64
 8   concavity_mean             569 non-null    float64
 9   concave_poinits_mean       569 non-null    float64
 10  symmetry_mean              569 non-null    float64
 11  fractal_dimension_mean     569 non-null    float64
 12  radius_ste                 569 non-null    float64
 13  texture_ste                569 non-null    float64
 14  perimeter_ste              569 non-null    float64
 15  area_ste                   569 non-null    float64
 16  smoothness_ste             569 non-null    float64
 17  compactness_ste            569 non-null    float64
 18  concavity_ste              569 non-null    float64
 19  concave_poinits_ste        569 non-null    float64
 20  symmetry_ste               569 non-null    float64
 21  fractal_dimension_ste      569 non-null    float64
 22  radius_largest             569 non-null    float64
 23  texture_largest            569 non-null    float64
 24  perimeter_largest          569 non-null    float64
 25  area_largest               569 non-null    float64
 26  smoothness_largest         569 non-null    float64
 27  compactness_largest        569 non-null    float64
 28  concavity_largest          569 non-null    float64
 29  concave_poinits_largest    569 non-null    float64
 30  symmetry_largest           569 non-null    float64
 31  fractal_dimension_largest  569 non-null    float64
dtypes: float64(30), int64(1), object(1)
memory usage: 142.4+ KB

Display the first five rows:


dataset.head()


id	diagnosis	radius_mean	texture_mean	perimeter_mean	area_mean	smoothness_mean	compactness_mean	concavity_mean	concave_poinits_mean	...	radius_largest	texture_largest	perimeter_largest	area_largest	smoothness_largest	compactness_largest	concavity_largest	concave_poinits_largest	symmetry_largest	fractal_dimension_largest

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0


Împărțiți setul de date în seturi de instruire și testare utilizândpandas.DataFrame.sample,pandas.DataFrame.dropşipandas.DataFrame.iloc. Make sure to split the features from the target labels. The test set is used to evaluate your model's generalizability to unseen data.


train_dataset = dataset.sample(frac=0.75, random_state=1)


len(train_dataset)


427


test_dataset = dataset.drop(train_dataset.index)


len(test_dataset)


142


# The `id` column can be dropped since each row is unique
x_train, y_train = train_dataset.iloc[:, 2:], train_dataset.iloc[:, 1]
x_test, y_test = test_dataset.iloc[:, 2:], test_dataset.iloc[:, 1]


Preprocesarea datelor

Acest set de date conține valoarea medie, eroarea standard și valorile maxime pentru fiecare dintre cele 10 măsurători ale tumorii colectate de exemplu."diagnosis"coloana țintă este o variabilă categorică cu'M'Indică o tumoare malignă și'B'Această coloană trebuie să fie convertită într-un format binar numeric pentru formarea modelului.

pepandas.Series.mapFuncția este utilă pentru cartografierea valorilor binare în categorii.

De asemenea, setul de date ar trebui transformat într-un tensor cutf.convert_to_tensorFuncția după prelucrare este completă.


y_train, y_test = y_train.map({'B': 0, 'M': 1}), y_test.map({'B': 0, 'M': 1})
x_train, y_train = tf.convert_to_tensor(x_train, dtype=tf.float32), tf.convert_to_tensor(y_train, dtype=tf.float32)
x_test, y_test = tf.convert_to_tensor(x_test, dtype=tf.float32), tf.convert_to_tensor(y_test, dtype=tf.float32)


WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1723689945.265757  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.269593  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.273290  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.276976  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.288712  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.292180  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.295550  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.299093  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.302584  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.306098  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.309484  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689945.312921  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.538105  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.540233  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.542239  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.544278  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.546323  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.548257  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.550168  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.552143  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.554591  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.556540  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.558447  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.560412  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.599852  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.601910  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.604061  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.606104  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.608094  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.610074  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.611985  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.613947  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.615903  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.618356  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.620668  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1723689946.623031  132290 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355

Utilizațiseaborn.pairplotpentru a revizui distribuția comună a câtorva perechi de caracteristici bazate pe medie din setul de instruire și pentru a observa modul în care acestea se referă la țintă:


sns.pairplot(train_dataset.iloc[:, 1:6], hue = 'diagnosis', diag_kind='kde');


Această pereche demonstrează că anumite caracteristici, cum ar fi raza, perimetrul și zona sunt foarte corelate. Acest lucru este de așteptat, deoarece raza tumorii este direct implicată în calculul ambelor perimetrul și zona.

Asigurați-vă că verificați și statisticile generale. Observați modul în care fiecare caracteristică acoperă o gamă foarte diferită de valori.


train_dataset.describe().transpose()[:10]




count

mean

std

min

25%

50%

75%

max

id

427.0

2.756014e+07

1.162735e+08

8670.00000

865427.500000

905539.00000

8.810829e+06

9.113205e+08

radius_mean

427.0

1.414331e+01

3.528717e+00

6.98100

11.695000

13.43000

1.594000e+01

2.811000e+01

texture_mean

427.0

1.924468e+01

4.113131e+00

10.38000

16.330000

18.84000

2.168000e+01

3.381000e+01

perimeter_mean

427.0

9.206759e+01

2.431431e+01

43.79000

75.235000

86.87000

1.060000e+02

1.885000e+02

area_mean

427.0

6.563190e+02

3.489106e+02

143.50000

420.050000

553.50000

7.908500e+02

2.499000e+03

smoothness_mean

427.0

9.633618e-02

1.436820e-02

0.05263

0.085850

0.09566

1.050000e-01

1.634000e-01

compactness_mean

427.0

1.036597e-01

5.351893e-02

0.02344

0.063515

0.09182

1.296500e-01

3.454000e-01

concavity_mean

427.0

8.833008e-02

7.965884e-02

0.00000

0.029570

0.05999

1.297500e-01

4.268000e-01

concave_poinits_mean

427.0

4.872688e-02

3.853594e-02

0.00000

0.019650

0.03390

7.409500e-02

2.012000e-01

symmetry_mean

427.0

1.804597e-01

2.637837e-02

0.12030

0.161700

0.17840

1.947000e-01

2.906000e-01

ID

427.0

2.756014e+07

1.162735e+08

8670.00000

865427.500000

905539.00000

8.810829e+06

9.113205e+08

Războiul înseamnă

427.0

1.414331e+01

3.528717e+00

6.98100

11.695000

13.43000

1.594000e+01

2.811000e+01

Textul = semnificaţie

427.0

1.924468e+01

4.113131e+00

10.38000

16.330000

18.84000

2.168000e+01

3.381000e+01

Perimetrul înseamnă

427.0

9.206759e+01

2.431431e+01

43.79000

75.235000

86.87000

1.060000e+02

1.885000e+02

Domeniul înțelesului

427.0

6.563190e+02

3.489106e+02

143.50000

420.050000

553.50000

7.908500e+02

2.499000e+03

Smoothness - semnifică

427.0

9.633618e-02

1.436820e-02

0.05263

0.085850

0.09566

1.050000e-01

1.634000e-01

compactness_mean

427.0

1.036597e-01

5.351893e-02

0.02344

0.063515

0.09182

1.296500e-01

3.454000e-01

Cuvânt cheie_mean

427.0

8.833008e-02

7.965884e-02

0.00000

0.029570

0.05999

1.297500e-01

4.268000e-01

concave_poinits_mean înțeles

427.0

4.872688e-02

3.853594e-02

0.00000

0.019650

0.03390

7.409500e-02

2.012000e-01

symmetry_mean

427.0

1.804597e-01

2.637837e-02

0.12030

0.161700

0.17840

1.947000e-01

2.906000e-01

Given the inconsistent ranges, it is beneficial to standardize the data such that each feature has a zero mean and unit variance. This process is called normalization.


class Normalize(tf.Module):
  def __init__(self, x):
    # Initialize the mean and standard deviation for normalization
    self.mean = tf.Variable(tf.math.reduce_mean(x, axis=0))
    self.std = tf.Variable(tf.math.reduce_std(x, axis=0))

  def norm(self, x):
    # Normalize the input
    return (x - self.mean)/self.std

  def unnorm(self, x):
    # Unnormalize the input
    return (x * self.std) + self.mean

norm_x = Normalize(x_train)
x_train_norm, x_test_norm = norm_x.norm(x_train), norm_x.norm(x_test)


Regresie logistică

Înainte de a construi un model de regresie logistică, este crucial să înțelegem diferențele metodei față de regresia liniară tradițională.

Fundamentele regresiei logistice

Regresia liniară returnează o combinație liniară a intrărilor sale; această ieșire este nelimitată.Regresie logisticăEste în(0, 1)pentru fiecare exemplu, reprezintă probabilitatea ca exemplul să aparţinăpozitivăde clasă.

Regresia logistică cartografiază rezultatele continue ale regresiei liniare tradiționale,(-∞, ∞)În ceea ce priveşte probabilităţile,(0, 1)Această transformare este, de asemenea, simetrică, astfel încât întoarcerea semnului de ieșire liniară are ca rezultat inversul probabilității inițiale.

Lăsați Y să denumească probabilitatea de a fi în clasă1cartografierea dorită poate fi obţinută prin interpretarea rezultatului de regresie liniară ca fiindÎnregistrează oddsRaportul de a fi în clasă1Spre deosebire de clasa0:

ln⁡(Y1−Y)=wX+b

Prin setarea wX+b=z, această ecuație poate fi apoi rezolvată pentru Y:

Y=ez1+ez=11+e−z

Expresia 11+e−z este cunoscută sub numele deFuncția sigmoidPrin urmare, ecuația de regresie logistică poate fi scrisă ca Y =σ (wX + b).

Setul de date din acest tutorial se ocupă de o matrice de caracteristici de înaltă dimensiune. Prin urmare, ecuația de mai sus trebuie rescrisă într-o formă vectorială de matrice după cum urmează:

Y=σ(Xw+b)

în care:

  • Ym×1: un vector țintă
  • Xm×n: o matrice de caracteristici
  • wn×1: un vector de greutate
  • b) un bias
  • σ: o funcție sigmoidă aplicată fiecărui element al vectorului de ieșire

Începe prin vizualizarea funcției sigmoide, care transformă ieșirea liniară,(-∞, ∞)Pentru a cădea între0şi1Funcţia sigmoid este disponibilă întf.math.sigmoid.


x = tf.linspace(-10, 10, 500)
x = tf.cast(x, tf.float32)
f = lambda x : (1/20)*x + 0.6
plt.plot(x, tf.math.sigmoid(x))
plt.ylim((-0.1,1.1))
plt.title("Sigmoid function");


Funcția Log Loss

peLog pierdere, sau pierderea încrucișată binară, este funcția ideală de pierdere pentru o problemă de clasificare binară cu regresie logistică. Pentru fiecare exemplu, pierderea de jurnal cuantifică similitudinea dintre o probabilitate prezisă și valoarea reală a exemplului.

L=−1m∑i=1myi⋅log⁡(y^i)+(1−yi)⋅log⁡(1−y^i)

în care:

  • y^: un vector al probabilităţilor prezise
  • y: un vector al obiectivelor reale

Puteţi utilizatf.nn.sigmoid_cross_entropy_with_logitsAceastă funcție aplică automat activarea sigmoidă la ieșirea de regresie:


def log_loss(y_pred, y):
  # Compute the log loss function
  ce = tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=y_pred)
  return tf.reduce_mean(ce)


Regula de actualizare a gradului de coborâre

API-urile TensorFlow Core acceptă diferențierea automată cutf.GradientTapeDacă sunteți curios despre matematica din spatele regresiei logisticeActualizări GradientIată o scurtă explicație:

În ecuația de mai sus pentru pierderea log, amintiți-vă că fiecare y^i poate fi rescris în termeni de intrări ca σ(Xiw + b).

Obiectivul este de a găsi un w și b care minimizează pierderea logului:

L=−1m∑i=1myi⋅log⁡(σ(Xiw+b))+(1−yi)⋅log⁡(1−σ(Xiw+b))

Luând gradientul L în raport cu w, obțineți următoarele:

∂L∂w=1m(σ(Xw+b)−y)X

Luând gradientul L în raport cu b, obțineți următoarele:

∂L∂b=1m∑i=1mσ(Xiw+b)−yi

Acum construiți modelul de regresie logistică.


class LogisticRegression(tf.Module):

  def __init__(self):
    self.built = False

  def __call__(self, x, train=True):
    # Initialize the model parameters on the first call
    if not self.built:
      # Randomly generate the weights and the bias term
      rand_w = tf.random.uniform(shape=[x.shape[-1], 1], seed=22)
      rand_b = tf.random.uniform(shape=[], seed=22)
      self.w = tf.Variable(rand_w)
      self.b = tf.Variable(rand_b)
      self.built = True
    # Compute the model output
    z = tf.add(tf.matmul(x, self.w), self.b)
    z = tf.squeeze(z, axis=1)
    if train:
      return z
    return tf.sigmoid(z)

Pentru a valida, asiguraţi-vă că modelul neinstruit emite valori în intervalul de(0, 1) for a small subset of the training data.


log_reg = LogisticRegression()


y_pred = log_reg(x_train_norm[:5], train=False)
y_pred.numpy()


array([0.9994985 , 0.9978607 , 0.29620072, 0.01979049, 0.3314926 ],
      dtype=float32)

Apoi, scrieți o funcție de precizie pentru a calcula proporția de clasificări corecte în timpul instruirii.Pentru a recupera clasificările din probabilitățile prezise, setați un prag pentru care toate probabilitățile mai mari decât pragul aparțin clasei1Acesta este un hiperparametru configurabil care poate fi setat la0.5Ca un defect.


def predict_class(y_pred, thresh=0.5):
  # Return a tensor with  `1` if `y_pred` > `0.5`, and `0` otherwise
  return tf.cast(y_pred > thresh, tf.float32)

def accuracy(y_pred, y):
  # Return the proportion of matches between `y_pred` and `y`
  y_pred = tf.math.sigmoid(y_pred)
  y_pred_class = predict_class(y_pred)
  check_equal = tf.cast(y_pred_class == y,tf.float32)
  acc_val = tf.reduce_mean(check_equal)
  return acc_val


Trenul modelului

Utilizarea mini-batch-urilor pentru antrenament asigură atât eficiența memoriei, cât și o convergență mai rapidă.tf.data.DatasetAPI are funcții utile pentru batching și shuffling. API-ul vă permite să construiți conducte de intrare complexe din piese simple, reutilizabile.


batch_size = 64
train_dataset = tf.data.Dataset.from_tensor_slices((x_train_norm, y_train))
train_dataset = train_dataset.shuffle(buffer_size=x_train.shape[0]).batch(batch_size)
test_dataset = tf.data.Dataset.from_tensor_slices((x_test_norm, y_test))
test_dataset = test_dataset.shuffle(buffer_size=x_test.shape[0]).batch(batch_size)

Acum scrieți o buclă de instruire pentru modelul de regresie logistică. buclă utilizează funcția de pierdere a jurnalului și gradientele sale în raport cu intrarea pentru a actualiza în mod iterativ parametrii modelului.


# Set training parameters
epochs = 200
learning_rate = 0.01
train_losses, test_losses = [], []
train_accs, test_accs = [], []

# Set up the training loop and begin training
for epoch in range(epochs):
  batch_losses_train, batch_accs_train = [], []
  batch_losses_test, batch_accs_test = [], []

  # Iterate over the training data
  for x_batch, y_batch in train_dataset:
    with tf.GradientTape() as tape:
      y_pred_batch = log_reg(x_batch)
      batch_loss = log_loss(y_pred_batch, y_batch)
    batch_acc = accuracy(y_pred_batch, y_batch)
    # Update the parameters with respect to the gradient calculations
    grads = tape.gradient(batch_loss, log_reg.variables)
    for g,v in zip(grads, log_reg.variables):
      v.assign_sub(learning_rate * g)
    # Keep track of batch-level training performance
    batch_losses_train.append(batch_loss)
    batch_accs_train.append(batch_acc)

  # Iterate over the testing data
  for x_batch, y_batch in test_dataset:
    y_pred_batch = log_reg(x_batch)
    batch_loss = log_loss(y_pred_batch, y_batch)
    batch_acc = accuracy(y_pred_batch, y_batch)
    # Keep track of batch-level testing performance
    batch_losses_test.append(batch_loss)
    batch_accs_test.append(batch_acc)

  # Keep track of epoch-level model performance
  train_loss, train_acc = tf.reduce_mean(batch_losses_train), tf.reduce_mean(batch_accs_train)
  test_loss, test_acc = tf.reduce_mean(batch_losses_test), tf.reduce_mean(batch_accs_test)
  train_losses.append(train_loss)
  train_accs.append(train_acc)
  test_losses.append(test_loss)
  test_accs.append(test_acc)
  if epoch % 20 == 0:
    print(f"Epoch: {epoch}, Training log loss: {train_loss:.3f}")


Epoch: 0, Training log loss: 0.661
Epoch: 20, Training log loss: 0.418
Epoch: 40, Training log loss: 0.269
Epoch: 60, Training log loss: 0.178
Epoch: 80, Training log loss: 0.137
Epoch: 100, Training log loss: 0.116
Epoch: 120, Training log loss: 0.106
Epoch: 140, Training log loss: 0.096
Epoch: 160, Training log loss: 0.094
Epoch: 180, Training log loss: 0.089


Evaluarea performanței

Observați schimbările în pierderea și acuratețea modelului în timp.


plt.plot(range(epochs), train_losses, label = "Training loss")
plt.plot(range(epochs), test_losses, label = "Testing loss")
plt.xlabel("Epoch")
plt.ylabel("Log loss")
plt.legend()
plt.title("Log loss vs training iterations");

plt.plot(range(epochs), train_accs, label = "Training accuracy")
plt.plot(range(epochs), test_accs, label = "Testing accuracy")
plt.xlabel("Epoch")
plt.ylabel("Accuracy (%)")
plt.legend()
plt.title("Accuracy vs training iterations");


print(f"Final training log loss: {train_losses[-1]:.3f}")
print(f"Final testing log Loss: {test_losses[-1]:.3f}")


Final training log loss: 0.089
Final testing log Loss: 0.077


print(f"Final training accuracy: {train_accs[-1]:.3f}")
print(f"Final testing accuracy: {test_accs[-1]:.3f}")


Final training accuracy: 0.968
Final testing accuracy: 0.979

Modelul demonstrează o precizie ridicată și o pierdere scăzută atunci când vine vorba de clasificarea tumorilor în setul de date de instruire și, de asemenea, se generalizează bine la datele de testare invizibile. Pentru a merge un pas mai departe, puteți explora ratele de eroare care oferă mai multe informații dincolo de scorul general de precizie. Cele două rate de eroare cele mai populare pentru problemele de clasificare binară sunt rata falsă pozitivă (FPR) și rata falsă negativă (FNR).

Pentru această problemă, FPR este proporția de predicții tumorale maligne în rândul tumorilor care sunt de fapt benigne.

Calcularea unei matrice de confuzie utilizândsklearn.metrics.confusion_matrix, care evaluează acuratețea clasificării și utilizează matplotlib pentru a afișa matricea:


def show_confusion_matrix(y, y_classes, typ):
  # Compute the confusion matrix and normalize it
  plt.figure(figsize=(10,10))
  confusion = sk_metrics.confusion_matrix(y.numpy(), y_classes.numpy())
  confusion_normalized = confusion / confusion.sum(axis=1, keepdims=True)
  axis_labels = range(2)
  ax = sns.heatmap(
      confusion_normalized, xticklabels=axis_labels, yticklabels=axis_labels,
      cmap='Blues', annot=True, fmt='.4f', square=True)
  plt.title(f"Confusion matrix: {typ}")
  plt.ylabel("True label")
  plt.xlabel("Predicted label")

y_pred_train, y_pred_test = log_reg(x_train_norm, train=False), log_reg(x_test_norm, train=False)
train_classes, test_classes = predict_class(y_pred_train), predict_class(y_pred_test)


show_confusion_matrix(y_train, train_classes, 'Training')

show_confusion_matrix(y_test, test_classes, 'Testing')

În multe studii medicale de testare, cum ar fi detectarea cancerului, având o rată falsă pozitivă ridicată pentru a asigura o rată falsă negativă scăzută este perfect acceptabilă și de fapt încurajată, deoarece riscul de a pierde un diagnostic de tumoare malignă (fals negativ) este mult mai rău decât clasificarea greșită a unei tumori benigne ca maligne (false pozitiv).

Pentru a controla FPR și FNR, încercați să schimbați hiperparametrul pragului înainte de a clasifica predicțiile de probabilitate. Un prag mai mic crește șansele generale ale modelului de a face o clasificare a tumorii maligne. Acest lucru crește în mod inevitabil numărul de false pozitive și FPR, dar ajută, de asemenea, la reducerea numărului de false negative și FNR.


Salvează modelul

Începeți prin crearea unui modul de export care ia date brute și efectuează următoarele operațiuni:

  • normalizare
  • Prognoza probabilității
  • Predicții de clasă


class ExportModule(tf.Module):
  def __init__(self, model, norm_x, class_pred):
    # Initialize pre- and post-processing functions
    self.model = model
    self.norm_x = norm_x
    self.class_pred = class_pred

  @tf.function(input_signature=[tf.TensorSpec(shape=[None, None], dtype=tf.float32)])
  def __call__(self, x):
    # Run the `ExportModule` for new data points
    x = self.norm_x.norm(x)
    y = self.model(x, train=False)
    y = self.class_pred(y)
    return y


log_reg_export = ExportModule(model=log_reg,
                              norm_x=norm_x,
                              class_pred=predict_class)

Dacă doriţi să salvaţi modelul în starea sa actuală, puteţi face acest lucru utilizândtf.saved_model.savePentru a încărca un model salvat şi a face predicţii, utilizaţitf.saved_model.loadfuncţie .


models = tempfile.mkdtemp()
save_path = os.path.join(models, 'log_reg_export')
tf.saved_model.save(log_reg_export, save_path)


INFO:tensorflow:Assets written to: /tmpfs/tmp/tmp9k_sar52/log_reg_export/assets
INFO:tensorflow:Assets written to: /tmpfs/tmp/tmp9k_sar52/log_reg_export/assets


log_reg_loaded = tf.saved_model.load(save_path)
test_preds = log_reg_loaded(x_test)
test_preds[:10].numpy()


array([1., 1., 1., 1., 0., 1., 1., 1., 1., 1.], dtype=float32)


Concluzie

Acest notebook a introdus câteva tehnici pentru a gestiona o problemă de regresie logistică.

  • API-urile TensorFlow Core pot fi utilizate pentru a construi fluxuri de lucru de învățare automată cu niveluri ridicate de configurabilitate
  • Analyzing error rates is a great way to gain more insight about a classification model's performance beyond its overall accuracy score.
  • Overfitting este o altă problemă comună pentru modelele de regresie logistică, deși nu a fost o problemă pentru acest tutorial.

Pentru mai multe exemple de utilizare a API-urilor TensorFlow Core, consultațiGhidulDacă doriți să aflați mai multe despre încărcarea și pregătirea datelor, consultați tutorialele de peImagini de încărcare a datelorsauÎncărcarea datelor CSV.


Publicat inițial pe site-ul TensorFlow, acest articol apare aici sub un titlu nou și este licențiat sub CC BY 4.0.

Publicată inițial peTensorFlowAcest articol apare aici sub un titlu nou și este licențiat sub CC BY 4.0.

TensorFlow


Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks