<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Narendra kumar A</title>
    <description>The latest articles on DEV Community by Narendra kumar A (@narendraanupoju).</description>
    <link>https://dev.to/narendraanupoju</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F286204%2Fe59829bc-fa2b-4f12-99a8-1a9cab3fb1f4.jpg</url>
      <title>DEV Community: Narendra kumar A</title>
      <link>https://dev.to/narendraanupoju</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/narendraanupoju"/>
    <language>en</language>
    <item>
      <title>Python &amp; data science in banking sectors</title>
      <dc:creator>Narendra kumar A</dc:creator>
      <pubDate>Thu, 03 Mar 2022 18:53:58 +0000</pubDate>
      <link>https://dev.to/narendraanupoju/python-data-science-in-banking-sectors-h8g</link>
      <guid>https://dev.to/narendraanupoju/python-data-science-in-banking-sectors-h8g</guid>
      <description>&lt;p&gt;Data science in banking plays a major role nowadays. Banks all over the world analyze data to provide better experiences to their customers and also to reduce risks.&lt;br&gt;
In this post, You can get to know the importance and role of data science in the banking sector and how it leverages the earnings potential by reducing the risks of a firm.&lt;/p&gt;

&lt;p&gt;Here are a few applications across banking:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Credit Decisions&lt;/li&gt;
&lt;li&gt;Risk Assessment&lt;/li&gt;
&lt;li&gt;Fraud prevention&lt;/li&gt;
&lt;li&gt;Process Automation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The above use cases have been applied by JP Morgan Chase &amp;amp; Co in their business operations and management as per a case study. You can find more information on the case study from the following link &lt;a href="https://www.superiordatascience.com/jpmcasestudy.html" rel="noopener noreferrer"&gt;https://www.superiordatascience.com/jpmcasestudy.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;A PayPal's Use case&lt;/u&gt;: Here is another example that was applied by PayPal. PayPal uses AI base model for listing your available payment options(between linked bank accounts and credit/debit cards). This happens when PayPal deducts money when you are performing transactions. With PayPal, you can observe your &lt;strong&gt;bank account doesn't show up few times when you are performing a transaction&lt;/strong&gt;. This moreover happens when you transfer funds with &lt;em&gt;friends and family&lt;/em&gt; or &lt;em&gt;Goods and services&lt;/em&gt; category. This is because an AI-based model will classify your list of payment options linked, based on the Risk Assessment analysis from your previous transactions.&lt;br&gt;
&lt;strong&gt;Note:&lt;/strong&gt; Accross the europe, the bank transactions will be preformed using a payment system called &lt;strong&gt;&lt;em&gt;SEPA Direct debit Mandate&lt;/em&gt;&lt;/strong&gt;. For paypal to preform these type of transactions they will not have access to check the users bank account whether they had enough funds or not. They will only get the information on whether a payment is successful or  declined after paypal registers the transaction on users account bank. This usually takes a couple of working days for bank to make successful or unsuccessful transaction. For this reason, paypal have to provide a credit for the user if they use the bank account which might be high risk depends on the transaction amount. So, during the risk assessment your listed bank account will more likely gets a high risk score than the credit cards or debit cards transactions.&lt;/p&gt;

&lt;p&gt;You can look into this thread for more information on this issue by few PayPal users at &lt;a href="https://www.paypal-community.com/t5/Transactions/Linked-bank-account-not-showing-as-payment-method/td-p/1808787" rel="noopener noreferrer"&gt;https://www.paypal-community.com/t5/Transactions/Linked-bank-account-not-showing-as-payment-method/td-p/1808787&lt;/a&gt;&lt;br&gt;
You can also find more information on how PayPal uses AI in their business from the following link &lt;a href="https://www.paypal.com/us/brc/article/enterprise-solutions-paypal-machine-learning-stop-fraud" rel="noopener noreferrer"&gt;https://www.paypal.com/us/brc/article/enterprise-solutions-paypal-machine-learning-stop-fraud&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A practical example with python:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a practical understanding, we can look into an example of Loan eligibility prediction. For this, we can use a publicly available dataset from the Kaggle. We start with data processing which includes handling missing data, data analysis then followed by training and testing machine learning models.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Loan eligibility identification&lt;/strong&gt;&lt;/em&gt; is one of the most challenging problems in the banking sector. Applicant’s eligibility for a loan will be based on several factors like credit history, Salary, loan application amount, tenure to repay, and a few other factors. To solve this problem we use machine learning to train a few sample records and predict future outcomes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Steps Involved:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dataset Information&lt;/li&gt;
&lt;li&gt;Loading data&lt;/li&gt;
&lt;li&gt;Dealing with Missing Values&lt;/li&gt;
&lt;li&gt;Adding extra features&lt;/li&gt;
&lt;li&gt;Exploratory Data Analysis&lt;/li&gt;
&lt;li&gt;Correlation matrix and Outliers Detection&lt;/li&gt;
&lt;li&gt;Encoding Categorical to numerical data&lt;/li&gt;
&lt;li&gt;Model training and evaluation&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here we use pandas, matplotlib, scikit-learn modules in our data processing and model development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dataset Information:&lt;/strong&gt; &lt;br&gt;
Contains  614 records with the following 13 column names&lt;br&gt;
'Loan_ID'&lt;br&gt;
'Gender'&lt;br&gt;
'Married'&lt;br&gt;
'Dependents'&lt;br&gt;
'Education'&lt;br&gt;
'Self_Employed'&lt;br&gt;
'ApplicantIncome'&lt;br&gt;
'CoapplicantIncome'&lt;br&gt;
'LoanAmount'&lt;br&gt;
'Loan_Amount_Term'&lt;br&gt;
'Credit_History'&lt;br&gt;
'Property_Area'&lt;br&gt;
'Loan_Status‘&lt;/p&gt;

&lt;p&gt;You can load the data using the following code sniplet:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loading data:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas as pd
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
data = pd.read_csv('train.csv')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9s9ecxzwsedtw73wf7n.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9s9ecxzwsedtw73wf7n.PNG" alt="Dataset_loaded" width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dealing with Missing Values:&lt;/strong&gt;&lt;br&gt;
After loading the dataset, we have to find whether any missing values exist in our dataset. We can deal with the missing values in different ways. We can either remove the rows containing missing values in case you consider having large enough dataset for model training, or we can fill the missing values by using any statistical methods by finding mean, average, or clustering, machine learning model to predict the missing values. This depends on the type of variables that you are dealing with and the amount of data available.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;print(data.isnull().sum())&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Will give us the count of missing values in each column of our dataframe.&lt;br&gt;
Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Loan_ID               0
Gender               13
Married               3
Dependents           15
Education             0
Self_Employed        32
ApplicantIncome       0
CoapplicantIncome     0
LoanAmount           22
Loan_Amount_Term     14
Credit_History       50
Property_Area         0
Loan_Status           0
dtype: int64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our dataset columns, Credit_History, Self_Emoloyed, Dependents, Loan_Amount_Term, Gender, and Married are categorical columns so we used mode to fill the missing values in these columns while LoanAmount is a numerical data type, so we fill these missing values using median of column values&lt;br&gt;
We can perform this operation with the folowing code sniplets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data['Gender'] = data['Gender'].fillna(data['Gender'].dropna().mode().values[0])
data['Married'] = data['Married'].fillna(data['Married'].dropna().mode().values[0])
data['Dependents'] = data['Dependents'].fillna(data['Dependents'].dropna().mode().values[0])
data['Self_Employed'] = data['Self_Employed'].fillna(data['Self_Employed'].dropna().mode().values[0])
data['LoanAmount'] = data['LoanAmount'].fillna(data['LoanAmount'].dropna().median())
data['Loan_Amount_Term'] = data['Loan_Amount_Term'].fillna(data['Loan_Amount_Term'].dropna().mode().values[0])
data['Credit_History'] = data['Credit_History'].fillna(data['Credit_History'].dropna().mode().values[0])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Adding extra features:&lt;/strong&gt; &lt;br&gt;
Adding extra features based on a few data analysis insights can improve the model accuracy.&lt;br&gt;
Based on our dataset and goal we are adding two extra columns Total_Income, avg_income_met.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total_Income is calculated by adding ApplicantIncome and CoapplicantIncome for each applicant/record.&lt;/li&gt;
&lt;li&gt;avg_income_met column is generated with 1’s and 0’s by calculating whether is applicant Total_Income is greater than the average income of all the applicants with Loan_Status=Y (Yes)
Dataframe with new columns:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fghwtnr1sin7xje108j83.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fghwtnr1sin7xje108j83.JPG" alt="extra_features" width="800" height="218"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exploratory Data Analysis:&lt;/strong&gt;&lt;br&gt;
Few data analysis observations were performed on the dataset to analyze and get insights throughout the data&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpduir6r2ca0x7i7apoto.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpduir6r2ca0x7i7apoto.JPG" alt="Exploratory data analysis" width="800" height="414"&gt;&lt;/a&gt;&lt;br&gt;
From the above graphs following observations can be noted&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Applicants with fewer Dependents have more possibility of getting a loan.&lt;/li&gt;
&lt;li&gt;More applications are made by the applicants from semi-urban areas.&lt;/li&gt;
&lt;li&gt;Graduates are more likely to get loans.&lt;/li&gt;
&lt;li&gt;Credit History should be moreover positive for the applicants with average income.&lt;/li&gt;
&lt;li&gt;Married people are more likely to apply for loans.&lt;/li&gt;
&lt;li&gt;Males applicants are higher than female applicants.&lt;/li&gt;
&lt;li&gt;Self-employed applicants have less probability of getting a loan.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The EDA graphs can be generated individually using the following code sniplets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data['Gender'].value_counts(normalize=True).plot.bar(title='Gender')
plt.show()

data['Married'].value_counts(normalize=True).plot.bar(title='Married')
plt.show()

data['Self_Employed'].value_counts(normalize=True).plot.bar(title='Self_Employed')
plt.show()

data['Credit_History'].value_counts(normalize=True).plot.bar(title='Credit_History')
plt.show()

# Independent Variable (Ordinal)
data['Dependents'].value_counts(normalize=True).plot.bar(title='Dependents', color= 'cyan',edgecolor='black')
plt.show()

data['Education'].value_counts(normalize=True).plot.bar(title='Education', color= 'cyan',edgecolor='black')
plt.show()

data['Property_Area'].value_counts(normalize=True).plot.bar(title='Property_Area', color= 'cyan',edgecolor='black')
plt.show()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Correlation matrix and Outliers Detection:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Correlation matrix is a table showing correlation coefficients between variables. Thus we can remove variables that having less correlation as a dimensional reduction technique.&lt;/li&gt;
&lt;li&gt;An outlier is a value in a data set that is very different from the other values. That is, outliers are values unusually far from the middle. In most cases, outliers have influence on mean , but not on the median , or mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Correlation matrix and boxplot can be generated using the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;corr = data.corr()
sns.heatmap(corr, 
            xticklabels=corr.columns.values,
            yticklabels=corr.columns.values)

data.boxplot(column = 'Total_Income', by = 'Loan_Status')
plt.suptitle("")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspmn1cpdbm496u9t97a6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspmn1cpdbm496u9t97a6.png" alt="correlation_matrix" width="436" height="339"&gt;&lt;/a&gt;&lt;br&gt;
From the above heatmap, we can observe that Married and Gender columns are negatively correlated and the Loan_Status is well correlated with credit_History.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1wy2saa424egmqdp8yu6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1wy2saa424egmqdp8yu6.png" alt="boxPlot" width="398" height="278"&gt;&lt;/a&gt;&lt;br&gt;
The above code sniplets will generate a box plot to check the data distribution of Total_income based on Loan_Status as above.&lt;br&gt;
From the above boxplot, we can observe that there are outliers present that have Total_Income greater than 60000. The outliers should be handled as these will reduce the standard deviation between variables and result in decreasing correlation. We considered data having greater than 30000 are outliers. We removed the records containing outliers with the following code sniplet.&lt;br&gt;
&lt;code&gt;data.drop(data[data.Total_Income &amp;gt;30000].index)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encoding Categorical to numerical data:&lt;/strong&gt;&lt;br&gt;
Columns Gender, Married, Education, Property_Area, Self_Employed, and Loan_Status contain categorical values. So we convert these data types to numerical by using a dictionary as mentioned below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat2num = {'Male': 1, 'Female': 2,
           'Yes': 1, 'No': 0,
            'Graduate': 1, 'Not Graduate': 0,
            'Rural': 1, 'Semiurban': 2,'Urban': 3,
            'Y': 1, 'N': 0,
            '3+': 3}
data = data.applymap(lambda item: cat2num.get(item) if item in cat2num else item)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before training machine learning algorithms, we have to evaluate whether all the features will be used to train the machine learning algorithms. In our data LoanID has unique values for each applicant, so we drop this column as it is not useful for model training and predictions.&lt;br&gt;
&lt;code&gt;data.drop('Loan_ID', axis = 1, inplace = True)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In our dataframe we have &lt;strong&gt;Dependants&lt;/strong&gt; column with values 0, 1, 2, 3, 3+. Here 3+ is not numerical datatypeinstead it is of string datatype. So we convert this to numerical datatype.&lt;br&gt;
&lt;code&gt;data['Dependents'] = pd.to_numeric(data['Dependents'])&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, we are good to train the data with a few machine learning models and test the model with predictions, and calculating accuracy with f1_score.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model training and evaluation:&lt;/strong&gt;&lt;br&gt;
All the models trained and tested are imported from the available scikit-learn module.&lt;br&gt;
Every model is imported from sklearn module&lt;br&gt;
.fit() method used to train&lt;br&gt;
     model.fit(X_train, y_train)&lt;br&gt;
X_train – contains all the features after splitting data.&lt;br&gt;
Y_train – contains target variable Loan_Status.&lt;br&gt;
•predict() method used for prediction&lt;br&gt;
Here we have used f1_socre which is an evaluation metric for testing model accuracy&lt;/p&gt;

&lt;p&gt;To achieve the goal, we have selected five classifier models to train and test on our data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support Vector Machine Classifier&lt;/li&gt;
&lt;li&gt;Decision Tree Classifier&lt;/li&gt;
&lt;li&gt;Random Forest Classifier&lt;/li&gt;
&lt;li&gt;KNearestNeighbors Classifier&lt;/li&gt;
&lt;li&gt;Naive Bayes Classifier
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score

#splitting data (80% - for training, 20% - for validation)
X_train, X_test, y_train, y_test = train_test_split(data.drop('Loan_Status', axis = 1), 
                                                    data['Loan_Status'], test_size=0.20, random_state=0)

# SVM classifier
from sklearn import svm
classifier = svm.SVC(kernel='linear')
classifier.fit(X_train,y_train)
svm_prediction = classifier.predict(X_test)
evaluation_svm = f1_score(y_test, svm_prediction)
print('SVM classifier f1_score : ', evaluation_svm)

# Decision Tree
from sklearn.tree import DecisionTreeClassifier
d_tree = DecisionTreeClassifier()
d_tree.fit(X_train, y_train)
d_pred = d_tree.predict(X_test)
evaluation_DT = f1_score(y_test, d_pred)
print('Decision Tree f1_score : ', evaluation_DT)

#Random Forest Classifier
from sklearn.ensemble import RandomForestClassifier
forest = RandomForestClassifier()
forest.fit(X_train, y_train)
forest_prediction = forest.predict(X_test)
evaluation_forest = f1_score(y_test, forest_prediction)
print('Random Forest Classifier f1_score : ', evaluation_forest)

#KNN classifier
from sklearn.neighbors import KNeighborsClassifier
KNN_model = KNeighborsClassifier(n_neighbors=3)
KNN_model.fit(X_train, y_train)
KNN_predicted= KNN_model.predict(X_test)
evaluation_KNN = f1_score(y_test, KNN_predicted)
print('KNN f1_score : ', evaluation_KNN)

# Navie Bayes classification
from sklearn.naive_bayes import GaussianNB
NB_model = GaussianNB()
NB_model.fit(X_train, y_train)
NB_predicted= NB_model.predict(X_test)
evaluation_NB = f1_score(y_test, NB_predicted)
print('NB f1_score : ', evaluation_NB)

scores_N = list(('svm', 'DT', 'forest', 'KNN', 'NB'))
scores = list((evaluation_svm, evaluation_DT, evaluation_forest, evaluation_KNN, evaluation_NB))
x = np.array([0,1,2,3,4])
plt.xticks(x, scores_N)
plt.plot(scores)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might need to use kfold technique to train and evaluate the models in cases of small dataset. &lt;br&gt;
&lt;strong&gt;K-Fold&lt;/strong&gt; is validation technique in which we split the data into k-subsets and the holdout method is repeated k-times where each of the k subsets are used as test set and other k-1 subsets are used for the training purpose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;br&gt;
Model evaluation is tested on 123 samples (20% of the dataset called validation dataset)&lt;br&gt;
From the above graph, we can observe that the Gaussian Naive Bayes classifier resulted in the highest accuracy of 89.23%&lt;br&gt;
Scores plot using matplotlib&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1gv1udaj2jx64gmfw3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1gv1udaj2jx64gmfw3e.png" alt="modelScores" width="372" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Future posts:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How datascience techniques can be used for malware detection on android systems.&lt;/li&gt;
&lt;li&gt;A programmers instinct towards datascience (In this post, I would like to discuss how programming tricks can be used to perform data-processing tasks, model development and training with a minimal knowledge on datascience concepts)
.
.
.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are interested to know how datascience can be used in any particular field, please comment your interested area of study. I will try do a post with a practical example.&lt;/p&gt;

&lt;p&gt;Please comment down, if you have any questions.&lt;br&gt;
Thank you for your time, hope you enjoyed reading. Happy learning&lt;/p&gt;

</description>
      <category>financialanalysis</category>
      <category>paypal</category>
      <category>datavisualization</category>
      <category>python</category>
    </item>
    <item>
      <title>Denoising MRI data with Tensorflow-Python</title>
      <dc:creator>Narendra kumar A</dc:creator>
      <pubDate>Fri, 18 Feb 2022 17:17:31 +0000</pubDate>
      <link>https://dev.to/narendraanupoju/denoising-mri-data-with-tensorflow-python-4c10</link>
      <guid>https://dev.to/narendraanupoju/denoising-mri-data-with-tensorflow-python-4c10</guid>
      <description>&lt;p&gt;You may find a lot of information on the internet about why deep learning is useful in medical imaging analysis and reconstruction. A simple answer is - ‘Medical data contains numerous amount of data points and where deep learning comes into play.’&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Data always follows a pattern, that can be analysed using different AI based models.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What next for this post??&lt;/p&gt;

&lt;p&gt;This post is to show a basic example on how deeplearning can be used in medical domain supporting the healthcare professionals with denoising medical imaging data. It can also be used in data analysis, disease detection, artifacts removal, reconstructing undersampled data and lot more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;prerequisite&lt;/u&gt;&lt;/strong&gt;: Basic knowledge on python, Numpy, Basics in dataprocessing(Image)&lt;/p&gt;

&lt;p&gt;For our example let us take few medical imaging data samples then create and train a basic deep learning model (convolutional autoencoder) that reduces the noise in our medical images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps involved:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reading data&lt;/li&gt;
&lt;li&gt;Preprocessing data&lt;/li&gt;
&lt;li&gt;Generating noisy data using scikit-learn random noise generator.&lt;/li&gt;
&lt;li&gt;Build a model and train&lt;/li&gt;
&lt;li&gt;Prediction and model evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Read data:&lt;/strong&gt; Here I am using a total of 20 MRI nifty volumes(T1 weighted MRI scans). We use nibabel a python module to load the data. Each volume contains a sequence of 128 brain slices which i have discussed in my previous blog @&lt;a href="https://dev.to/narendraanupoju/mri-data-processing-with-python-1jgg"&gt;https://dev.to/narendraanupoju/mri-data-processing-with-python-1jgg&lt;/a&gt;&lt;br&gt;
The following function can load the data from .nii or .nii.gz format files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import nibabel as nib
def FileRead(file_path):
    data = nib.load(file_path).get_fdata()
    return data[:,:,14:114]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dataset structure&lt;/strong&gt; - Each sample had a shape (256, 256, 128) (represented as a 3 dimensional numpy array). Here we can observe that we have 128 slices of brain scans sequentially. We also need to perform normalization for each sample because of the wide range of data distribution&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preprocess the data:&lt;/strong&gt; - Preprocessing is one of the most important step before training any machine learning or deep learning models. Preprocessing techniques can include data cleaning, data transformation, outliers detection, handling missing data ..soon a lot other depends on the input data and end result you need. We are using data transformation technique called normalization to reduce the variance in our data.&lt;/p&gt;

&lt;p&gt;Now we stack all the volumes and generate a NumPy array before it can be used for training a deep learning model. I am only considering the centric slices of the volumes as the initial and the end volumes don't contain more useful information for the model training, so we are neglecting them. 100 center slices are considered for each sample.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Note: Please note that, we are training the model with 2D slices rather than training with 3D volumes. &lt;/u&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import glob
import numpy as np
def normalize(x):
    x = (x-np.min(x)) / (np.max(x)-np.min(x))
    return x
listFiles = glob.glob('/*.nii.gz')
totalData = np.dstack([normalize(FileRead(file)) for file in totalFiles])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, after the processing is done, you will get a NumPy array something like the below shape:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Final shape of data : (256, 256, 2000)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;From the above snippet, we can observe 2000 samples of MRI slices aligned across third dimension axis. We are only working w.r.t 2D slices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generating Noisy Data:&lt;/strong&gt; - Now, we have noise free images and we need noisy images to train our model w.r.t ground truths. For this, I am using sklearn random_noise generator to generate the noise on each image. The noise generated on each slice is based on the Gaussian noise considering the local variance for each data sample.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from skimage.util import random_noise

print('____Generating noisy data______')
noisyData= np.zeros(totalData.shape)
for img in range(samplesCount):
    noisy= random_noise(totalData[:,:,img],mode='localvar' ,seed=None,clip=True)
    noisyData[:,:,img] = noisy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagrpp5y9jpb64s1oxyhy.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagrpp5y9jpb64s1oxyhy.PNG" alt="generated_noise_01" width="594" height="310"&gt;&lt;/a&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvb2293rrzf9lpl4x6pc.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvb2293rrzf9lpl4x6pc.PNG" alt="generated_noise_02" width="569" height="308"&gt;&lt;/a&gt;&lt;br&gt;
After generating noisy data, now we have noisy samples w.r.t ground truths. We can observe from the above noisy images that most of the brains internal structures are distorted. Now we use a simple convolution autoencoder model built on top of TensorFlow to remove the noise from our data reconstructs the image with better internal structures.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Noisy samples data shape : (256, 256, 2000) #containing noise&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Ground truth data shape : (256, 256, 200)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;One last step before model training is we have to structure our data with standard representation &lt;code&gt;(batch_size, lenght, width, height)&lt;/code&gt;. For that, we expand &lt;strong&gt;totalData&lt;/strong&gt; and &lt;strong&gt;noisyData&lt;/strong&gt; with 4th dimension to train and roll the third axis to starting index as shown below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;totalData = np.rollaxis(totalData, -1)
totalData = np.expand_dims(totalData, axis=-1)
noisyData = np.rollaxis(noisyData, -1)
noisyData= np.expand_dims(noisyData, axis=-1)

X_train, X_test, y_train, y_test = train_test_split(noisyData, totalData , test_size=0.2, random_state=42)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;u&gt;Note&lt;/u&gt; You can also consider converting numpy arrays to tensors and use the advantage of tensorflow Dataloader class.&lt;br&gt;
For simple understandinf i am only considering only numpy arrays.&lt;/p&gt;

&lt;p&gt;After spliting the data shapes are as follows:&lt;br&gt;
X_train : (1600, 256, 256, 1)&lt;br&gt;
y_train : (1600, 256, 256, 1)&lt;br&gt;
X_test  : (400 , 256, 256, 1)&lt;br&gt;
X_test  : (400 , 256, 256, 1)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model building and training&lt;/strong&gt;&lt;br&gt;
Now we have simple convolutional autoencode model as shown below to train and predict our results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import tensorflow as tf
import keras
import keras.layers as layers
import keras.models as models
from keras.initializers import orthogonal
from tensorflow.keras.optimizers import Adam

def ConvolutionLayer(x, filters, kernel, strides, padding, block_id, kernel_init=orthogonal()):
    prefix = f'block_{block_id}_'

    x = layers.Conv2D(filters, kernel_size=kernel, strides=strides, padding=padding,
                      kernel_initializer=kernel_init, name=prefix+'conv')(x)

    x = layers.LeakyReLU(name=prefix+'lrelu')(x)
    x = layers.Dropout(0.2, name=prefix+'drop')((x))
    x = layers.BatchNormalization(name=prefix+'conv_bn')(x)
    return x

def DeconvolutionLayer(x, filters, kernel, strides, padding, block_id, kernel_init=orthogonal()):
    prefix = f'block_{block_id}_'

    x = layers.Conv2DTranspose(filters, kernel_size=kernel, strides=strides, padding=padding,
                               kernel_initializer=kernel_init, name=prefix+'de-conv')(x)

    x = layers.LeakyReLU(name=prefix+'lrelu')(x)
    x = layers.Dropout(0.2, name=prefix+'drop')((x))
    x = layers.BatchNormalization(name=prefix+'conv_bn')(x)
    return x


# Convolutional Autoencoder with skip connections
def noiseModel(input_shape):
    inputs = layers.Input(shape=input_shape)

    # 256 x 256
    conv1 = ConvolutionLayer(inputs, 64, 3, strides=2, padding='same', block_id=1)

    conv2 = ConvolutionLayer(conv1, 128, 5, strides=2, padding='same', block_id=2)

    # 64 x 64
    conv3 = ConvolutionLayer(conv2, 256, 3, strides=2, padding='same', block_id=3)

    # 16 x 16
    deconv1 = DeconvolutionLayer(conv3, 128, 3, strides=2, padding='same', block_id=4)

    # 64 x 64
    deconv2 = DeconvolutionLayer(deconv1, 64, 3, strides=2, padding='same', block_id=5)

    # 256 x 256
    deconv3 = DeconvolutionLayer(deconv2, 1, 3, strides=2, padding='same', block_id=6)

    return models.Model(inputs=inputs, outputs=deconv3)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the above code each &lt;strong&gt;ConvolutionLayer&lt;/strong&gt; and &lt;strong&gt;DeconvolutionLayer&lt;/strong&gt; block contains sequential operation of convolution/convolution transpose, followed by leakyRelu(activation function), dropout and batchnormalization layers.&lt;br&gt;
Our convolutional autoencoder model consists of six blocks, first three blocks is the &lt;strong&gt;_encoder network _&lt;/strong&gt;part where they perform the convolution operations to generate a latent feature map of the noisy data, then the latent feature map is passed to &lt;strong&gt;_decoder _&lt;/strong&gt;for generating a noise free image.&lt;/p&gt;

&lt;p&gt;Further more detailed information on the model development and parametric optimization can be discussed in the next post.&lt;/p&gt;

&lt;p&gt;Now we have our model blocks &lt;strong&gt;ConvolutionLayer&lt;/strong&gt; and &lt;strong&gt;DeconvolutionLayer&lt;/strong&gt; which will support the model generation &lt;strong&gt;&lt;u&gt;noiseModel&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, we have to define an optmizer, metric and the loss functions that is required for our model training for updating the weights and bias.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;input_shape = (256, 256)    # shape of the sample
model = noiseModel((*input_shape, 1))
model_optimizer = Adam(learning_rate=0.002)

def SSIMMeasure(y_true, y_pred):
    return tf.reduce_mean(tf.image.ssim(y_true, y_pred, 1.0))

def SSIMLoss(y_true, y_pred):
    return 1 - tf.reduce_mean(tf.image.ssim(y_true, y_pred, 1.0))

model.compile(optimizer=model_optimizer, loss=SSIMLoss, metrics=[SSIMMeasure])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are good to call the training method to train our model.&lt;br&gt;
Let us view the summary of our simple convolutional autoencoder  model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(model.summary())
Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, 256, 256, 1)]     0         

 block_1_conv (Conv2D)       (None, 128, 128, 64)      640       

 block_1_lrelu (LeakyReLU)   (None, 128, 128, 64)      0         

 block_1_drop (Dropout)      (None, 128, 128, 64)      0         

 block_1_conv_bn (BatchNorma  (None, 128, 128, 64)     256       
 lization)                                                       

 block_2_conv (Conv2D)       (None, 64, 64, 128)       204928    

 block_2_lrelu (LeakyReLU)   (None, 64, 64, 128)       0         

 block_2_drop (Dropout)      (None, 64, 64, 128)       0         

 block_2_conv_bn (BatchNorma  (None, 64, 64, 128)      512       
 lization)                                                       

 block_3_conv (Conv2D)       (None, 32, 32, 256)       295168    

 block_3_lrelu (LeakyReLU)   (None, 32, 32, 256)       0         

 block_3_drop (Dropout)      (None, 32, 32, 256)       0         

 block_3_conv_bn (BatchNorma  (None, 32, 32, 256)      1024      
 lization)                                                       

 block_4_de-conv (Conv2DTran  (None, 64, 64, 128)      295040    
 spose)                                                          

 block_4_lrelu (LeakyReLU)   (None, 64, 64, 128)       0         

 block_4_drop (Dropout)      (None, 64, 64, 128)       0         

 block_4_conv_bn (BatchNorma  (None, 64, 64, 128)      512       
 lization)                                                       

 block_5_de-conv (Conv2DTran  (None, 128, 128, 64)     73792     
 spose)                                                          

 block_5_lrelu (LeakyReLU)   (None, 128, 128, 64)      0         

 block_5_drop (Dropout)      (None, 128, 128, 64)      0         

 block_5_conv_bn (BatchNorma  (None, 128, 128, 64)     256       
 lization)                                                       

 block_6_de-conv (Conv2DTran  (None, 256, 256, 1)      577       
 spose)                                                          

 block_6_lrelu (LeakyReLU)   (None, 256, 256, 1)       0         

 block_6_drop (Dropout)      (None, 256, 256, 1)       0         

 block_6_conv_bn (BatchNorma  (None, 256, 256, 1)      4         
 lization)                                                       

=================================================================
Total params: 872,709
Trainable params: 871,427
Non-trainable params: 1,282
_________________________________________________________________
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the above model summary you can observe that we have around 0.9 million trainable parameters and very few non trainable parameters. Adding more layers will result in increase of trainable parameters. &lt;/p&gt;

&lt;p&gt;For training we have to define the batch size and epochs aswell, and also we log the information into tensorboard and csv logger so that the data can be analysed lateron. For this i have the following training loop as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Path_MODELSAVE = 'saved_models'
Path_LOGS = 'logs'
for i in [Path_MODELSAVE, Path_LOGS]:
    if i not in os.listdir(os.getcwd()):
        os.mkdir(i)

epochs = 100
batch_size = 10
saved_weight = os.path.join(Path_MODELSAVE, 'dataweights.{epoch:02d}-{SSIMMeasure:.2f}.hdf5')

model_checkpoint = keras.callbacks.ModelCheckpoint(saved_weight,
                                        monitor = 'val_SSIMMeasure',
                                        verbose=1,
                                        save_best_only=False,
                                        save_weights_only=True,
                                        mode='auto', save_freq = 'epoch', period = 10)

tensorboard = keras.callbacks.TensorBoard(log_dir=Path_LOGS,
                                            histogram_freq=0,
                                            write_graph=True,
                                            write_images=True)

csv_logger = keras.callbacks.CSVLogger(f'{Path_LOGS}/keras_log.csv' ,append=True)

model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size, 
            validation_data=(X_test, y_test), 
            callbacks=[model_checkpoint, tensorboard, csv_logger])

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the above sniplet &lt;strong&gt;model_checkpoint&lt;/strong&gt; saves the model in our local system over a period of 10 epochs.&lt;br&gt;
&lt;strong&gt;tensorboard&lt;/strong&gt; will log the tensorboard events to Path_LOGS directory and &lt;strong&gt;csv_logger&lt;/strong&gt; will log &lt;strong&gt;loss&lt;/strong&gt;, &lt;strong&gt;SSIMMeasure&lt;/strong&gt; for both training and validation into a .csv file for each epoc.&lt;/p&gt;

&lt;p&gt;model.fit() function will perform all the training process considering the batch_size and callbacks as defined above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prediction and model evaluation&lt;/strong&gt;&lt;br&gt;
Once the data is trained, you can perform prediction on any other samples for model evaluation by maintaining the batch size of the trained model.&lt;br&gt;
Also please note that you have to perform the same preprocessing steps on the samples that are passed for model prediction. In our case we have to perform normalization before passing a sample for prediction.&lt;/p&gt;

&lt;p&gt;Here are few predictions from the model trained with 130 epochs.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakf30hi1rongzvoakrdr.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakf30hi1rongzvoakrdr.PNG" alt="model_prediction_1" width="681" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1d27s4oqqgmimwbyjhpq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1d27s4oqqgmimwbyjhpq.PNG" alt="model_prediction_2" width="684" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From above results we can observe that our model could able to remove the noise and also generates few structures that are not exactly visible in our noisy data. It all happened by training upto few 130 epochs with batch_size equal to 10 and model containing only 6 blocks.&lt;/p&gt;

&lt;p&gt;If you want to see better results, i suggest to train your model with more number of epochs with a greater batch_size by inspecting whether your  model is overfitting or underfitting.&lt;/p&gt;

&lt;p&gt;Below you can observe the model accuracy and loss over training and validation.&lt;/p&gt;

&lt;p&gt;Training results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgudcro0v02tfnnkavker.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgudcro0v02tfnnkavker.PNG" alt=" " width="800" height="326"&gt;&lt;/a&gt;&lt;br&gt;
Validation results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s2stlk1iyyx34okqobj.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s2stlk1iyyx34okqobj.PNG" alt=" " width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any questions regarding the post, please comment. I will try to answer asap.&lt;/p&gt;

&lt;p&gt;If this article helped you, you can support my work here ☕&lt;/p&gt;

&lt;p&gt;👉 Buy me a coffee: &lt;a href="https://buymeacoffee.com/anupoju" rel="noopener noreferrer"&gt;https://buymeacoffee.com/anupoju&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>medicalimaging</category>
      <category>imageprocessing</category>
      <category>neuralnetworks</category>
    </item>
    <item>
      <title>MRI Data Processing with Python</title>
      <dc:creator>Narendra kumar A</dc:creator>
      <pubDate>Mon, 03 Aug 2020 17:04:26 +0000</pubDate>
      <link>https://dev.to/narendraanupoju/mri-data-processing-with-python-1jgg</link>
      <guid>https://dev.to/narendraanupoju/mri-data-processing-with-python-1jgg</guid>
      <description>&lt;p&gt;Understanding and processing MRI data can be tricky and confusing. In this blog, I will provide a basic introduction on how to load and process MRI data using the most important Python libraries.&lt;/p&gt;

&lt;p&gt;MRI data mainly consists of three pieces of information.&lt;br&gt;
-&amp;gt; Header (metadata)&lt;br&gt;
-&amp;gt; Affine (Represents the affine transformation)&lt;br&gt;
-&amp;gt; Image data (N-D Array)&lt;/p&gt;

&lt;p&gt;Most of the medical imaging data will be in the Nifti (.nii) and Dicom (.dcm) formats. We will be discussing Nifti format data, dicom format will be discussed in further posts.&lt;/p&gt;

&lt;p&gt;Here We use Numpy, Nibabel libraries to load and process data and matplotlib for visualization.&lt;/p&gt;

&lt;p&gt;If you don’t have these libraries installed, you can install using pip package manager in your python environment entering the following commands:&lt;br&gt;
&lt;br&gt;
pip install numpy&lt;br&gt;
pip install niabel&lt;br&gt;
pip install matplotlib&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Importing modules&lt;/b&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;nibabel&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;nib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;b&gt;Loading data&lt;/b&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path to Nifti format data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;#(.nii or .nii.gz)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv8831ys5uw16zys7vnbw.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv8831ys5uw16zys7vnbw.PNG" alt="Alt Text" width="664" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here &lt;b&gt;data&lt;/b&gt; is a data object containing header, affine, and image data with all required attributes for further processing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;image_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_fdata&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;b&gt;get_fdata()&lt;/b&gt; function returns a floating-point NumPy matrix containing image pixel data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;image_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(256, 256, 128)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;output shape represents that &lt;b&gt;image_data&lt;/b&gt; is a 3d volume, z-axis(128) represents the number of slices in MRI data&lt;/p&gt;

&lt;p&gt;To check the &lt;b&gt;affine coordinates&lt;/b&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;affine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output an array relating array coordinates from the image data array to coordinates in some RAS+ world coordinate system &lt;br&gt;
RAS (Right, Anterior, Superior)&lt;br&gt;
For a detailed understanding of coordinate systems of neuroimaging go through the following link:&lt;br&gt;
&lt;a href="https://nipy.org/nibabel/coordinate_systems.html" rel="noopener noreferrer"&gt;https://nipy.org/nibabel/coordinate_systems.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To check the &lt;b&gt;header&lt;/b&gt; info of the data object&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A detailed understanding of metadata and affine transformations will be discussed in a next post.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Visualizing&lt;/b&gt; MRI slices&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_data&lt;/span&gt;&lt;span class="p"&gt;[:,:,&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gray&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcp8c8guzaqwturp0reu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcp8c8guzaqwturp0reu5.png" alt="Alt Text" width="262" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can change the integer value in the above code snippet with in a range of (0-127) to visualize different slices.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_data&lt;/span&gt;&lt;span class="p"&gt;[:,:,&lt;/span&gt;&lt;span class="mi"&gt;116&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gray&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visualize 116th slice&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwcccwj1aybcrvuosvt99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwcccwj1aybcrvuosvt99.png" alt="Alt Text" width="262" height="252"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,:,:],&lt;/span&gt; &lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gray&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visualize 120th slice w.r.to x-axis&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fli3r50xfjl1ov2r51i3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fli3r50xfjl1ov2r51i3i.png" alt="Alt Text" width="149" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;matplotlib.image.AxesImage at 0x1f6cb300148&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For a detailed understanding on Indexing using NumPy go through the following link &lt;br&gt;
&lt;a href="https://numpy.org/doc/stable/user/basics.indexing.html" rel="noopener noreferrer"&gt;https://numpy.org/doc/stable/user/basics.indexing.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In further posts, I will be discussing how to prepare MRI data to apply machine learning algorithms, noise removal techniques, and different pre-processing and post-processing techniques.&lt;/p&gt;




&lt;p&gt;If this article helped you, you can support my work here ☕&lt;br&gt;&lt;br&gt;
👉 Buy me a coffee: &lt;a href="https://buymeacoffee.com/anupoju" rel="noopener noreferrer"&gt;https://buymeacoffee.com/anupoju&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>medicalimaging</category>
      <category>imageprocessing</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
