<jupyter_start><jupyter_text>![](http://www.cs.wisc.edu/~olvi/uwmp/92_5622_www.gif)['breast-cancer-wisconsin-data-kaggle-link'](https://www.kaggle.com/uciml/breast-cancer-wisconsin-data/version/2)[breast-cancer-wisconsin-data-uci-link](http://archive.ics.uci.edu/ml/datasets/breast+cancer+wisconsin+%28diagnostic%29)<jupyter_code># The goal is to classify whether the breast cancer is benign or malignant. 
import warnings
warnings.filterwarnings('ignore')

import numpy as np
import pandas as pd

# Fit with polyfit
from numpy.polynomial.polynomial import polyfit

import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
sns.set(style = "whitegrid")
sns.set(color_codes = True)
plt.style.use('ggplot')

#Encoding categorical data values
from sklearn.preprocessing import LabelEncoder

#Feature Scaling
from sklearn.preprocessing import StandardScaler

from sklearn.model_selection import train_test_split

from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
import statsmodels.api as sm
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from xgboost import XGBClassifier
from sklearn.ensemble import GradientBoostingClassifier  #GBM algorithm

from sklearn.metrics import roc_auc_score, roc_curve, auc
from sklearn.utils import resample

from scipy.stats import skew

from multiprocessing import Process

import time    
import datetime
bc = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data',  names = ['id', 'diagnosis', 'radius_mean', 'texture_mean', 'perimeter_mean',
       'area_mean', 'smoothness_mean', 'compactness_mean', 'concavity_mean',
       'concave points_mean', 'symmetry_mean', 'fractal_dimension_mean',
       'radius_se', 'texture_se', 'perimeter_se', 'area_se', 'smoothness_se',
       'compactness_se', 'concavity_se', 'concave points_se', 'symmetry_se',
       'fractal_dimension_se', 'radius_worst', 'texture_worst',
       'perimeter_worst', 'area_worst', 'smoothness_worst',
       'compactness_worst', 'concavity_worst', 'concave points_worst',
       'symmetry_worst', 'fractal_dimension_worst', 'Unnamed: 32'])

bc.head()
bc.shape
bc.info()
bc.columns
from IPython.core.display import display, HTML
display(HTML("""<p class="normal">1) ID number
<br>2) Diagnosis (M = malignant, B = benign)
<br>3-32)
<br>
<br>Ten real-valued features are computed for each cell nucleus:
<br>
<br>	a) radius (mean of distances from center to points on the perimeter)
<br>	b) texture (standard deviation of gray-scale values)
<br>	c) perimeter
<br>	d) area
<br>	e) smoothness (local variation in radius lengths)
<br>	f) compactness (perimeter^2 / area - 1.0)
<br>	g) concavity (severity of concave portions of the contour)
<br>	h) concave points (number of concave portions of the contour)
<br>	i) symmetry 
<br>	j) fractal dimension ("coastline approximation" - 1)</p>"""))
x = pd.DataFrame(bc.isnull().sum())
x[x[0] > 0].T
del bc['Unnamed: 32']
bc.columns
labelencoder = LabelEncoder()
bc.diagnosis = labelencoder.fit_transform(bc.diagnosis)
bc.head(2)
bc.drop(['id', 'diagnosis'], axis = 1).hist(figsize = (14, 14))
plt.show()
bc.diagnosis.value_counts().plot(kind = 'bar')
#or # subdata.Year.value_counts().plot.bar()
plt.title('Number of Malignent and Benign Cancer')
plt.xlabel('Diagnosis')
plt.ylabel('Count')
plt.xticks([.05 ,1], ['Benign', 'Malignent'])
plt.show()
# We can observe our data has more Benign diagnosis.
#bc.drop(['id'], axis = 1).corr().style.background_gradient().set_precision(2)
plt.figure(figsize = (12, 8))
sns.heatmap(bc.drop(['id'], axis = 1).corr())
plt.show()
pd.DataFrame(bc.drop(['id'], axis = 1).corr()['diagnosis'].sort_values(ascending = False)[1:12]).T #top 15 values
pd.DataFrame(bc.drop(['id'], axis = 1).corr()['diagnosis'].sort_values(ascending = False)[-5:]).T #last 5 values`
# We can observe that our diagnosis is highly correlated with radius_mean, perimeter_mean, area_mean, 
# concave points_mean(number of concave portions of the contour)
# Let's plot the ones with high correlation with diagnosis
results = sm.OLS(bc.diagnosis, bc.radius_mean).fit()

b, m = polyfit(bc.diagnosis, bc.radius_mean, 1)

plt.plot(bc.diagnosis, bc.radius_mean, 'D')
plt.plot(bc.diagnosis, b + m * bc.diagnosis, '-')

plt.xticks([0.0 ,1.0], ['Benign', 'Malignent'])
plt.ylabel('Radius')
plt.title('Relationship between the Radius of Tumor and Diagnosis')
plt.show()
results = sm.OLS(bc.diagnosis, bc['concave points_mean']).fit()

b, m = polyfit(bc.diagnosis, bc['concave points_mean'], 1)

plt.plot(bc.diagnosis, bc['concave points_mean'], 'D')
plt.plot(bc.diagnosis, b + m * bc.diagnosis, '-')

plt.xticks([0.0 ,1.0], ['Benign', 'Malignent'])
plt.ylabel('Concativity of Tumor')
plt.title('Relationship between the Radius of Tumor and Concativity of Tumor')
plt.show()
# We can observe that the Malignant tumors are more concave and have more radius, this is true for the area or the perimeter also
X = bc.drop(['id', 'diagnosis'], axis = 1)
y = bc.diagnosis
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 1234)
# We need to bring all features to the same level of magnitudes. This is done by scaling. 
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
def model_clf(x):
    model = x
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)
    
    model_clf.cm = confusion_matrix(y_test, y_pred)
    model_clf.modl = str(x).split("(")[0]
    model_clf.accuracy = accuracy_score(y_test, y_pred)
models_list = [LogisticRegression(random_state = 1234),
             
               KNeighborsClassifier(n_neighbors = 3, metric = 'minkowski', p = 2),
             
               SVC(kernel = 'linear', random_state = 1234),
             
               SVC(kernel = 'rbf', random_state = 1234),
             
               GaussianNB(),
             
               DecisionTreeClassifier(criterion = 'entropy', random_state = 1234),
             
               RandomForestClassifier(n_estimators = 25, criterion = 'entropy', random_state = 1234),
             
               XGBClassifier(base_score = 0.5, colsample_bylevel = 1, colsample_bytree = 1,
                                   gamma = 0, learning_rate = 0.1, max_delta_step = 0, max_depth = 1,
                                   min_child_weight = 1, missing = None, n_estimators = 700, nthread = -1,
                                   objective = 'binary:logistic', reg_alpha = 0, reg_lambda = 1,
                                   scale_pos_weight = 1, seed = 1234, silent = True, subsample = 1),
             
               GradientBoostingClassifier(random_state = 1234)]
start_time = time.clock()

name = []
accuracy = []
conf = []
for mdl in models_list:
    model_clf(mdl)
    name.append(model_clf.modl)
    accuracy.append(model_clf.accuracy)
    conf.append(model_clf.cm)
    
print(time.clock() - start_time, "seconds")

df_ac = pd.DataFrame({'Model Name': name, 
              'Accuracy' : accuracy, 
              'Confusion Matrix' : conf}).set_index('Model Name')


df_ac
label_frac_error = 1 - np.diag(df_ac['Confusion Matrix'][:1][0]) / np.sum(df_ac['Confusion Matrix'][:1][0], axis=1)
plt.bar(np.arange(2), label_frac_error)
plt.xlabel('True Label')
plt.xticks([.05 ,1], ['Benign', 'Malignent'])
plt.ylabel('Fraction classified incorrectly')
plt.show()
df_ac['Accuracy'].plot(linestyle = '--', marker = 'D', color = 'b')
plt.xticks(np.arange(0, 9), list(df_ac.index), rotation = 90)
plt.title('Model Accuracy')
plt.title('Model Accuracy')
plt.legend()
plt.annotate('accuracy : 0.965035', xy=(-0.4, 0.966))
plt.show()
# Logistic Regression models seems to be outperforming other models.
# # let's look at the important columns in the model with the best accuracy, ie Logistic Regression
m = LogisticRegression(random_state = 1234).fit(X_train, y_train)

feature_importance = abs(m.coef_[0])
feature_importance = 100.0 * (feature_importance / feature_importance.max())
sorted_idx = np.argsort(feature_importance)
pos = np.arange(sorted_idx.shape[0]) + .5

plt.figure(figsize = (5, 10))
plt.barh(pos, feature_importance[sorted_idx], align='center')
plt.yticks(pos, (np.array(X.columns)[sorted_idx]), fontsize = 12)
plt.xlabel('Relative Feature Importance')
 
plt.show()
# texture, radius, smoothness, and area impacts our model for classifying between benign and malignant
# we can easily see that the imbalance in the classes is affecting our result, let's look at it closely through ROC_AUC
# Implementing the ROC curve on the logistic regression.  
prob_lr = LogisticRegression(random_state = 1234).fit(X_train, y_train).predict_proba(X_test)
prob_lr = [p[1] for p in prob_lr]

#Verifying the last five scores in prob_lr
prob_lr[:5]
print("AUC score is: ", roc_auc_score(y_test, prob_lr)) # AUC score
# The ROC_AUC is giving us good accuracy.  We can say that the model was not overfit and that the 
# imbalance is not significantly impacting the results
# plotting the ROC and AUC score
fpr, tpr, threshold = roc_curve(y_test, prob_lr)
print('fpr: ', fpr, '\ntpr: ', tpr, '\nthreshold: ', threshold)
plt.figure()
plt.plot(fpr, tpr)
plt.plot([0, 1], [0, 1], color = 'navy', linestyle = '--', label = 'ROC curve (area = %0.2f)' % auc(fpr, tpr))
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.legend(loc = "lower right")
plt.show()
# We will now try upsampling our prediction feature so we can mitigate the imbalance which might exist if we have more data points
bc.diagnosis.value_counts()
majority = bc[bc.diagnosis == 0]
minority = bc[bc.diagnosis == 1]

minority_upsampled = resample(minority, replace = True, n_samples = max(bc.diagnosis.value_counts()), random_state = 1234)

upsampled = pd.concat([majority, minority_upsampled])

# New data set for upsampled values
print(upsampled.diagnosis.value_counts())
X_b = upsampled.drop(['id', 'diagnosis'], axis = 1)
y_b = upsampled.diagnosis

X_train_b, X_test_b, y_train_b, y_test_b = train_test_split(X_b, y_b, test_size = 0.25, random_state = 1234)

X_train_b = sc.fit_transform(X_train_b)
X_test_b = sc.transform(X_test_b)
def model_clf(x):
    model = x
    model.fit(X_train_b, y_train_b)
    y_pred = model.predict(X_test_b)
    
    model_clf.cm = confusion_matrix(y_test_b, y_pred)
    model_clf.modl = str(x).split("(")[0]
    model_clf.accuracy = accuracy_score(y_test_b, y_pred)
start_time = time.clock()

name = []
accuracy = []
conf = []
for mdl in models_list:
    model_clf(mdl)
    name.append(model_clf.modl)
    accuracy.append(model_clf.accuracy)
    conf.append(model_clf.cm)
    
print(time.clock() - start_time, "seconds")

df_ac = pd.DataFrame({'Model Name': name, 
              'Accuracy' : accuracy, 
              'Confusion Matrix' : conf}).set_index('Model Name')


df_ac
label_frac_error =  1 - np.diag(df_ac['Confusion Matrix'][df_ac.Accuracy == np.max(df_ac.Accuracy)][0]) / np.sum(df_ac['Confusion Matrix'][df_ac.Accuracy == np.max(df_ac.Accuracy)][0])
plt.bar(np.arange(2), label_frac_error)
plt.xlabel('True Label')
plt.xticks([.05 ,1], ['Benign', 'Malignent'])
plt.ylabel('Fraction classified incorrectly')
plt.show()
df_ac['Accuracy'].plot(linestyle = '--', marker = 'D', color = 'b')
plt.xticks(np.arange(0, 9), list(df_ac.index), rotation = 90)
plt.title('Model Accuracy')
plt.title('Model Accuracy')
plt.legend()
plt.annotate(str(df_ac.index[df_ac.Accuracy == np.max(df_ac.Accuracy)][0]) + ' accuracy: ' + str(df_ac.Accuracy[df_ac.Accuracy == np.max(df_ac.Accuracy)][0]), xy=(-0.4, 0.967))
plt.show()
# there is still incorrectly predicted classes but their fraction is insignificant
# SVC linear model seems to be outperforming other models.<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13654953676654702, 'fraction_numerical': 0.01736082130039229, 'mean_word_length': 4.4687357371063445, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 23, 'https://': 1, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '208790', 'license': 'MIT', 'n_tokens_mistral': 4472, 'n_tokens_neox': 4126, 'n_words': 1023, 'path': 'Breast_Cancer.ipynb', 'repo_name': 'Nik8x/Breast_Cancer', 'size': '11981'}