Galle, LK--:--5/6 sites live

Project 19 Breast Cancer Classification using Machine Learning

Feature scaling ඉඳන් evaluation metrics දක්වා ඔක්කොම එකට එකතු කරන, high-stakes classification project එකක් — recall එක හරියට ගැනීම ඇත්තටම වැදගත් වෙන්න පුළුවන් model එකක් වර්ගයක්.

A final, high-stakes classification project pulling together everything from feature scaling to evaluation metrics — the kind of model where getting recall right can genuinely matter.

18 May 20267 min readSelf Guide · Stage 16#Evaluating & Choosing Models#Hands-on Projects#Machine learning

Lesson 52 of 64 · Part 4 · Evaluating & Choosing Models · Hands-on Projects · bilingual notes (English + සිංහල)

Why this matters. A final, high-stakes classification project pulling together everything from feature scaling to evaluation metrics — the kind of model where getting recall right can genuinely matter.

සිංහලෙන්: Feature scaling ඉඳන් evaluation metrics දක්වා ඔක්කොම එකට එකතු කරන, high-stakes classification project එකක් — recall එක හරියට ගැනීම ඇත්තටම වැදගත් වෙන්න පුළුවන් model එකක් වර්ගයක්.

What you'll use this for. This mirrors real diagnostic-support tools used alongside (never instead of) a doctor's judgment — the model flags likely cases for closer review.

සිංහලෙන්: Doctor කෙනෙකුගෙ තීරණයට වෙනුවට නෙවෙයි, ඒක එක්කම පාවිච්චි කරන සැබෑ diagnostic-support tools වගේම දෙයක් තමයි මේක — probable cases, ළං review එකකට flag කරනවා model එකෙන්.

Key principles

  • Feature scaling matters even more when features are on wildly different scales (like cell measurements in this dataset). A feature measured in the hundreds shouldn't automatically dominate one measured in decimals — standardization (from Part 1) is what keeps the comparison fair.
    Features දැඩි ලෙස වෙනස් scales වල තියෙනකොට (මේ dataset එකේ cell measurements වගේ), feature scaling එකට තව වැදගත්කම එනවා

Walkthrough

Importing the Dependencies

ExamplePython
import numpy as np
import pandas as pd
import sklearn.datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

Data Collection & Processing

ExamplePython
# loading the data from sklearn
breast_cancer_dataset = sklearn.datasets.load_breast_cancer()
ExamplePython
print(breast_cancer_dataset)

Output

Output
{'data': array([[1.799e+01, 1.038e+01, 1.228e+02, ..., 2.654e-01, 4.601e-01,
        1.189e-01],
       [2.057e+01, 1.777e+01, 1.329e+02, ..., 1.860e-01, 2.750e-01,
        8.902e-02],
       [1.969e+01, 2.125e+01, 1.300e+02, ..., 2.430e-01, 3.613e-01,
        8.758e-02],
       ...,
       [1.660e+01, 2.808e+01, 1.083e+02, ..., 1.418e-01, 2.218e-01,
        7.820e-02],
       [2.060e+01, 2.933e+01, 1.401e+02, ..., 2.650e-01, 4.087e-01,
        1.240e-01],
       [7.760e+00, 2.454e+01, 4.792e+01, ..., 0.000e+00, 2.871e-01,
        7.039e-02]]), 'target': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
       0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0,
       1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0,
       1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1,
       1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0,
… (29 more lines)
ExamplePython
# loading the data to a data frame
data_frame = pd.DataFrame(breast_cancer_dataset.data, columns = breast_cancer_dataset.feature_names)
ExamplePython
# print the first 5 rows of the dataframe
data_frame.head()
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavity…
017.9910.38122.801001.00.118400.277600.3001…
120.5717.77132.901326.00.084740.078640.0869…
219.6921.25130.001203.00.109600.159900.1974…
311.4220.3877.58386.10.142500.283900.2414…
420.2914.34135.101297.00.100300.132800.1980…
ExamplePython
# adding the 'target' column to the data frame
data_frame['label'] = breast_cancer_dataset.target
ExamplePython
# print last 5 rows of the dataframe
data_frame.tail()
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavity…
56421.5622.39142.001479.00.111000.115900.24390…
56520.1328.25131.201261.00.097800.103400.14400…
56616.6028.08108.30858.10.084550.102300.09251…
56720.6029.33140.101265.00.117800.277000.35140…
5687.7624.5447.92181.00.052630.043620.00000…
ExamplePython
# number of rows and columns in the dataset
data_frame.shape

Output

Output
(569, 31)
ExamplePython
# getting some information about the data
data_frame.info()

Output

Output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 569 entries, 0 to 568
Data columns (total 31 columns):
 #   Column                   Non-Null Count  Dtype  
---  ------                   --------------  -----  
 0   mean radius              569 non-null    float64
 1   mean texture             569 non-null    float64
 2   mean perimeter           569 non-null    float64
 3   mean area                569 non-null    float64
 4   mean smoothness          569 non-null    float64
 5   mean compactness         569 non-null    float64
 6   mean concavity           569 non-null    float64
 7   mean concave points      569 non-null    float64
 8   mean symmetry            569 non-null    float64
 9   mean fractal dimension   569 non-null    float64
 10  radius error             569 non-null    float64
 11  texture error            569 non-null    float64
 12  perimeter error          569 non-null    float64
… (20 more lines)
ExamplePython
# checking for missing values
data_frame.isnull().sum()

Output

Output
mean radius                0
mean texture               0
mean perimeter             0
mean area                  0
mean smoothness            0
mean compactness           0
mean concavity             0
mean concave points        0
mean symmetry              0
mean fractal dimension     0
radius error               0
texture error              0
perimeter error            0
area error                 0
smoothness error           0
compactness error          0
concavity error            0
concave points error       0
… (14 more lines)
ExamplePython
# statistical measures about the data
data_frame.describe()
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavity…
count569.000000569.000000569.000000569.000000569.000000569.000000569.000000…
mean14.12729219.28964991.969033654.8891040.0963600.1043410.088799…
std3.5240494.30103624.298981351.9141290.0140640.0528130.079720…
min6.9810009.71000043.790000143.5000000.0526300.0193800.000000…
25%11.70000016.17000075.170000420.3000000.0863700.0649200.029560…
50%13.37000018.84000086.240000551.1000000.0958700.0926300.061540…

… 2 more rows

ExamplePython
# checking the distribution of Target Varibale
data_frame['label'].value_counts()

Output

Output
1    357
0    212
Name: label, dtype: int64

1 --> Benign

0 --> Malignant

ExamplePython
data_frame.groupby('label').mean()
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavity…
label…
017.46283021.604906115.365377978.3764150.1028980.1451880.160775…
112.14652417.91476278.075406462.7901960.0924780.0800850.046058…

Separating the features and target

ExamplePython
X = data_frame.drop(columns='label', axis=1)
Y = data_frame['label']
ExamplePython
print(X)

Output

Output
     mean radius  mean texture  ...  worst symmetry  worst fractal dimension
0          17.99         10.38  ...          0.4601                  0.11890
1          20.57         17.77  ...          0.2750                  0.08902
2          19.69         21.25  ...          0.3613                  0.08758
3          11.42         20.38  ...          0.6638                  0.17300
4          20.29         14.34  ...          0.2364                  0.07678
..           ...           ...  ...             ...                      ...
564        21.56         22.39  ...          0.2060                  0.07115
565        20.13         28.25  ...          0.2572                  0.06637
566        16.60         28.08  ...          0.2218                  0.07820
567        20.60         29.33  ...          0.4087                  0.12400
568         7.76         24.54  ...          0.2871                  0.07039

[569 rows x 30 columns]
ExamplePython
print(Y)

Output

Output
0      0
1      0
2      0
3      0
4      0
      ..
564    0
565    0
566    0
567    0
568    1
Name: label, Length: 569, dtype: int64

Splitting the data into training data & Testing data

ExamplePython
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=2)
ExamplePython
print(X.shape, X_train.shape, X_test.shape)

Output

Output
(569, 30) (455, 30) (114, 30)

Model Training

Logistic Regression

ExamplePython
model = LogisticRegression()
ExamplePython
# training the Logistic Regression model using Training data

model.fit(X_train, Y_train)

Output

Output
/usr/local/lib/python3.7/dist-packages/sklearn/linear_model/_logistic.py:818: ConvergenceWarning: lbfgs failed to converge (status=1):
STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.

Increase the number of iterations (max_iter) or scale the data as shown in:
    https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
    https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
  extra_warning_msg=_LOGISTIC_SOLVER_CONVERGENCE_MSG,

Output

Output
LogisticRegression()

Model Evaluation

Accuracy Score

ExamplePython
# accuracy on training data
X_train_prediction = model.predict(X_train)
training_data_accuracy = accuracy_score(Y_train, X_train_prediction)
ExamplePython
print('Accuracy on training data = ', training_data_accuracy)

Output

Output
Accuracy on training data =  0.9494505494505494
ExamplePython
# accuracy on test data
X_test_prediction = model.predict(X_test)
test_data_accuracy = accuracy_score(Y_test, X_test_prediction)
ExamplePython
print('Accuracy on test data = ', test_data_accuracy)

Output

Output
Accuracy on test data =  0.9298245614035088

Building a Predictive System

ExamplePython
input_data = (13.54,14.36,87.46,566.3,0.09779,0.08129,0.06664,0.04781,0.1885,0.05766,0.2699,0.7886,2.058,23.56,0.008462,0.0146,0.02387,0.01315,0.0198,0.0023,15.11,19.26,99.7,711.2,0.144,0.1773,0.239,0.1288,0.2977,0.07259)

# change the input data to a numpy array
input_data_as_numpy_array = np.asarray(input_data)

# reshape the numpy array as we are predicting for one datapoint
input_data_reshaped = input_data_as_numpy_array.reshape(1,-1)

prediction = model.predict(input_data_reshaped)
print(prediction)

if (prediction[0] == 0):
  print('The Breast cancer is Malignant')

else:
  print('The Breast Cancer is Benign')

Output

Output
[1]
The Breast Cancer is Benign

Output

Output
/usr/local/lib/python3.7/dist-packages/sklearn/base.py:446: UserWarning: X does not have valid feature names, but LogisticRegression was fitted with feature nam
  "X does not have valid feature names, but"

Keep going: ← Lesson 51 · Lesson 53 → · Track it in the Self Guide