<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Ramazan Olmez on Medium]]></title>
        <description><![CDATA[Stories by Ramazan Olmez on Medium]]></description>
        <link>https://medium.com/@ramazanolmeez?source=rss-b005bac7906e------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*7tW6KlpcfptthWv7mYB0dw.jpeg</url>
            <title>Stories by Ramazan Olmez on Medium</title>
            <link>https://medium.com/@ramazanolmeez?source=rss-b005bac7906e------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 08:32:19 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@ramazanolmeez/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[End-to-End Machine Learning Project: Churn Prediction]]></title>
            <link>https://medium.com/@ramazanolmeez/end-to-end-machine-learning-project-churn-prediction-e9c4d0322ac9?source=rss-b005bac7906e------2</link>
            <guid isPermaLink="false">https://medium.com/p/e9c4d0322ac9</guid>
            <category><![CDATA[classification]]></category>
            <category><![CDATA[catboost]]></category>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[fastapi]]></category>
            <category><![CDATA[streamlit]]></category>
            <dc:creator><![CDATA[Ramazan Olmez]]></dc:creator>
            <pubDate>Thu, 22 Feb 2024 18:45:53 GMT</pubDate>
            <atom:updated>2024-02-22T19:40:08.698Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/697/1*P2Jnnq8Y5yMuD2NcsnJVdg.png" /></figure><p>The main objective of this article is to develop an end-to-end machine learning project. For a model to be truly useful, it needs to be stored and distributed. Within the scope of this article, I aim to develop a project based on a real-world scenario.</p><p>You can access the project on GitHub. You can also access the EDA and model development section on Kaggle.</p><ul><li><a href="https://github.com/rolmez/Customer-Churn-Project">GitHub</a></li><li><a href="https://www.kaggle.com/code/rolmez/telco-customer-churn-eda">EDA Kaggle</a></li><li><a href="https://www.kaggle.com/code/rolmez/telco-catboost-xgboost">Model Development Kaggle</a></li></ul><p>The following tools will be used throughout the project.</p><ul><li>Catboost</li><li>Streamlit</li><li>FastAPI</li><li>Docker</li></ul><p><strong>Table of Contents</strong> <br>· <a href="#766a">1. Aim of the Project and Data Set</a><br> ∘ <a href="#7a7c">Data Set</a><br>· <a href="#1916">2. Data Preprocessing and Model Development</a><br>· <a href="#1179">3. Interface (Streamlit)</a><br>· <a href="#3d9d">4. API (FastAPI)</a><br>· <a href="#9a41">5. Automation (Docker)</a><br>· <a href="#d24e">6. Conclusion</a></p><h3>1. Aim of the Project and Data Set</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/438/1*OwYuoyFFQn5cmAJAl8dP-g.png" /><figcaption>Aim of the project</figcaption></figure><h4><strong>Data Set</strong></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/830/1*2se448p2nO8Sqcwq_KzrTA.png" /><figcaption>Dataset</figcaption></figure><p>You can access the customer data to be used in the project from <a href="https://www.kaggle.com/datasets/blastchar/telco-customer-churn">Kaggle</a>. This dataset consists of 7043 customers with 21 columns (features). It contains customer account information, demographic information, and registered services. The target variable (Churn) provides information on whether the customer has churned.<br>You can also access the extended and updated dataset version from this <a href="https://community.ibm.com/community/user/businessanalytics/blogs/steven-macko/2019/07/11/telco-customer-churn-1113">link</a>.</p><h3>2. Data Preprocessing and Model Development</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*UGAMMi67iEfMLE9vvU804w.png" /><figcaption><a href="https://catboost.ai/">Source</a></figcaption></figure><p>There are quite a lot of categorical variables in the dataset. By encoding these variables into numerical form, we can also use different models with different preprocessing techniques. But in this study, we will use the Catboost algorithm, which has proven its success with categorical variables. If you want to improve performance in model development, you can try various tools that provide hyperparameter optimization such as Optuna, etc.</p><p>We can start data preprocessing and model development by creating a Python file called train_model.py</p><pre>################################################## Import Libraries ##################################################<br><br>import numpy as np<br>import pandas as pd<br>import os<br><br>from sklearn import metrics<br>from sklearn.model_selection import train_test_split, StratifiedShuffleSplit<br>from sklearn.metrics import (<br>    accuracy_score, classification_report, recall_score, confusion_matrix,<br>    roc_auc_score, precision_score, f1_score, roc_curve, auc<br>)<br>from sklearn.preprocessing import OrdinalEncoder<br><br>from catboost import CatBoostClassifier, Pool<br><br>################################################## Data Loading and Editing ##################################################<br><br>data_path = &quot;../data/WA_Fn-UseC_-Telco-Customer-Churn.csv&quot;<br>df = pd.read_csv(data_path)<br><br># Convert TotalCharges to numeric, filling NaN values<br>df[&#39;TotalCharges&#39;] = pd.to_numeric(df[&#39;TotalCharges&#39;], errors=&#39;coerce&#39;)<br>df[&#39;TotalCharges&#39;].fillna(df[&#39;tenure&#39;] * df[&#39;MonthlyCharges&#39;], inplace=True)<br><br># Convert SeniorCitizen to object<br>df[&#39;SeniorCitizen&#39;] = df[&#39;SeniorCitizen&#39;].astype(object)<br><br># Replace &#39;No phone service&#39; and &#39;No internet service&#39; with &#39;No&#39; for certain columns<br>df[&#39;MultipleLines&#39;] = df[&#39;MultipleLines&#39;].replace(&#39;No phone service&#39;, &#39;No&#39;)<br>columns_to_replace = [&#39;OnlineSecurity&#39;, &#39;OnlineBackup&#39;, &#39;DeviceProtection&#39;, &#39;TechSupport&#39;, &#39;StreamingTV&#39;, &#39;StreamingMovies&#39;]<br>for column in columns_to_replace:<br>    df[column] = df[column].replace(&#39;No internet service&#39;, &#39;No&#39;)<br><br># Convert &#39;Churn&#39; categorical variable to numeric<br>df[&#39;Churn&#39;] = df[&#39;Churn&#39;].replace({&#39;No&#39;: 0, &#39;Yes&#39;: 1})<br><br>################################################## StratifiedShuffleSplit ##################################################<br><br># Create the StratifiedShuffleSplit object<br>strat_split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=64)<br><br>train_index, test_index = next(strat_split.split(df, df[&quot;Churn&quot;]))<br><br># Create train and test sets<br>strat_train_set = df.loc[train_index]<br>strat_test_set = df.loc[test_index]<br><br>X_train = strat_train_set.drop(&quot;Churn&quot;, axis=1)<br>y_train = strat_train_set[&quot;Churn&quot;].copy()<br><br>X_test = strat_test_set.drop(&quot;Churn&quot;, axis=1)<br>y_test = strat_test_set[&quot;Churn&quot;].copy()<br><br>################################################## CATBOOST ##################################################<br><br># Identify categorical columns<br>categorical_columns = df.select_dtypes(include=[&#39;object&#39;]).columns.tolist()<br><br># Initialize and fit CatBoostClassifier<br>cat_model = CatBoostClassifier(verbose=False, random_state=0, scale_pos_weight=3)<br>cat_model.fit(X_train, y_train, cat_features=categorical_columns, eval_set=(X_test, y_test))<br><br># Predict on test set<br>y_pred = cat_model.predict(X_test)<br><br># Calculate evaluation metrics<br>accuracy, recall, roc_auc, precision = [round(metric(y_test, y_pred), 4) for metric in [accuracy_score, recall_score, roc_auc_score, precision_score]]<br><br># Create a DataFrame to store results<br>model_names = [&#39;CatBoost_Model&#39;]<br>result = pd.DataFrame({&#39;Accuracy&#39;: accuracy, &#39;Recall&#39;: recall, &#39;Roc_Auc&#39;: roc_auc, &#39;Precision&#39;: precision}, index=model_names)<br><br># Print results<br>print(result)<br><br># Save the model in the &#39;model&#39; directory<br>model_dir = &quot;../model&quot;<br>if not os.path.exists(model_dir):<br>    os.makedirs(model_dir)<br><br>model_path = os.path.join(model_dir, &quot;catboost_model.cbm&quot;)<br>cat_model.save_model(model_path)</pre><p><strong>Step 1: Importing Libraries</strong><br>We start by importing essential libraries required for data processing, model training, and evaluation. These include libraries such as NumPy and Pandas for data manipulation, scikit-learn for machine learning functionalities, and CatBoost for building our predictive model.</p><p><strong>Step 2: Data Loading and Editing</strong><br>Next, we load the dataset from a specified path using Pandas. We perform some initial data editing steps to ensure data consistency and readiness for modeling. This involves converting certain columns to numeric data types, handling missing values, and encoding categorical variables.</p><p><strong>Step 3: Stratified Splitting</strong><br>The unbalanced nature of the dataset was observed in the EDA study. To ensure an unbiased distribution of classes in our train-test split, we employ StratifiedShuffleSplit from scikit-learn. This method preserves the proportion of classes in both training and testing sets, critical for reliable model evaluation.</p><p><strong>Step 4: Model Training with CatBoost</strong><br>Training our predictive model using CatBoost. We initialize a CatBoostClassifier with appropriate parameters, including verbosity and random state. We fit the model to the training data, specifying categorical features to ensure proper handling of categorical variables. I would like to emphasize that the model training phase has not been elaborated and it may be good to revisit this phase in your work.</p><p><strong>Step 5: Model Evaluation</strong><br>Once the model is trained, we evaluate its performance using various metrics such as accuracy, recall, ROC AUC score, and precision. These metrics provide insights into how well our model predicts customer churn.</p><p><em>After developing the model with your data, we need to save the model for later use.</em></p><p>After analyzing the data and building the machine learning model, interactive interfaces are required to increase the usability of this model. Streamlit is a good alternative for this task.</p><h3>3. Interface (Streamlit)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Qq2TRBTJyPNaq_blmvWWZA.png" /><figcaption><a href="https://streamlit.io/">Source</a></figcaption></figure><p><a href="https://streamlit.io/">Streamlit</a> is an open-source application framework for machine learning and data science teams. It is often used in the prototyping phase of projects as it provides a fast interface. It is easy to use and has a strong community.</p><p>We started our project by creating a python file named streamlit-app.py to create a fast interface. The following code allows us to create an interactive interface using Streamlit and evaluate the churn probability of customers using the CatBoost model. It also allows us to understand and visualize the model’s decisions using SHAP values.</p><p>At this point in the project, I think it might be good to briefly mention <strong>SHAP</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JBu7nuqdwEo0pVm1mfQuBA.png" /><figcaption><a href="https://shap.readthedocs.io/en/latest/index.html">Source</a></figcaption></figure><p><a href="https://shap.readthedocs.io/en/latest/index.html"><strong>SHAP (SHapley Additive exPlanations)</strong></a> is one of the explainable artificial intelligence methods developed with a game theoretic approach. It allows us to comment on the model, making it less of a black box. It tells us to what extent each attribute used in the model affects the model outcome.</p><p>Let’s continue creating the streamlit-app.py file.</p><pre>import shap<br>import pandas as pd<br>import numpy as np<br>import streamlit as st<br>from matplotlib import pyplot as plt<br>from pyarrow import parquet as pq<br>from catboost import CatBoostClassifier, Pool<br>import joblib<br><br># Path of the trained model and data<br>MODEL_PATH = &quot;../model/cat_model.cbm&quot; <br>DATA_PATH = &quot;../data/churn_data_regulated.parquet&quot;<br><br>st.set_page_config(page_title=&quot;Churn Project&quot;)<br><br>@st.cache_resource<br>def load_data():<br>    data = pd.read_parquet(DATA_PATH)<br>    return data<br><br>def load_x_y(file_path):<br>    data = joblib.load(file_path)<br>    data.reset_index(drop=True, inplace=True)<br>    return data<br><br>def load_model():<br>    model = CatBoostClassifier()<br>    model.load_model(MODEL_PATH)<br>    return model<br><br>def calculate_shap(model, X_train, X_test):<br>    # Calculate SHAP values<br>    explainer = shap.TreeExplainer(model)<br>    shap_values_cat_train = explainer.shap_values(X_train)<br>    shap_values_cat_test = explainer.shap_values(X_test)<br>    return explainer, shap_values_cat_train, shap_values_cat_test<br><br>def plot_shap_values(model, explainer, shap_values_cat_train, shap_values_cat_test, customer_id, X_test, X_train):<br>    # Visualize SHAP values for a specific customer<br>    customer_index = X_test[X_test[&#39;customerID&#39;] == customer_id].index[0]<br>    fig, ax_2 = plt.subplots(figsize=(6,6), dpi=200)<br>    shap.decision_plot(explainer.expected_value, shap_values_cat_test[customer_index], X_test[X_test[&#39;customerID&#39;] == customer_id], link=&quot;logit&quot;)<br>    st.pyplot(fig)<br>    plt.close()<br><br>def display_shap_summary(shap_values_cat_train, X_train):<br>    # Create the plot summarizing the SHAP values<br>    shap.summary_plot(shap_values_cat_train, X_train, plot_type=&quot;bar&quot;, plot_size=(12,12))<br>    summary_fig, _ = plt.gcf(), plt.gca()<br>    st.pyplot(summary_fig)<br>    plt.close()<br><br>def display_shap_waterfall_plot(explainer, expected_value, shap_values, feature_names, max_display=20):<br>    # Create SHAP waterfall drawing<br>    fig, ax = plt.subplots(figsize=(6, 6), dpi=150)<br>    shap.plots._waterfall.waterfall_legacy(expected_value, shap_values, feature_names=feature_names, max_display=max_display, show=False)<br>    st.pyplot(fig)<br>    plt.close()<br><br>def summary(model, data, X_train, X_test):<br>    # Calculate SHAP values<br>    explainer, shap_values_cat_train, shap_values_cat_test = calculate_shap(model, X_train, X_test)<br><br>    # Summarize and visualize SHAP values<br>    display_shap_summary(shap_values_cat_train, X_train)<br><br>def plot_shap(model, data, customer_id, X_train, X_test):<br>    # Calculate SHAP values<br>    explainer, shap_values_cat_train, shap_values_cat_test = calculate_shap(model, X_train, X_test)<br>    <br>    # Visualize SHAP values<br>    plot_shap_values(model, explainer, shap_values_cat_train, shap_values_cat_test, customer_id, X_test, X_train)<br><br>    # Waterfall<br>    customer_index = X_test[X_test[&#39;customerID&#39;] == customer_id].index[0]<br>    display_shap_waterfall_plot(explainer, explainer.expected_value, shap_values_cat_test[customer_index], feature_names=X_test.columns, max_display=20)<br><br>st.title(&quot;Telco Customer Churn Project&quot;)<br><br>def main():<br>    model = load_model()<br>    data = load_data()<br><br>    X_train = load_x_y(&quot;../data/X_train.pkl&quot;)<br>    X_test = load_x_y(&quot;../data/X_test.pkl&quot;)<br>    y_train = load_x_y(&quot;../data/y_train.pkl&quot;)<br>    y_test = load_x_y(&quot;../data/y_test.pkl&quot;)<br><br>    max_tenure = data[&#39;tenure&#39;].max()<br>    max_monthly_charges = data[&#39;MonthlyCharges&#39;].max()<br>    max_total_charges = data[&#39;TotalCharges&#39;].max()<br><br>    # Radio buttons for options<br>    election = st.radio(&quot;Make Your Choice:&quot;, (&quot;Feature Importance&quot;, &quot;User-based SHAP&quot;, &quot;Calculate the probability of CHURN&quot;))<br>    available_customer_ids = X_test[&#39;customerID&#39;].tolist()<br>    <br>    # If User-based SHAP option is selected<br>    if election == &quot;User-based SHAP&quot;:<br>        # Customer ID text input<br>        customer_id = st.selectbox(&quot;Choose the Customer&quot;, available_customer_ids)<br>        customer_index = X_test[X_test[&#39;customerID&#39;] == customer_id].index[0]<br>        st.write(f&#39;Customer {customer_id}: Actual value for the Customer Churn : {y_test.iloc[customer_index]}&#39;)<br>        y_pred = model.predict(X_test)<br>        st.write(f&quot;Customer {customer_id}: CatBoost Model&#39;s prediction for the Customer Churn : {y_pred[customer_index]}&quot;)<br>        plot_shap(model, data, customer_id, X_train=X_train, X_test=X_test)<br>    <br>    # If Feature Importance is selected<br>    elif election == &quot;Feature Importance&quot;:<br>        summary(model, data, X_train=X_train, X_test=X_test)<br><br>    # If Calculate CHURN Probability option is selected<br>    elif election == &quot;Calculate the probability of CHURN&quot;:<br>        # Retrieving data from the user<br>        customerID = &quot;6464-UIAEA&quot;<br>        gender = st.selectbox(&quot;Gender:&quot;, (&quot;Female&quot;, &quot;Male&quot;))<br>        senior_citizen = st.number_input(&quot;SeniorCitizen (0: No, 1: Yes)&quot;, min_value=0, max_value=1, step=1)<br>        partner = st.selectbox(&quot;Partner:&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        dependents = st.selectbox(&quot;Dependents:&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        tenure = st.number_input(&quot;Tenure:&quot;, min_value=0, max_value=max_tenure, step=1)<br>        phone_service = st.selectbox(&quot;PhoneService:&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        multiple_lines = st.selectbox(&quot;MultipleLines:&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        internet_service = st.selectbox(&quot;InternetService:&quot;, (&quot;No&quot;, &quot;DSL&quot;, &quot;Fiber optic&quot;))<br>        online_security = st.selectbox(&quot;OnlineSecurity:&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        online_backup = st.selectbox(&quot;OnlineBackup:&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        device_protection = st.selectbox(&quot;DeviceProtection:&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        tech_support = st.selectbox(&quot;TechSupport:&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        streaming_tv = st.selectbox(&quot;StreamingTV:&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        streaming_movies = st.selectbox(&quot;StreamingMovies:&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        contract = st.selectbox(&quot;Contract:&quot;, (&quot;Month-to-month&quot;, &quot;One year&quot;, &quot;Two year&quot;))<br>        paperless_billing = st.selectbox(&quot;PaperlessBilling&quot;, (&quot;No&quot;, &quot;Yes&quot;))<br>        payment_method = st.selectbox(&quot;PaymentMethod:&quot;, (&quot;Electronic check&quot;, &quot;Mailed check&quot;, &quot;Bank transfer (automatic)&quot;, &quot;Credit card (automatic)&quot;))<br>        monthly_charges = st.number_input(&quot;Monthly Charges&quot;, min_value=0.0, max_value=max_monthly_charges, step=0.01)<br>        total_charges = st.number_input(&quot;Total Charges&quot;, min_value=0.0, max_value=max_total_charges, step=0.01)<br>        <br>        # Confirmation button<br>        confirmation_button = st.button(&quot;Confirm&quot;)<br><br>        # When the confirmation button is clicked<br>        if confirmation_button:<br>            # Convert user-entered data into a data frame<br>            new_customer_data = pd.DataFrame({<br>                &quot;customerID&quot;: [customerID],<br>                &quot;gender&quot;: [gender],<br>                &quot;SeniorCitizen&quot;: [senior_citizen],<br>                &quot;Partner&quot;: [partner],<br>                &quot;Dependents&quot;: [dependents],<br>                &quot;tenure&quot;: [tenure],<br>                &quot;PhoneService&quot;: [phone_service],<br>                &quot;MultipleLines&quot;: [multiple_lines],<br>                &quot;InternetService&quot;: [internet_service],<br>                &quot;OnlineSecurity&quot;: [online_security],<br>                &quot;OnlineBackup&quot;: [online_backup],<br>                &quot;DeviceProtection&quot;: [device_protection],<br>                &quot;TechSupport&quot;: [tech_support],<br>                &quot;StreamingTV&quot;: [streaming_tv],<br>                &quot;StreamingMovies&quot;: [streaming_movies],<br>                &quot;Contract&quot;: [contract],<br>                &quot;PaperlessBilling&quot;: [paperless_billing],<br>                &quot;PaymentMethod&quot;: [payment_method],<br>                &quot;MonthlyCharges&quot;: [monthly_charges],<br>                &quot;TotalCharges&quot;: [total_charges]<br>            })<br><br>            # Predict churn probability using the model<br>            churn_probability = model.predict_proba(new_customer_data)[:, 1]<br><br>            # Format churn probability<br>            formatted_churn_probability = &quot;{:.2%}&quot;.format(churn_probability.item())<br><br>            big_text = f&quot;&lt;h1&gt;Churn Probability: {formatted_churn_probability}&lt;/h1&gt;&quot;<br>            st.markdown(big_text, unsafe_allow_html=True)<br>            st.write(new_customer_data.to_dict())<br><br>if __name__ == &quot;__main__&quot;:<br>    main()</pre><p><strong>Step 1: Setting Up</strong><br>Streamlit app begins by importing necessary libraries, including Streamlit itself, Pandas for data manipulation, CatBoost for loading the trained model, and SHAP for visualizing model explanations.</p><p><strong>Step 2: Data Loading and Model Loading</strong><br>The app loads the preprocessed data and the trained CatBoost model. This ensures that we have the necessary data and model ready for inference.</p><p><strong>Step 3: User Interface Components</strong><br>The app provides a user interface with different options:</p><ul><li>Feature Importance: Allows users to view the summary of feature importance based on SHAP values.</li><li>User-based SHAP: Enables users to select a specific customer and visualize the SHAP values for that customer, helping understand the model’s prediction rationale.</li><li>Calculate the probability of CHURN: Lets users input their data for a hypothetical customer and calculates the probability of churn using the trained model.</li></ul><p><strong>Step 4: Loading and Preparing User Data</strong><br>If the user selects the “Calculate the probability of CHURN” option, the app prompts them to input various customer attributes such as gender, tenure, contract type, etc. Upon confirmation, the app formats this input data into a DataFrame and feeds it into the model to predict the probability of churn for the customer.</p><p><strong>Step 5: Displaying Results</strong><br>Finally, the app presents the results to the user. For the “Calculate the probability of CHURN” option, it displays the churn probability along with the input data in a formatted manner. For other options like “Feature Importance” and “User-based SHAP”, it generates visualizations to help users interpret the model’s behavior.</p><p>You can run this code from the terminal in the folder with the file named streamlit-app.py as follows</p><pre>streamlit run streamlit-app.py</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/580/1*iLo8_u2XWrhSk2vHfND3Lg.png" /><figcaption>Image by author</figcaption></figure><p>We can see the application interface in the window that opens on localhost in the browser. This interface has different options such as the SHAP summary, SHAP data for a specific user, and the calculation of the churn probability of a customer based on new values entered by the user.</p><p><strong>Feature Importance:</strong> We may want to take an overview of which features are decisive in the model’s decision-making process.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LFTILmXY7aNPdnfNhP6Npg.png" /><figcaption>The order of importance of features for the created CatBoost model is as follows</figcaption></figure><p><strong>User-based SHAP:</strong> We may want to know the criteria by which a particular customer’s model result was selected. Let’s take a look at the customer in our test set with customerID <strong>6100-QQQQHEB</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xEmKDImpXWQzOU8Mro02Og.png" /><figcaption>6100-QQQQQQQHEB Customer’s churn values predicted by the model and actual churn values</figcaption></figure><p>It is seen that the customer with customerID <strong>6100-QQQHEB</strong> is Churn according to the data set. Also, the model says that this customer will be Churn according to the training set it is trained. But this information is not enough. We may want to see based on which features it says that the customer will be Churn.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/634/1*1anFXjhSuO5Rg0LaVMs5XQ.png" /><figcaption>Features that influenced the model to make this decision</figcaption></figure><p>The SHAP chart in the photo shows that the customer with ID <strong>6100-QQQQHEB</strong> has a Churn probability of over <strong>80%</strong>. The model makes this decision because the user’s InternetService feature is Fiber Optic, Contract feature is Month-to-month, and PaymentMethod feature is Electronic check. Other features also confirm this decision but are negligible.</p><p>Similar inferences can be seen in another SHAP graph.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/599/1*YfLKuysJNqFMsa2Tjrcr_A.png" /><figcaption>Features that influenced the model to make this decision</figcaption></figure><p><strong>Calculate the probability of CHURN: </strong>Through the model and streamlit interface we have created, we can ask users to give new customer values and calculate the churn probability in line with these values.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MCxHuVwX8MCS-6LRBvnPdw.png" /><figcaption>Calculate the probability of CHURN 1</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KJJ6w1SVCZ4GyM_UdtoKCw.png" /><figcaption>Calculate the probability of CHURN 2</figcaption></figure><p>According to the values entered, the churn probability of the new customer created was <strong>71.33%</strong>.</p><p>Besides an interactive interface, it is vital to quickly and reliably convert the model into an API. API enables the model to be used by a wider audience, integrated with other applications and made easier to use. FastAPI is a good example of all these processes.</p><h3>4. API (FastAPI)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*onAL2ILr6zjIC2lSfzJE6Q.png" /><figcaption><a href="https://fastapi.tiangolo.com/">Source</a></figcaption></figure><p><a href="https://fastapi.tiangolo.com/">FastAPI</a> is a Python web framework for developing fast web applications and APIs. It is especially focused on performance, speed, and security, and is very useful for API development thanks to its asynchronous programming support and Python typing support.</p><p>Within the scope of the project, uvicorn was used to launch the FastAPI application. <a href="https://www.uvicorn.org/">Uvicorn</a> is a server application for Python web servers. It provides a fast installation like FastAPI. It is also very easy to use. Alternatives such as Gunicorn, Hypercorn, and Daphne can be used instead of Uvicorn. Which server to use depends on the requirements and performance expectations of the project.</p><p>To provide a simple API to the project, we created a Python file named fast-api.py in the project folder. The following code allows to create a fast API using uvicorn and FastAPI.</p><p>The API layer is constructed as follows:</p><pre>import uvicorn<br>import pandas as pd<br>from fastapi import FastAPI<br>from catboost import CatBoostClassifier<br><br># Path to the model<br>MODEL_PATH = &quot;../model/cat_model.cbm&quot; <br><br># Function to load the trained model<br>def load_model():<br>    model = CatBoostClassifier()<br>    model.load_model(MODEL_PATH)<br>    return model<br><br># Function to predict churn probability from data in DataFrame format<br>def get_churn_probability(data, model):<br>    # Convert incoming data into a DataFrame<br>    dataframe = pd.DataFrame.from_dict(data, orient=&#39;index&#39;).T<br>    # Make the prediction<br>    churn_probability = model.predict_proba(dataframe)[0][1]<br>    return churn_probability<br><br># Load the model<br>model = load_model()<br><br># Create the FastAPI application<br>app = FastAPI(title=&quot;Churn Prediction API&quot;, version=&quot;1.0&quot;)<br><br>@app.get(&#39;/&#39;)<br>def index():<br>    return {&#39;message&#39;: &#39;CHURN Prediction API&#39;}<br><br># Define the API endpoint<br>@app.post(&#39;/predict/&#39;)<br>def predict_churn(data: dict):<br>    # Get the prediction<br>    churn_probability = get_churn_probability(data, model)<br>    # Return the prediction<br>    return {&#39;Churn Probability&#39;: churn_probability}<br><br># Run the application<br>if __name__ == &#39;__main__&#39;:<br>    uvicorn.run(&quot;fast-api:app&quot;, host=&#39;127.0.0.1&#39;, port=5000)</pre><p><strong>Step 1: Setting Up<br></strong>FastAPI script begins by importing necessary libraries, including FastAPI itself, Pandas for data manipulation, and CatBoost for loading the trained model.</p><p><strong>Step 2: Loading the Model</strong><br>The script defines a function load_model() to load the pre-trained CatBoost model from the specified path.</p><p><strong>Step 3: Predicting Churn Probability</strong><br>Another function get_churn_probability() is defined to predict churn probability from the input data in DataFrame format. This function converts the incoming data dictionary into a DataFrame and then uses the loaded model to predict the churn probability.</p><p><strong>Step 4: Creating FastAPI Application</strong><br>The FastAPI application is created with the title “Churn Prediction API” and version “1.0”.</p><p><strong>Step 5: Defining API Endpoints<br>- </strong>The / endpoint is defined to provide a simple message indicating the availability of the CHURN Prediction API.<br>- The /predict/ endpoint is defined to accept POST requests with data in JSON format. It calls the predict_churn() function, which in turn uses the loaded model to predict churn probability for the provided data.</p><p><strong>Step 6: Running the Application</strong><br>Finally, the application is run using the uvicorn.run() function. It specifies the script file (fast-api) and the FastAPI instance (app), along with host and port configurations.</p><p>You can start the API inside the folder containing thefast-api.pyfile as follows:</p><pre>python fast-api.py</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/647/1*VjSWiQTPWYNf1vQKOc3VLQ.png" /><figcaption>Image by author</figcaption></figure><p>We can see the API by going to the Host given to Uvicorn.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/567/1*FLwvImii3bDrWPv3dt_3kA.png" /><figcaption>localhost</figcaption></figure><p>But to access the API we created, we need to add /docs or /redoc at the end of the extension (http://127.0.0.1:5000/docs).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/889/1*-S6EhWlDocM4Bx6lNep5pg.png" /><figcaption>API in localhost</figcaption></figure><p>The API created allows us to interactively see the churn probability of the customer we will create.</p><p>We can enter the generated customer data by clicking on <em>Try it out</em> under <em>POST </em>-&gt; <em>/predict/</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aWxzpjWPr9gUkmRZzmHxrQ.png" /><figcaption>Execute</figcaption></figure><p>By pressing <em>Execute</em>, we evaluate the churn probability of the customer. If the API returns a successful response, we should see a result like below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/607/1*WisfYkBCPUVMJQbGOwtUqg.png" /><figcaption>API answer</figcaption></figure><p>It is seen that the customer’s Churn probability is <strong>62.8504%</strong>. Using the same customer data, we could also obtain the Churn probability via Streamlit.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/1*NvN3kv4Zvu4jzUrpTZgqeg.png" /></figure><p>Now that we have successfully built the Streamlit interface and API, it’s time to move the model to the product environment. In this process, the necessary work will be done to ensure that the model can be used comfortably on every platform and device.</p><h3>5. Automation (Docker)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/275/1*zjcJ-bzsJHo-_v5CCYYhbA.png" /><figcaption><a href="https://www.docker.com/">Source</a></figcaption></figure><p><a href="https://www.docker.com/">Docker</a> is referred to as a containerization technology. Containers are used to run applications and their dependencies in an independent and isolated environment. A Docker container contains all the application code, libraries, and configuration files.</p><p>From this point on, we need to automate the model file that we know works in our system. So why do we need such a solution? A model that works properly on our system may not work on other systems due to issues such as compatibility. We need to standardize the model and make it work properly in the system components we build. Docker offers a good solution to avoid facing problems such as who has which packages installed on whose system, and who received an error at which stage. Besides all these, it provides portability, dependency management, isolation, and easier deployment.</p><p>In the first step, we created train_model.py file where the data preprocessing steps and the model are developed. Instead of working with this file, we will create predict.py, which contains the same process, but with an extra prediction section.</p><p><em>The model created in the train_model.py script needs to be saved to be used here. Edit the file path in the script below according to the file path where you saved the model.</em></p><p>predict.py file:</p><pre>import pandas as pd<br>from catboost import CatBoostClassifier<br><br># Load the trained model<br>MODEL_PATH = &quot;model/cat_model.cbm&quot; <br>model = CatBoostClassifier()<br>model.load_model(MODEL_PATH)<br><br>def predict_churn(user_input):<br>    try:<br>        # Prepare data for prediction<br>        user_data = pd.DataFrame([user_input])<br>        <br>        # Make prediction<br>        prediction = model.predict_proba(user_data)[:, 1][0]<br>        <br>        return {&quot;Churn Probability&quot;: float(prediction)}<br>    except Exception as e:<br>        return {&quot;error&quot;: str(e)}<br><br>if __name__ == &quot;__main__&quot;:<br>    # Ask user for input<br>    customerID = &quot;6464-UIAEA&quot;<br>    print(&quot;Please enter the following information:&quot;)<br>    gender = input(&quot;Gender (Male/Female): &quot;).strip()<br>    senior_citizen = int(input(&quot;Senior Citizen (0/1): &quot;).strip())<br>    partner = input(&quot;Partner (Yes/No): &quot;).strip()<br>    dependents = input(&quot;Dependents (Yes/No): &quot;).strip()<br>    tenure = int(input(&quot;Tenure (months): &quot;).strip())<br>    phone_service = input(&quot;Phone Service (Yes/No): &quot;).strip()<br>    multiple_lines = input(&quot;Multiple Lines (Yes/No): &quot;).strip()<br>    internet_service = input(&quot;Internet Service (DSL/Fiber optic/No): &quot;).strip()<br>    online_security = input(&quot;Online Security (Yes/No): &quot;).strip()<br>    online_backup = input(&quot;Online Backup (Yes/No): &quot;).strip()<br>    device_protection = input(&quot;Device Protection (Yes/No): &quot;).strip()<br>    tech_support = input(&quot;Tech Support (Yes/No): &quot;).strip()<br>    streaming_tv = input(&quot;Streaming TV (Yes/No): &quot;).strip()<br>    streaming_movies = input(&quot;Streaming Movies (Yes/No): &quot;).strip()<br>    contract = input(&quot;Contract (Month-to-month/One year/Two year): &quot;).strip()<br>    paperless_billing = input(&quot;Paperless Billing (Yes/No): &quot;).strip()<br>    payment_method = input(&quot;Payment Method (Electronic check/Mailed check/Bank transfer (automatic)/Credit card (automatic)): &quot;).strip()<br>    monthly_charges = float(input(&quot;Monthly Charges ($): &quot;).strip())<br>    total_charges = float(input(&quot;Total Charges ($): &quot;).strip())<br><br>    new_customer_data = pd.DataFrame({<br>                &quot;customerID&quot;: [customerID],<br>                &quot;gender&quot;: [gender],<br>                &quot;SeniorCitizen&quot;: [senior_citizen],<br>                &quot;Partner&quot;: [partner],<br>                &quot;Dependents&quot;: [dependents],<br>                &quot;tenure&quot;: [tenure],<br>                &quot;PhoneService&quot;: [phone_service],<br>                &quot;MultipleLines&quot;: [multiple_lines],<br>                &quot;InternetService&quot;: [internet_service],<br>                &quot;OnlineSecurity&quot;: [online_security],<br>                &quot;OnlineBackup&quot;: [online_backup],<br>                &quot;DeviceProtection&quot;: [device_protection],<br>                &quot;TechSupport&quot;: [tech_support],<br>                &quot;StreamingTV&quot;: [streaming_tv],<br>                &quot;StreamingMovies&quot;: [streaming_movies],<br>                &quot;Contract&quot;: [contract],<br>                &quot;PaperlessBilling&quot;: [paperless_billing],<br>                &quot;PaymentMethod&quot;: [payment_method],<br>                &quot;MonthlyCharges&quot;: [monthly_charges],<br>                &quot;TotalCharges&quot;: [total_charges]<br>            })<br><br>    # Predict churn probability using the model<br>    churn_probability = model.predict_proba(new_customer_data)[:, 1]<br><br>    # Format churn probability<br>    formatted_churn_probability = &quot;{:.2%}&quot;.format(churn_probability.item())<br><br>    print(f&quot;Churn Probability: {formatted_churn_probability}&quot;)</pre><p>This Python script allows the user to predict churn using the pre-trained model. It converts the user’s input into a DataFrame and gives it to the model to make a prediction. The script ends by printing the result to the screen.</p><p>Requirements should be well specified in the Dockerfile created for the deployment of the model. At this stage, we continue by creating a <strong>requirements.txt</strong> file. There are several ways to create this file. Specific libraries used when creating the model can be specified manually. Or if you used virtual environments such as virtualenv, pip freeze, pipreqs or piqar can be used as a good option. However, it should be noted that pip freeze will save all the packages in the virtual environment, not the environment variables used in your work. You can review <a href="https://pip.pypa.io/en/stable/cli/pip_freeze/">here</a> for the use of pip freeze.</p><p>For this work, I used <strong>pip freeze</strong> and created the requirements.txt file in the project folder:</p><pre>altair==5.2.0<br>annotated-types==0.6.0<br>anyio==4.2.0<br>asttokens==2.4.1<br>attrs==23.2.0<br>blinker==1.7.0<br>cachetools==5.3.2<br>catboost==1.2.2<br>certifi==2024.2.2<br>charset-normalizer==3.3.2<br>click==8.1.7<br>cloudpickle==3.0.0<br>contourpy==1.2.0<br>cycler==0.12.1<br>decorator==5.1.1<br>executing==2.0.1<br>fastapi==0.109.2<br>fonttools==4.48.1<br>gitdb==4.0.11<br>GitPython==3.1.41<br>graphviz==0.20.1<br>h11==0.14.0<br>idna==3.6<br>importlib-metadata==7.0.1<br>ipython<br>jedi==0.19.1<br>Jinja2==3.1.3<br>joblib==1.3.2<br>jsonschema==4.21.1<br>jsonschema-specifications==2023.12.1<br>kiwisolver==1.4.5<br>llvmlite==0.42.0<br>markdown-it-py==3.0.0<br>MarkupSafe==2.1.5<br>matplotlib==3.8.3<br>matplotlib-inline==0.1.6<br>mdurl==0.1.2<br>numba==0.59.0<br>numpy==1.26.4<br>packaging==23.2<br>pandas==2.2.0<br>parso==0.8.3<br>pexpect==4.9.0<br>pillow==10.2.0<br>plotly==5.18.0<br>prompt-toolkit==3.0.43<br>protobuf==4.25.2<br>ptyprocess==0.7.0<br>pure-eval==0.2.2<br>pyarrow==15.0.0<br>pydantic==2.6.1<br>pydantic_core==2.16.2<br>pydeck==0.8.1b0<br>Pygments==2.17.2<br>pyparsing==3.1.1<br>python-dateutil==2.8.2<br>pytz==2024.1<br>referencing==0.33.0<br>requests==2.31.0<br>rich==13.7.0<br>rpds-py==0.18.0<br>scikit-learn==1.4.0<br>scipy==1.12.0<br>shap==0.44.1<br>six==1.16.0<br>slicer==0.0.7<br>smmap==5.0.1<br>sniffio==1.3.0<br>stack-data==0.6.3<br>starlette==0.36.3<br>streamlit==1.31.1<br>tenacity==8.2.3<br>threadpoolctl==3.3.0<br>toml==0.10.2<br>toolz==0.12.1<br>tornado==6.4<br>tqdm==4.66.2<br>traitlets==5.14.1<br>typing_extensions==4.9.0<br>tzdata==2024.1<br>tzlocal==5.2<br>urllib3==2.2.0<br>uvicorn==0.27.1<br>validators==0.22.0<br>watchdog==4.0.0<br>wcwidth==0.2.13<br>zipp==3.17.0</pre><p>Dockerfile is a configuration file that determines the structure of Docker containers. It contains instructions such as how to run the application and which dependencies should be installed. Docker creates a container using this Dockerfile and converts this container into a file called an “image”. This “image” then becomes executable on any system.</p><p>After creating the requirements.txt file, we can create the Dockerfile:</p><pre># Use a Python-based image<br>FROM python:3.9-slim<br><br># Copy requirements.txt and install dependencies<br>COPY requirements.txt requirements.txt<br>RUN pip install --no-cache-dir -r requirements.txt<br><br># Specify working directory<br>WORKDIR /app<br><br># Copy application code<br>COPY . .<br><br># Run the application<br>CMD [&quot;python&quot;, &quot;src/predict.py&quot;]</pre><p><strong>Step 1: Base Image Selection</strong><br>We start by specifying the base image that provides the minimum Python environment in which the container will be created (python:3.9-slim).</p><p><strong>Step 2: Installing Dependencies</strong><br>Copy the requirements.txt file from the host machine to the container and install the dependencies listed in it using pip.</p><p><strong>Step 3: Setting the Working Directory and Copying Application Code</strong><br>Set the working directory to /app. Copy all files and directories from the host machine to the /app directory within the container.</p><p><strong>Step 4: Running the Application</strong><br>Execute the predict.py script using the Python interpreter as the default command when the container starts.</p><p>To continue at this stage of the project, after installing Docker and creating the necessary files, we can go to the directory where the Dockerfile is located and build it as follows.</p><pre>docker build -t churn-prediction-app .</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/895/1*J-lRzBlz-IhOK66BytQb_g.png" /><figcaption>Image by author</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/560/1*sSwRLhgYHuKK7-HFujYpCQ.png" /><figcaption>Image by author</figcaption></figure><p>You can see if the Dockerfile has been successfully built with the command below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/778/1*gy4WzT90TRbkvk1q0GPnkA.png" /><figcaption>Images list</figcaption></figure><p>We have done the build, we can run the image we created in the terminal.</p><pre>docker run -it churn-prediction-app</pre><p>We can see the result of the model by entering the customer information we want to see the churn probability in order.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SAhRQLyn4SX3Pfz3Gz2ydQ.png" /><figcaption>Predict</figcaption></figure><p>Through Docker, we can see the Churn probability of the customer we created for prediction in Streamlit and FastAPI. Users who want to predict the model we have created can access this convenience by building and running the Dockerfile.</p><h3>6. Conclusion</h3><p>During the development of the project, a machine learning model was developed using CatBoost with customer data provided by the telecom company. To examine the model interactively, an interface was designed using Streamlit. In addition, an API was created with FastAPI to quickly access and integrate the model. Finally, optimization was achieved using Docker to make the project more scalable and deployable.</p><blockquote>I would like to express my sincere thanks to Hasan Avcı for his support during this journey and to <a href="https://inzva.com/">inzva</a> for the opportunities they provided.</blockquote><p>Thank you for reading and please do not hesitate to share your comments and suggestions.</p><p>LinkedIn: <a href="https://www.linkedin.com/in/ramazanolmez/">https://www.linkedin.com/in/ramazanolmez/</a><br>Mail: ramazanolmeez@gmail.com</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e9c4d0322ac9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Handling Missing Values in Data Science / Machine Learning Projects: Strategies and Practice]]></title>
            <link>https://medium.com/@ramazanolmeez/handling-missing-values-in-data-science-machine-learning-projects-strategies-and-practice-42d7376ca94a?source=rss-b005bac7906e------2</link>
            <guid isPermaLink="false">https://medium.com/p/42d7376ca94a</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[handling-missing-values]]></category>
            <category><![CDATA[missing-value-treatment]]></category>
            <category><![CDATA[missing-values]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Ramazan Olmez]]></dc:creator>
            <pubDate>Thu, 08 Feb 2024 11:08:50 GMT</pubDate>
            <atom:updated>2024-02-08T11:08:50.117Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DXg4ptaU_iyH6_5E" /><figcaption>Photo by <a href="https://unsplash.com/@rinako?utm_source=medium&amp;utm_medium=referral">bao sabrina</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><blockquote>You can also view the work on <a href="https://www.kaggle.com/code/rolmez/handling-missing-values-strategies-and-practice/notebook">Kaggle</a>.</blockquote><p><strong>Table of Contents<br></strong>· <a href="#0f36">1. Introduction</a><br>· <a href="#f235">2. Types of Missing Data</a><br> ∘ <a href="#abb1">a. Missing Completely At Random (MCAR)</a><br> ∘ <a href="#da17">b. Missing At Random (MAR)</a><br> ∘ <a href="#31f0">c. Missing Not At Random (MNAR)</a><br>· <a href="#0395">3. Dataset</a><br>· <a href="#340b">4. Missing Value Analysis</a><br>· <a href="#9383">5. Methods</a><br> ∘ <a href="#f775">5.1. Ignoring Missing Data</a><br> ∘ <a href="#a481">5.2. Delete Missing Data</a><br> ∘ <a href="#d121">5.3. Statistically Filling Missing Data (Mean-Median-Constant)</a><br> ∘ <a href="#3a15">5.4. Other Filling Methods (Forward Fill — Backward Fill — Linear (Interpolation))</a><br> ∘ <a href="#ee26">5.5. Advanced Imputation Techniques (Prediction of Missing Values) (KNN — Linear Regression — Random Forest Regressor)</a><br>· <a href="#5bf6">6. Result</a></p><h3>1. Introduction</h3><p>Missing values are a common problem in machine learning and data science projects. Failure to handle missing data correctly can skew the results of machine learning models or reduce the model&#39;s accuracy. To overcome these obstacles, we must either carefully remove missing values or carefully complete them. Either way, our goal is to create a complete dataset that will put our analysis on a solid footing. Ignoring missing data can directly affect the performance and reliability of our models. Therefore, it is extremely important to know the different techniques for dealing with missing values and choose the right method. While dealing with missing values is not our ultimate goal, it plays a critical role in data preprocessing steps and can help to significantly improve model performance. In this article, I will explain the causes and types of missing data and the advantages and disadvantages of various methods to deal with this problem.</p><p>Missing data can be caused by merging data sources, accidents or measurement errors during data collection, lack of records, respondent unwillingness to provide information, etc.</p><h3>2. Types of Missing Data</h3><p>Missing data types are categorized into 3 groups in the literature:</p><h4>a. Missing Completely At Random (MCAR)</h4><p>In the MCAR case, there is no relationship between the missing data and the other values in the data set. In other words, the missing values are completely independent of the other data. As the missing values increase, the overall information content of the data set decreases. This can affect the accuracy and reliability of the analysis results.</p><h4>b. Missing At Random (MAR)</h4><p>MAR is a type of missing data where the missing data is correlated with other observed values. In this case, missing data does not occur randomly, but is missing according to a specific pattern. This pattern can be explained by a variable for which we have information about the cause of the missingness. If missing data of this type is ignored, the results of the analysis may not reflect the real situation.</p><h4>c. Missing Not At Random (MNAR)</h4><p>MNAR is a type of missing data where the missing data is due to unobserved data and cannot be explained by other observed data. If there is a structure or pattern in the missing data and this pattern cannot be explained by the observed data, it can be categorized as MNAR.</p><h3>3. Dataset</h3><p>In this article, I will use the “UCI Heart Disease Data” set available in the UCI Data Repository. This dataset aims to predict whether a patient has heart disease based on certain characteristics. You can access the dataset here;</p><ul><li><a href="https://www.kaggle.com/datasets/redwankarimsony/heart-disease-data">https://www.kaggle.com/datasets/redwankarimsony/heart-disease-data</a></li><li><a href="https://archive.ics.uci.edu/dataset/45/heart+disease">https://archive.ics.uci.edu/dataset/45/heart+disease</a></li></ul><p>In the dataset, the target variable is given in 5 groups. These groups will be reduced to 2 (with heart disease, and without heart disease) and evaluated.</p><p>In addition, since this study does not focus on model development, I will encode the categorical variables and make the entire dataset numerical. The dataset I will use in the scope of the article looks as follows.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/681/1*c2jopjVXzgKkxOLLNy7b2w.png" /><figcaption>The dataset looks like this</figcaption></figure><h3>4. Missing Value Analysis</h3><p>Visualizations and summaries are the first step in understanding missing information in a dataset. Identifying how many and what types of missing values are present in our dataset is one of the first steps when dealing with missing values. A glance at the number of missing values in the dataset can give a good idea:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/326/1*msRDhTTKlfEMnUzIYmw7oQ.png" /><figcaption>Variable-based count of missing values</figcaption></figure><p>However, as well as the number of missing data, another point to look at is the proportion of missing data in the whole data set. The following function can be used for this analysis:</p><pre>def missing_values(df):<br>        # Total missing values<br>        mis_val = df.isnull().sum()<br>        <br>        # Percentage<br>        mis_val_percent = 100 * df.isnull().sum() / len(df)<br>        <br>        # Make a table with the results<br>        mis_val_table = pd.concat([mis_val, mis_val_percent], axis=1)<br>    <br>        mis_val_table_ren_columns = mis_val_table.rename(<br>        columns = {0 : &#39;Missing Values&#39;, 1 : &#39;% of Total Values&#39;})<br>        <br>        # Sort the table by percentage of missing descending<br>        mis_val_table_ren_columns = mis_val_table_ren_columns[<br>            mis_val_table_ren_columns.iloc[:,1] != 0].sort_values(<br>        &#39;% of Total Values&#39;, ascending=False).round(1)<br>        <br>        # Print some summary information<br>        print (&quot;Your selected dataframe has &quot; + str(df.shape[1]) + &quot; columns.\n&quot;      <br>            &quot;There are &quot; + str(mis_val_table_ren_columns.shape[0]) +<br>              &quot; columns that have missing values.&quot;)<br>        <br>        # Return the dataframe with missing information<br>        return mis_val_table_ren_columns<br>    <br>missing_values_table = missing_values(data)<br>missing_values_table</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/376/1*zs4sB1l_lO6ZDSC2iUZKLg.png" /><figcaption>Missing values ratio</figcaption></figure><p>Although the proportion of missing values in the whole data set provides some information, it is not enough. One of the useful tools for analysis is missingno. <a href="https://github.com/ResidentMario/missingno">Missingno</a>, provides a flexible and easy-to-use toolkit that allows one to get a quick visual summary.</p><p>To see how the data correlate with each other;</p><pre>sorted = data.sort_values(&#39;oldpeak&#39;)<br>msno.matrix(sorted)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CpFwv7E-NVfUhsiLBg3g0A.png" /></figure><p>You can also use a heat map for correlation:</p><pre>msno.heatmap(data)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fmLH33YQHMjDYhAfcF2jiA.png" /></figure><p>In this dataset, ‘trestbps’, ‘thalch’ and ‘oldpeak’ variables are highly correlated with each other. The reason behind this should be investigated, and we should take this into account when dealing with missing values.</p><p>Another point we can look at in visualization is the dendrogram.</p><pre>msno.dendrogram(data)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rcWFl7RkrD49Uzz5ZqSDpg.png" /></figure><p>This tree diagram groups variables with high correlation together. The variables at position 0 are not correlated with the missing variables. As I observed in the heatmap, the variables ‘thalch’, ‘trestbps’ and ‘oldpeak’ are highly correlated with each other. At the same time, these 3 variables are more correlated with ‘thal’ and ‘chol’ than ‘ca’.</p><h3>5. Methods</h3><p>There are multiple assignment methods we can use depending on whether the data is missing at random, the proportion of missing values, and the machine learning model we plan to use. It is important to handle missing data appropriately. If we want to use an algorithm that can work with missing data, perhaps we should leave it as it is. However, most algorithms cannot work with missing data and they need to be cleaned/edited.</p><p>In this article, each method was applied to the dataset, and the Random Forest Classifier model was trained with the new dataset. The accuracy of each method is shared and compared in the conclusion.</p><p>The most commonly used methods for dealing with missing data</p><ul><li>Using algorithms like XGBoost to ignore missing data</li><li>Remove missing data by row or column</li><li>Filling in missing data statistically</li><li>Filling missing data with other methods</li><li>Prediction of missing values</li></ul><p>Before we move on to these methods, let’s load the libraries and create the functions you need to run the notebook.</p><pre>import numpy as np # For linear algebra operations and numerical computations<br>import pandas as pd # For data analysis and manipulation using data frames<br>import os<br><br># List Kaggle file paths<br>for dirname, _, filenames in os.walk(&#39;/kaggle/input&#39;):<br>    for filename in filenames:<br>        print(os.path.join(dirname, filename))<br><br>import missingno as msno # For visualizing missing data patterns<br><br>from sklearn.preprocessing import LabelEncoder # For converting categorical data to numerical values<br>from sklearn.model_selection import train_test_split # For splitting data into training and testing sets<br>from sklearn.metrics import accuracy_score # For calculating the accuracy score of a classification model<br>from sklearn.impute import KNNImputer # For imputing missing values using K-Nearest Neighbors<br>from sklearn.neighbors import KNeighborsClassifier # K-Nearest Neighbors classification model<br>from sklearn.linear_model import LinearRegression # Linear regression model<br>from sklearn.ensemble import RandomForestRegressor # Random Forest regression model<br>from sklearn.ensemble import RandomForestClassifier # Random Forest classifier model<br>from sklearn.metrics import mean_squared_error # Performance metric for regression models<br>from sklearn.impute import SimpleImputer # For imputing missing values with a simple strategy<br><br>from xgboost import XGBClassifier # XGBoost classification model</pre><pre>def read_data():<br>    &quot;&quot;&quot;<br>    Reads the &#39;Heart disease&#39; dataset,<br>    performs some editing, and returns it.<br>    &quot;&quot;&quot;<br>    df = pd.read_csv(&quot;/kaggle/input/heart-disease-data/heart_disease_uci.csv&quot;)<br>    df[&#39;num&#39;] = df[&#39;num&#39;].replace({2: 1, 3: 1, 4: 1})<br>    df = df.drop(&#39;id&#39;, axis=1)<br>    df[df.select_dtypes([&#39;object&#39;]).columns] = df.select_dtypes([&#39;object&#39;]).apply(lambda x: x.astype(&#39;category&#39;))<br>    <br>    categorical_columns = df.select_dtypes(include=[&#39;category&#39;]).columns<br><br>    # Convert categorical to numerical<br>    label_encoder = LabelEncoder()<br>    <br>    for column in categorical_columns:<br>        df[column] = label_encoder.fit_transform(df[column])<br>    return df<br><br>def split_dataset(df):<br>    &quot;&quot;&quot;<br>    Splits the dataset into training and testing sets.<br>    <br>    Parameters:<br>    - df (pd.DataFrame): The input dataset.<br>    <br>    Returns:<br>    - X_train, X_test, y_train, y_test: Training and testing sets for features and labels.<br>    &quot;&quot;&quot;<br>    X = df.drop(&#39;num&#39;, axis=1)<br>    y = df[&#39;num&#39;]<br>    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)<br>    # print(f&#39;Size of the Train: {X_train.shape[0]}&#39;)<br>    # print(f&#39;Size of the Test: {X_test.shape[0]}&#39;)<br>    return X_train, X_test, y_train, y_test<br><br>def train_model_XGBoost(X_train, X_test, y_train, y_test):<br>    &quot;&quot;&quot;<br>    Trains an XGBoost model on the given training set and evaluates it on the test set.<br>    <br>    Parameters:<br>    - X_train, X_test, y_train, y_test: Training and testing sets for features and labels.<br>    &quot;&quot;&quot;<br>    # Create and train the XGBoost model<br>    xgb_model = XGBClassifier()<br>    xgb_model.fit(X_train, y_train)<br><br>    # Evaluate the model on the test set<br>    y_pred = xgb_model.predict(X_test)<br>    accuracy = accuracy_score(y_test, y_pred)<br>    print(f&quot;Accuracy: {accuracy}\n&quot;)<br>    return accuracy<br>    <br>def train_model_random_forest(X_train, X_test, y_train, y_test):<br>    &quot;&quot;&quot;<br>    Creates and trains a RandomForest model on the given training set <br>    and evaluates its performance on the test set.<br>    <br>    Parameters:<br>    - X_train, X_test, y_train, y_test: Training and testing sets for features and labels.<br>    <br>    Returns:<br>    - accuracy (float): Accuracy score of the trained model on the test set.<br>    &quot;&quot;&quot;<br>    # Create and train the RandomForest model<br>    rf_model = RandomForestClassifier()<br>    rf_model.fit(X_train, y_train)<br><br>    # Evaluate the model on the test set<br>    y_pred = rf_model.predict(X_test)<br>    accuracy = accuracy_score(y_test, y_pred)<br>    print(f&quot;Accuracy: {accuracy}\n&quot;)<br>    return accuracy<br><br><br># To compare the success of the methods<br>accuracies = {}</pre><h4>5.1. Ignoring Missing Data</h4><p>Most popular models (SVM, NN…) cannot work with missing data. However, there are a few predictive models that can handle missing data internally. In this step, we will train a model using XGBoost without handling missing values in the raw dataset.</p><pre># Read and preprocess the dataset<br>df = read_data()<br><br># Split the dataset into training and testing sets<br>X_train, X_test, y_train, y_test = split_dataset(df)<br><br># Train an XGBoost model on the dataset without handling missing values<br>accuracy_no_handling = train_model_XGBoost(X_train, X_test, y_train, y_test)<br><br># Store the accuracy of the model without handling missing values in a dictionary<br>accuracies[&#39;No Handling&#39;] = accuracy_no_handling<br><br># A specific data, after the procedure<br>print(&quot;\n------------------\n&quot;)<br>print(&quot;\nAfter Imputation: \n&quot;)<br>X_train[(X_train[&#39;age&#39;]==58.0) &amp; (X_train[&#39;sex&#39;]==1.0) &amp; (X_train[&#39;dataset&#39;]==3.0) &amp; (X_train[&#39;chol&#39;]==385)]</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/244/1*e23DdLXuy5iivQUMD6mSAQ.png" /><figcaption>‘Accuracy’ without handling missing values</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/947/1*7_yva4MbqUvuPQS_fHWaZw.png" /><figcaption>‘Dataset’ before and after without handling missing values</figcaption></figure><p><strong>Pros:</strong></p><ul><li>Ignoring missing values simplifies the data preprocessing process. Instead of dealing with missing values, time is saved by feeding the dataset directly into the modeling algorithms.</li><li>This method is preferable for creating a quick prototype at the beginning of a project. Modeling can be started immediately, rather than having to go through the detailed process of filling in or cleaning up missing values.</li><li>Some machine learning algorithms can handle missing values directly and may not harm model performance. In particular, such algorithms, such as tree-based algorithms, can be robust to missing values.</li></ul><p><strong>Cons:</strong></p><ul><li>It can lead to the loss of potentially valuable information from the dataset. Missing values can often be indicative of important patterns in the dataset and ignoring this information can negatively impact the performance of the model.</li><li>It can reduce the predictive accuracy of the model. Missing values may prevent the model from generalizing correctly and lead to biased results.</li><li>It can introduce bias into the patterns in the dataset. This can reduce the model’s ability to fit real-world data and reduce the reliability of predictions.</li><li>Some algorithms can be robust to missing values, but this can lead to reduced precision of the model. Filling in or cleaning up missing values can help the model make more accurate and reliable predictions.</li></ul><h4>5.2. Delete Missing Data</h4><p>If models that do not tolerate missing data are to be used, the missing values must be removed from the data set. The simplest approach is to delete all samples that contain missing values. Missing values can be eliminated by removing variables that contain at least one missing value. Similarly, removing all columns with missing values from the data set is another approach. Before using these approaches, however, some aspects of the data need to be carefully considered. The size of the data after deletion of missing data, the randomness of missing data, or the ratio of missing data to the entire data set are critical points to consider when applying these approaches.</p><p>This category consists of 3 stages. These stages are:</p><ul><li>Pairwise Deletions</li><li>Listwise Deletions</li><li>Dropping Entire Columns</li></ul><p><strong>a. Pairwise Deletions</strong></p><p>If each data point has at least one missing value, that row of data is deleted from the entire list. This method can be used when the amount of missing data is small and the missing values are randomly distributed.</p><pre># Read and preprocess the dataset<br>df = read_data()<br><br># 1. Pairwise Deletions<br># Drop rows with any missing values (Pairwise Deletions)<br>df_pairwise = df.dropna()<br><br># Split the dataset (after Pairwise Deletions) into training and testing sets<br>X_train, X_test, y_train, y_test = split_dataset(df_pairwise)<br><br># Train a Random Forest model on the dataset after Pairwise Deletions<br>accuracy_pairwise = train_model_random_forest(X_train, X_test, y_train, y_test)<br><br># Store the accuracy of the model after Pairwise Deletions in a dictionary<br>accuracies[&#39;Pairwise&#39;] = accuracy_pairwise</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/246/1*6I4KwD3eqzkJGwqdsFC7aA.png" /><figcaption>‘Accuracy’ after Pairwise Deletion</figcaption></figure><p><strong>Pros:</strong></p><ul><li>It is very useful for simplicity and computational efficiency.</li></ul><p><strong>Cons:</strong></p><ul><li>It leads to a loss of information and a reduction in the number of samples. This can lead to insufficient data for the model.</li></ul><p><strong>b. Listwise Deletions</strong></p><p>All data instances with missing data from more than one variable are deleted. This method can be used when the amount of missing data is large or when the missing values are distributed according to a certain pattern.</p><pre># Read and preprocess the dataset<br>df = read_data()<br><br># 2. Listwise Deletions<br># Drop rows with missing values in specific columns<br>df_listwise = df.dropna(subset=[&#39;trestbps&#39;, &#39;chol&#39;, &#39;thalch&#39;, &#39;oldpeak&#39;, &#39;ca&#39;])<br><br># Split the dataset (after Listwise Deletions) into training and testing sets<br>X_train, X_test, y_train, y_test = split_dataset(df_listwise)<br><br># Train a Random Forest model on the dataset after Listwise Deletions<br>accuracy_listwise = train_model_random_forest(X_train, X_test, y_train, y_test)<br><br># Store the accuracy of the model after Listwise Deletions in a dictionary<br>accuracies[&#39;Listwise&#39;] = accuracy_listwise</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/236/1*EqQMLj8JrSgWTAPJlSWisQ.png" /><figcaption>‘Accuracy’ after Listwise Deletion</figcaption></figure><p><strong>Pros:</strong></p><ul><li>As with Pairwise Deletions, it is very simple and low-cost to implement.</li></ul><p><strong>Cons:</strong></p><ul><li>It may reduce the number of samples. This can lead to a destabilization of the dataset and loss of correlation.</li></ul><p><strong>c. Dropping Entire Columns</strong></p><p>All columns with too much missing data are deleted from the dataset. This method can be used when the amount of missing data is very large and the columns with missing data are not important for the analysis. However, this approach should only be used when there are many empty values in the column.</p><pre># Read and preprocess the dataset<br>df = read_data()<br><br># 3. Dropping Entire Columns<br># Drop entire columns with any missing values<br>df_dropping_entire_columns = df.dropna(axis=1)<br><br># Split the dataset (after Dropping Entire Columns) into training and testing sets<br>X_train, X_test, y_train, y_test = split_dataset(df_dropping_entire_columns)<br><br># Train a Random Forest model on the dataset after Dropping Entire Columns<br>accuracy_dropping_entire_columns = train_model_random_forest(X_train, X_test, y_train, y_test)<br><br># Store the accuracy of the model after Dropping Entire Columns in a dictionary<br>accuracies[&#39;Dropping Entire Columns&#39;] = accuracy_dropping_entire_columns<br><br># A specific data, after the procedure<br>print(&quot;\n------------------\n&quot;)<br>print(&quot;\nAfter Imputation: \n&quot;)<br>X_train[(X_train[&#39;age&#39;]==58.0) &amp; (X_train[&#39;sex&#39;]==1.0) &amp; (X_train[&#39;dataset&#39;]==3.0) &amp; (X_train[&#39;restecg&#39;]==0) &amp; (X_train[&#39;exang&#39;]==2)]</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/239/1*7LunKtMuuu9WmeOa-Y5ZSg.png" /><figcaption>‘Accuracy’ after Dropping Entire Columns</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/963/1*8sVt7ZgqYMXQFHQ3pARXzw.png" /><figcaption>‘Dataset’ before and after Dropping Entire Columns</figcaption></figure><p><strong>Pros:</strong></p><ul><li>Like other deletions, this method offers a simple and computationally cost-effective solution.</li></ul><p><strong>Cons:</strong></p><ul><li>Deleting all columns with missing values may result in the loss of important information in the dataset. This can negatively affect the accuracy and reliability of the model.</li><li>While the simplicity of this method may be attractive, deleting columns has serious consequences for model performance.</li></ul><h4>5.3. Statistically Filling Missing Data (Mean-Median-Constant)</h4><p>Another approach to handling missing data is to statistically fill them in. The filling process uses relationships between non-missing data.</p><p>Some methods of this approach include filling in missing data with mean, median, or constant if the data are numeric and mode if the data are categorical.</p><p><strong>a. Mean and Median</strong></p><p>Mean: This is the most common method of filling in missing values in numeric columns. This method may not be appropriate if there are outliers in the dataset. In such cases, outliers need to be addressed first.</p><p>Median: This is the value that divides the data series in half when we sort the dataset from smallest to largest. It is better to use the median if there are outliers in the data set.</p><pre>def impute_and_train(X_train, y_train, X_test, y_test, strategy):<br>    &quot;&quot;&quot;<br>    Imputes missing values in the training and testing sets using the specified strategy,<br>    trains a Random Forest model, and evaluates its performance on the test set.<br>    <br>    Parameters:<br>    - X_train, y_train: Training features and labels.<br>    - X_test, y_test: Testing features and labels.<br>    - strategy (str): Imputation strategy to handle missing values (&#39;mean&#39; or &#39;median&#39;).<br>    <br>    Returns:<br>    - accuracy (float): Accuracy score of the model on the test set.<br>    &quot;&quot;&quot;<br>    # Impute missing values<br>    imputer = SimpleImputer(strategy=strategy)<br>    X_train_imputed = pd.DataFrame(imputer.fit_transform(X_train), columns=X_train.columns)<br>    X_test_imputed = pd.DataFrame(imputer.transform(X_test), columns=X_test.columns)<br>    <br>    # Train a Random Forest model on the imputed training set<br>    rf_model = RandomForestClassifier()<br>    rf_model.fit(X_train_imputed, y_train)<br><br>    # Evaluate the model on the imputed test set<br>    y_pred = rf_model.predict(X_test_imputed)<br>    accuracy = accuracy_score(y_test, y_pred)<br>        <br>    print(f&quot;\n\nImputation strategy: {strategy}&quot;)<br>    print(f&quot;Accuracy: {accuracy}\n&quot;)<br>    return accuracy, X_train_imputed<br><br># Read and preprocess the dataset<br>df = read_data()<br>X_train, X_test, y_train, y_test = split_dataset(df)<br><br># Train the model using different imputation strategies<br>strategies = [&#39;mean&#39;, &#39;median&#39;]<br><br>for strategy in strategies:<br>    accuracy, X_train_imputed = impute_and_train(X_train, y_train, X_test, y_test, strategy)<br>    accuracies[strategy] = accuracy<br>    <br>    # A specific data, after the procedure<br>    print(&quot;\n------------------\n&quot;)<br>    print(&quot;\nAfter Imputation: \n&quot;)<br>    print(X_train_imputed[(X_train_imputed[&#39;age&#39;]==58.0) &amp; (X_train_imputed[&#39;sex&#39;]==1.0) &amp; (X_train_imputed[&#39;dataset&#39;]==3.0) &amp; (X_train_imputed[&#39;chol&#39;]==385)])<br>    print(&quot;\n----------------------------\n----------------------------\n----------------------------&quot;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/253/1*88rXJMLH7HVbzqUlyThrYA.png" /><figcaption>‘Accuracy’ after Mean and Median Imputation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/946/1*Jy2ISpNId_Ywj8LAICsEwQ.png" /><figcaption>‘Dataset’ before and after Mean Imputation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/954/1*MbS9u1-QD6le3Bm9t1Zb1g.png" /><figcaption>‘Dataset’ before and after Median Imputation</figcaption></figure><p><strong>Pros:</strong></p><ul><li>Easy to implement and fast.</li><li>Minimizes information loss.</li><li>Preserves the overall performance of the model.</li><li>Conserves the size of the data set.</li><li>More sensitive to outliers (Median Imputation).</li></ul><p><strong>Cons:</strong></p><ul><li>May increase the impact of outliers (Mean Imputation).</li><li>It can change the distribution between values.</li><li>Distort the original structure of missing values.</li><li>Reduces the natural variance of the data set.</li></ul><p><strong>b. Constant</strong></p><p>Constant filling is the process of filling missing values with a constant value (0, 100, 999, etc.). Although it has its advantages, it also has many disadvantages.</p><pre>def constant_imputer(X_train, y_train, X_test, y_test):<br>    &quot;&quot;&quot;<br>    Imputes missing values with a constant value (999) in the training and testing sets,<br>    trains a Random Forest model, and evaluates its performance on the test set.<br>    <br>    Parameters:<br>    - X_train, y_train: Training features and labels.<br>    - X_test, y_test: Testing features and labels.<br>    <br>    Returns:<br>    - accuracy (float): Accuracy score of the model on the test set.<br>    &quot;&quot;&quot;<br>    # Impute missing values with a constant value (999)<br>    imputer = SimpleImputer(strategy=&#39;constant&#39;, fill_value=999)<br>    X_train_imputed = pd.DataFrame(imputer.fit_transform(X_train), columns=X_train.columns)<br>    X_test_imputed = pd.DataFrame(imputer.transform(X_test), columns=X_test.columns)<br>    <br>    # Train a Random Forest model on the imputed training set<br>    rf_model = RandomForestClassifier()<br>    rf_model.fit(X_train_imputed, y_train)<br><br>    # Evaluate the model on the imputed test set<br>    y_pred = rf_model.predict(X_test_imputed)<br>    accuracy = accuracy_score(y_test, y_pred)<br>    print(f&quot;\nAccuracy: {accuracy}\n&quot;)<br>    return accuracy, X_train_imputed<br><br># Read and preprocess the dataset<br>df = read_data()<br>X_train, X_test, y_train, y_test = split_dataset(df)<br><br># Impute missing values with a constant value and train the model<br>accuracy_constant, X_train_imputed = constant_imputer(X_train, y_train, X_test, y_test)<br><br># Store the accuracy of the model with constant imputation in a dictionary<br>accuracies[&#39;Constant Impute&#39;] = accuracy_constant<br><br># A specific data, after the procedure<br>print(&quot;\n------------------\n&quot;)<br>print(&quot;\nAfter Imputation: \n&quot;)<br><br>X_train_imputed[(X_train_imputed[&#39;age&#39;]==58.0) &amp; (X_train_imputed[&#39;sex&#39;]==1.0) &amp; (X_train_imputed[&#39;dataset&#39;]==3.0) &amp; (X_train_imputed[&#39;chol&#39;]==385)]</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/243/1*jIu2NcUaUViPTDS165oU0A.png" /><figcaption>‘Accuracy’ after Constant Imputation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/969/1*kH084enqGW4-EKKMaR9o1w.png" /><figcaption>‘Dataset’ before and after Constant Imputation</figcaption></figure><p><strong>Pros:</strong></p><ul><li>Like other filling methods, it is a simple and quick approach.</li></ul><p><strong>Cons:</strong></p><ul><li>It may cause a loss of information in the dataset as it fills missing values with a random or meaningless value.</li><li>If an appropriate constant value is not chosen for missing values, it may negatively affect the performance of the model.</li></ul><h4>5.4. Other Filling Methods (Forward Fill — Backward Fill — Linear (Interpolation))</h4><p>Depending on the nature of the data or the type of data, some other filling methods may be more appropriate for filling missing values. For example, for a time series dataset, it may make sense to use the last valid observation to fill in the missing value.</p><p>Forward Fill: All missing values are filled according to the corresponding value in the previous row.</p><p>Backward Fill: The missing value is found using the next value.</p><p>Interpolation: Missing values are estimated using the linear relationship between other values in the dataset. Pandas’ interpolation method can be used to replace missing values with different interpolation methods such as ‘polynomial’, ‘linear’, and ‘quadratic’. The default method is ‘linear’.</p><blockquote>In the dataset we considered, the method could not be applied to all variables due to missing values in the last 2 columns of the ‘ca’ variable. To overcome this problem, I used a little trick in the code and used the mean method for this variable.</blockquote><pre>def fill_missing_values(data, method=&#39;ffill&#39;):<br>    &quot;&quot;&quot;<br>    Fills missing values in the dataset using specified methods: &#39;ffill&#39;, &#39;bfill&#39;, or &#39;linear&#39;.<br>    <br>    Parameters:<br>    - data (pd.DataFrame): Input dataset.<br>    - method (str): Method for filling missing values (&#39;ffill&#39;, &#39;bfill&#39;, or &#39;linear&#39;).<br>    <br>    Returns:<br>    - filled_data (pd.DataFrame): Dataset with filled missing values.<br>    &quot;&quot;&quot;<br>    if method == &#39;ffill&#39;:<br>        filled_data = data.fillna(method=&#39;ffill&#39;)<br>    elif method == &#39;bfill&#39;:<br>        data[&#39;ca&#39;] = data[&#39;ca&#39;].fillna(data[&#39;ca&#39;].mean())<br>        filled_data = data.fillna(method=&#39;bfill&#39;)<br>    else:<br>        filled_data = data.interpolate(method=&#39;linear&#39;, limit_direction=&#39;forward&#39;)<br>    return filled_data<br><br># Read and preprocess the dataset<br>data = read_data()<br><br># Fill missing values using forward fill method<br>filled_data_ffill = fill_missing_values(data, method=&#39;ffill&#39;)<br>X_train_ffill, X_test_ffill, y_train_ffill, y_test_ffill = split_dataset(filled_data_ffill)<br><br># Fill missing values using back fill method<br>filled_data_bfill = fill_missing_values(data, method=&#39;bfill&#39;)<br>X_train_bfill, X_test_bfill, y_train_bfill, y_test_bfill = split_dataset(filled_data_bfill)<br><br># Fill missing values using linear interpolation method<br>filled_data_linear = fill_missing_values(data, method=&#39;linear&#39;)<br>X_train_linear, X_test_linear, y_train_linear, y_test_linear = split_dataset(filled_data_linear)<br><br># A specific data, after the procedure<br># Train Random Forest models on datasets with different filling methods<br>print(&quot;\n\n\nFfill method:&quot;)<br>accuracy_ffill = train_model_random_forest(X_train_ffill, X_test_ffill, y_train_ffill, y_test_ffill)<br>print(&quot;\n------------------\n&quot;)<br>print(&quot;\nAfter Imputation: \n&quot;)<br>print(X_train_ffill[(X_train_ffill[&#39;age&#39;]==58.0) &amp; (X_train_ffill[&#39;sex&#39;]==1.0) &amp; (X_train_ffill[&#39;dataset&#39;]==3.0) &amp; (X_train_ffill[&#39;chol&#39;]==385)]<br>)<br>print(&quot;\n----------------------------\n----------------------------\n----------------------------&quot;)<br><br>print(&quot;\n\n\nBfill method:&quot;)<br>accuracy_bfill = train_model_random_forest(X_train_bfill, X_test_bfill, y_train_bfill, y_test_bfill)<br>print(&quot;\n------------------\n&quot;)<br>print(&quot;\nAfter Imputation: \n&quot;)<br>print(X_train_bfill[(X_train_bfill[&#39;age&#39;]==58.0) &amp; (X_train_bfill[&#39;sex&#39;]==1.0) &amp; (X_train_bfill[&#39;dataset&#39;]==3.0) &amp; (X_train_bfill[&#39;chol&#39;]==385)]<br>)<br>print(&quot;\n----------------------------\n----------------------------\n----------------------------&quot;)<br><br>print(&quot;\n\n\nLinear method:&quot;)<br>accuracy_linear = train_model_random_forest(X_train_linear, X_test_linear, y_train_linear, y_test_linear)<br>print(&quot;\n------------------\n&quot;)<br>print(&quot;\nAfter Imputation: \n&quot;)<br>print(X_train_linear[(X_train_linear[&#39;age&#39;]==58.0) &amp; (X_train_linear[&#39;sex&#39;]==1.0) &amp; (X_train_linear[&#39;dataset&#39;]==3.0) &amp; (X_train_linear[&#39;chol&#39;]==385)]<br>)<br>print(&quot;\n----------------------------\n----------------------------\n----------------------------&quot;)<br><br># Store accuracies in a dictionary for comparison<br>accuracies[&#39;Ffill&#39;] = accuracy_ffill<br>accuracies[&#39;Bfill&#39;] = accuracy_bfill<br>accuracies[&#39;Linear&#39;] = accuracy_linear</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/248/1*qli42f9VVgOq9jMpNXH9rA.png" /><figcaption>‘Accuracy’ after Forward Fill Imputation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/962/1*Zg1xEy_zS9-4rJcosKbk5Q.png" /><figcaption>‘Dataset’ before and after Forward Fill Imputation</figcaption></figure><p><strong>Pros:</strong></p><ul><li>Suitable for time series data.</li><li>Provides a quick and simple solution.</li><li>Helps preserve variance in the dataset.</li></ul><p><strong>Cons:</strong></p><ul><li>May give incorrect results if missing values are consecutive.</li><li>Does not take trends and seasonality into account.</li><li>May ignore relationships between variables.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/262/1*z1fIeJ4J0aSl9_qpgoBs0Q.png" /><figcaption>‘Accuracy’ after Before Fill Imputation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/951/1*ImWrD3zYgUGSYmQhjRbkXw.png" /><figcaption>‘Dataset’ before and after Before Fill Imputation</figcaption></figure><p><strong>Pros:</strong></p><ul><li>Suitable for time series data.</li><li>Provides a quick and simple solution.</li><li>Helps preserve variance in the dataset.</li></ul><p><strong>Cons:</strong></p><ul><li>May give incorrect results if missing values are consecutive.</li><li>Does not take trends and seasonality into account.</li><li>May ignore relationships between variables.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/260/1*zqOmj5vl_olubTDdZmTVEQ.png" /><figcaption>‘Accuracy’ after Interpolation Imputation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*dGoum9UrChYb_CCzVNq9oA.png" /><figcaption>‘Dataset’ before and after Interpolation Imputation</figcaption></figure><p><strong>Pros:</strong></p><ul><li>It considers the relationships between variables.</li><li>Can provide more accurate forecasts.</li></ul><p><strong>Cons:</strong></p><ul><li>May increase the impact of outliers.</li><li>Cannot accurately model complex relationships.</li></ul><h4>5.5. Advanced Imputation Techniques (Prediction of Missing Values) (KNN — Linear Regression — Random Forest Regressor)</h4><p>In previous methods for handling missing values, we did not take advantage of the correlation between the variable containing the missing value and other variables. Using other features that do not have missing values can be used to estimate missing values. Depending on the nature of the feature with missing values, regression or classification models can be used to estimate missing values.</p><p><strong>a. K-Nearest Neighbors (KNN)</strong></p><p>KNN is a method that uses the K nearest neighbor algorithm to predict missing values. The algorithm identifies k data points to make a prediction. These k data points are those closest to the data point with the missing value. If the data set is continuous, the Euclidean distance can be used as a distance measure, and if the data set is categorical, the Hamming distance can be used.</p><pre>def knn_impute(X_train, X_test, y_train, y_test, k=5):<br>    &quot;&quot;&quot;<br>    Imputes missing values using the K-Nearest Neighbors (KNN) algorithm.<br><br>    Parameters:<br>    - X_train: pandas DataFrame, training dataset<br>    - X_test: pandas DataFrame, testing dataset<br>    - y_train: pandas Series, training labels<br>    - y_test: pandas Series, testing labels<br>    - k: int, number of neighbors for KNN imputation<br><br>    Returns:<br>    - X_train_imputed, X_test_imputed, y_train, y_test: pandas DataFrames and Series,<br>      imputed training and testing datasets along with labels<br>    &quot;&quot;&quot;<br>    knn_imputer = KNNImputer(n_neighbors=k)<br>    X_train_imputed = pd.DataFrame(knn_imputer.fit_transform(X_train), columns=X_train.columns)<br>    X_test_imputed = pd.DataFrame(knn_imputer.transform(X_test), columns=X_test.columns)<br>    return X_train_imputed, X_test_imputed, y_train, y_test<br><br># Read and preprocess the dataset<br>df = read_data()<br>X_train, X_test, y_train, y_test = split_dataset(df)<br><br># Impute missing values using KNN<br>X_train_imputed, X_test_imputed, y_train, y_test = knn_impute(X_train, X_test, y_train, y_test, k=10)<br><br># Train a Random Forest model on the imputed dataset<br>accuracy_knn = train_model_random_forest(X_train_imputed, X_test_imputed, y_train, y_test)<br><br># Store the accuracy of the model with KNN imputation in a dictionary<br>accuracies[&#39;KNN&#39;] = accuracy_knn<br><br># A specific data, after the procedure<br>print(&quot;\n------------------\n&quot;)<br>print(&quot;\nAfter Imputation: \n&quot;)<br>X_train_imputed[(X_train_imputed[&#39;age&#39;]==58.0) &amp; (X_train_imputed[&#39;sex&#39;]==1.0) &amp; (X_train_imputed[&#39;dataset&#39;]==3.0) &amp; (X_train_imputed[&#39;chol&#39;]==385)]</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/233/1*5pfHEsMBPn1upvznQ1tMCg.png" /><figcaption>‘Accuracy’ after KNN Imputation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/955/1*YPeTRHWfrzxmAB-5bRaz2g.png" /><figcaption>‘Dataset’ before and after KNN Imputation</figcaption></figure><p><strong>Pros:</strong></p><ul><li>Takes into account the relationship between variables.</li><li>Effectively handles categorical and numerical data.</li><li>Easily adaptable to new data points.</li></ul><p><strong>Cons:</strong></p><ul><li>Computational costs can be high for large datasets.</li><li>It may be difficult to determine the optimal K value.</li><li>Performance may be degraded for high-dimensional datasets.</li><li>Affected by outliers.</li></ul><p><strong>b. Linear Regression</strong></p><p>Linear Regression is a regression technique that expresses the relationship between the dependent variable and the independent variables in a linear model. It can be used to estimate missing values because it builds a linear model on the dataset with missing values.</p><pre>def linear_regression_impute(df, target_column, feature_columns):<br>    &quot;&quot;&quot;<br>    Imputes missing values using linear regression.<br><br>    Parameters:<br>    - df: pandas DataFrame, input dataset<br>    - target_column: str, target column with missing values to be imputed<br>    - feature_columns: list, feature columns used to predict missing values<br><br>    Returns:<br>    - pd.DataFrame, dataset with imputed missing values<br>    &quot;&quot;&quot;<br>    # Separate missing and non-missing values<br>    df_missing = df[df[target_column].isnull()]<br>    df_not_missing = df.dropna(subset=[target_column])<br><br>    # Create training and test sets for the model<br>    X_train = df_not_missing[feature_columns]<br>    y_train = df_not_missing[target_column]<br><br>    # Create a linear regression model<br>    model = LinearRegression()<br>    model.fit(X_train, y_train)<br><br>    # Predict missing values using the model<br>    X_missing = df_missing[feature_columns]<br>    predicted_values = model.predict(X_missing)<br><br>    # Create a dataset with imputed missing values<br>    df_filled = df.copy()<br>    df_filled.loc[df[target_column].isnull(), target_column] = predicted_values<br><br>    return df_filled<br><br><br># Impute missing values using linear regression<br>target_columns_to_impute = [&#39;trestbps&#39;, &#39;chol&#39;, &#39;thalch&#39;, &#39;oldpeak&#39;, &#39;ca&#39;]<br>feature_columns_for_imputation = [&#39;age&#39;, &#39;sex&#39;, &#39;dataset&#39;, &#39;cp&#39;, &#39;fbs&#39;, &#39;restecg&#39;, &#39;exang&#39;, &#39;slope&#39;, &#39;thal&#39;]<br><br>linear_data = read_data()<br><br>for target_column in target_columns_to_impute:<br>    linear_data = linear_regression_impute(linear_data, target_column, feature_columns_for_imputation)<br><br># Split the dataset after linear regression imputation<br>X_train, X_test, y_train, y_test = split_dataset(linear_data)<br><br># Train a Random Forest model on the imputed dataset<br>accuracy_linear_reg = train_model_random_forest(X_train, X_test, y_train, y_test)<br><br># Store the accuracy of the model with linear regression imputation in a dictionary<br>accuracies[&#39;Linear Regression&#39;] = accuracy_linear_reg<br><br># A specific data, after the procedure<br>print(&quot;\n------------------\n&quot;)<br>print(&quot;\nAfter Imputation: \n&quot;)<br>X_train[(X_train[&#39;age&#39;]==58.0) &amp; (X_train[&#39;sex&#39;]==1.0) &amp; (X_train[&#39;dataset&#39;]==3.0) &amp; (X_train[&#39;chol&#39;]==385)]</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/231/1*SziOXhGxD1BWnG2k9FnSPQ.png" /><figcaption>‘Accuracy’ after Linear Regression Imputation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/988/1*oGkTwWcLd1MwQHZoAOXwZw.png" /><figcaption>‘Dataset’ before and after Linear Regression Imputation</figcaption></figure><p><strong>Pros:</strong></p><ul><li>It takes into account the relationship between the variable containing the missing values and other variables.</li><li>It has a fast calculation time.</li></ul><p><strong>Cons:</strong></p><ul><li>It works on the assumption of a linear relationship between variables.</li><li>It cannot capture non-linear relationships in the dataset.</li><li>May be sensitive to the impact of outliers.</li></ul><p><strong>c. Random Forest Regressor</strong></p><p>Random Forest Regressor is an ensemble regression algorithm where many decision trees are built together and the predictions are aggregated. It can be used to predict missing values because it can work with both categorical and numerical data and it is possible to train the trees independently. In addition, these models usually have good accuracy and don&#39;t predict outliers.</p><pre>def random_forest_impute(df, target_column, feature_columns):<br>    &quot;&quot;&quot;<br>    Imputes missing values using Random Forest.<br><br>    Parameters:<br>    - df: pandas DataFrame, input dataset<br>    - target_column: str, target column with missing values to be imputed<br>    - feature_columns: list, feature columns used to predict missing values<br><br>    Returns:<br>    - pd.DataFrame, dataset with imputed missing values<br>    &quot;&quot;&quot;<br>    # Separate missing and non-missing values<br>    df_missing = df[df[target_column].isnull()]<br>    df_not_missing = df.dropna(subset=[target_column])<br><br>    # Create training and test sets for the model<br>    X_train = df_not_missing[feature_columns]<br>    y_train = df_not_missing[target_column]<br><br>    # Create a Random Forest regression model<br>    model = RandomForestRegressor(random_state=42)<br>    model.fit(X_train, y_train)<br><br>    # Predict missing values using the model<br>    X_missing = df_missing[feature_columns]<br>    predicted_values = model.predict(X_missing)<br><br>    # Create a dataset with imputed missing values<br>    df_filled = df.copy()<br>    df_filled.loc[df[target_column].isnull(), target_column] = predicted_values<br><br>    return df_filled<br><br><br># Impute missing values using Random Forest<br>target_columns_to_impute = [&#39;trestbps&#39;, &#39;chol&#39;, &#39;thalch&#39;, &#39;oldpeak&#39;, &#39;ca&#39;]<br>feature_columns_for_imputation = [&#39;age&#39;, &#39;sex&#39;, &#39;dataset&#39;, &#39;cp&#39;, &#39;fbs&#39;, &#39;restecg&#39;, &#39;exang&#39;, &#39;slope&#39;, &#39;thal&#39;]<br><br>random_data = read_data()<br><br>for target_column in target_columns_to_impute:<br>    random_data = random_forest_impute(random_data, target_column, feature_columns_for_imputation)<br><br># Split the dataset after Random Forest imputation<br>X_train, X_test, y_train, y_test = split_dataset(random_data)<br><br># Train a Random Forest model on the imputed dataset<br>accuracy_random_forest = train_model_random_forest(X_train, X_test, y_train, y_test)<br><br># Store the accuracy of the model with Random Forest imputation in a dictionary<br>accuracies[&#39;Random Forest&#39;] = accuracy_random_forest<br><br># A specific data, after the procedure<br>print(&quot;\n------------------\n&quot;)<br>print(&quot;\nAfter Imputation: \n&quot;)<br>X_train[(X_train[&#39;age&#39;]==58.0) &amp; (X_train[&#39;sex&#39;]==1.0) &amp; (X_train[&#39;dataset&#39;]==3.0) &amp; (X_train[&#39;chol&#39;]==385)]</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/243/1*O4PkqvdsUN3J-ZzScxZmAg.png" /><figcaption>‘Accuracy’ after Random Forest Imputation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*lJPMnijVDa810g6kdU51Xw.png" /><figcaption>‘Dataset’ before and after Random Forest Imputation</figcaption></figure><p><strong>Pros:</strong></p><ul><li>Provides high predictive performance</li><li>Resistant to the effect of outliers.</li><li>Useful for identifying important features in a dataset.</li></ul><p><strong>Cons:</strong></p><ul><li>Managing the complexity of the model can be difficult.</li><li>Hyperparameters such as number of trees and depth may need to be adjusted.</li><li>Training times can be long for large datasets.</li></ul><h3>6. Result</h3><p>Addressing missing values is a critical step in the data analysis process. There is no perfect way to fill in missing values in a dataset. Understanding why data is missing is crucial to manage the remaining data appropriately. Each method has advantages and disadvantages and is suitable for different types of missing data values. Furthermore, improper handling of missing data can affect the results of machine learning models and reduce model accuracy. Therefore, the correct assignment of missing values is critical in data analysis.</p><p>The following table shows the accuracy rates of the methods discussed in this paper. As can be seen from the table, in some cases, leaving missing data untouched or choosing the simplest method shows better results than other complex methods. Nevertheless, it should be kept in mind that these methods and the algorithms used in model building can directly change the result.</p><pre># Translate Dictionary to DataFrame<br>df = pd.DataFrame(list(accuracies.items()), columns=[&#39;Method&#39;, &#39;Accuracy&#39;])<br><br># Formatting<br>df[&#39;Accuracy&#39;] = df[&#39;Accuracy&#39;].apply(lambda x: round(x, 3))<br>df</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/258/1*-Wyx4DJuWtcHfay9Xs-jFQ.png" /><figcaption>Accuracies obtained in the models trained separately after examining the missing data with all methods</figcaption></figure><p>Thank you for reading and your questions and comments;</p><p>LinkedIn: <a href="https://www.linkedin.com/in/ramazanolmez/">https://www.linkedin.com/in/ramazanolmez/</a></p><p>Mail: ramazanolmeez@gmail.com</p><p><strong>Sources:</strong></p><ul><li>Galli, Soledad., Python Feature Engineering Cookbook</li><li>Ozdemir, Sinan., Susarla, Divya., Feature Engineering Made Easy: Identify unique features from your dataset in order to build powerful machine learning systems</li><li>Kuhn, Max., Johnson, Kjell., Feature Engineering and Selection: A Practical Approach for Predictive Models (Chapman &amp; Hall/CRC Data Science Series)</li><li><a href="https://towardsdatascience.com/7-ways-to-handle-missing-values-in-machine-learning-1a6326adf79e">https://towardsdatascience.com/7-ways-to-handle-missing-values-in-machine-learning-1a6326adf79e</a></li><li><a href="https://www.analyticsvidhya.com/blog/2021/10/end-to-end-introduction-to-handling-missing-values/">https://www.analyticsvidhya.com/blog/2021/10/end-to-end-introduction-to-handling-missing-values/</a></li><li><a href="https://www.analyticsvidhya.com/blog/2021/10/handling-missing-value/">https://www.analyticsvidhya.com/blog/2021/10/handling-missing-value/</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=42d7376ca94a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[LangChain: PDF’lerinizle Konuşun]]></title>
            <link>https://medium.com/@ramazanolmeez/langchain-pdflerinizle-konu%C5%9Fun-26ec73b33672?source=rss-b005bac7906e------2</link>
            <guid isPermaLink="false">https://medium.com/p/26ec73b33672</guid>
            <category><![CDATA[faiss]]></category>
            <category><![CDATA[openai]]></category>
            <category><![CDATA[embedding]]></category>
            <category><![CDATA[semantic-search]]></category>
            <category><![CDATA[langchain]]></category>
            <dc:creator><![CDATA[Ramazan Olmez]]></dc:creator>
            <pubDate>Thu, 25 Jan 2024 22:02:03 GMT</pubDate>
            <atom:updated>2024-01-25T22:02:03.607Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/502/1*jdTcEPDLeemBzrDnUDDxYA.png" /></figure><p>PDF’ler, bilgi depolamak için yaygın olarak kullanılan bir dosya formatıdır. Ancak, PDF’lerle etkileşim kurma şeklimiz hala oldukça sınırlıdır. Genellikle, PDF’leri okumak için bir PDF okuyucu kullanırız ve uzun metinlerden çıkarım yapmak oldukça zaman alır. Peki, PDF’lerle sohbet edebilsek nasıl olurdu? PDF’lere soru sorabilseydik ve sorularımıza doğru cevaplar alabilseydik?</p><p>Bu yazının amacı, kullanıcıların araştırma makalelerinden, yasal belgelerden ve eğitim materyallerinden istenilen bilginin çıkarımını kolaylaştırarak etkileşimli bir arayüz oluşturmaktır. Bu yazıda OpenAI, FAISS, Streamlit ve Langchain kullanarak PDF’lerle sohbet edebilmemize yarayan bir uygulama geliştiriyorum.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fplayer.vimeo.com%2Fvideo%2F906477315%3Fapp_id%3D122963&amp;dntp=1&amp;display_name=Vimeo&amp;url=https%3A%2F%2Fvimeo.com%2F906477315&amp;image=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F1788277799-aba92839f81159b66dbe5e88fcf6b96cb6f9a3eaaefc946a65c7bc67110b3b8e-d_960&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=vimeo" width="1268" height="682" frameborder="0" scrolling="no"><a href="https://medium.com/media/8a0d1ca44568bef3dc7d74db2ea0a0b3/href">https://medium.com/media/8a0d1ca44568bef3dc7d74db2ea0a0b3/href</a></iframe><h4>Bu Uygulama Ne İşe Yarayacak, ChatGPT veya Bard kullanamaz mıyız?</h4><p>Büyük dil modelleri hayatımızın her alanına girmeye devam ediyor. Bu modeller, metin oluşturma, dilleri çevirme, farklı türde yaratıcı içerikler yazma ve sorularınızı bilgilendirici bir şekilde yanıtlama gibi birçok görevi de gerçekleştirebiliyor. Fakat bu modeller eğitimlerinde kullanılmadıkları verilere dayanan soruları cevaplamakta zorlanıyor ve yanlış bilgiler üretebiliyor. Veya kişisel belgelerinizi, dökümanlarınızı internet ortamına yüklemek istemeyebiliyoruz. Yine de bu belgelerden bilgi çıkarımı yapma niyetindesiniz. İşte tam bu noktada bu uygulamayı kendi sisteminizde çalıştırabilir ve zaman kazanabilirsiniz.</p><p>Aşağıdaki görsellerde, ChatGPT ve uygulamanın aynı sorulara verdikleri yanıtlar gözükmektedir:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JpI6xWuqJRau4SVGZzyYxA.png" /><figcaption>Image by Author</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DzFRKIVpZbDCR2YX6xmtcg.png" /><figcaption>Image by Author</figcaption></figure><h4>Kullanılacak Teknolojiler</h4><p><a href="https://platform.openai.com/docs/guides/embeddings/what-are-embeddings"><strong>OpenAI Embeddings</strong></a><strong>:</strong> Metinlerin semantik anlamını temsil eden vektörler oluşturmak için kullanılır. Bu projede ise PDF belgelerinden çıkarılan metin parçalarını gömme (embedding) vektörlerine dönüştürerek, belgeler arasında semantik benzerlikleri ölçmek ve kullanıcının sorularını anlamlı şekillerde yanıtlamak amacıyla kullanılmıştır. Bu gömme vektörleri, bilgi tabanını (Vector Store — Knowledge Base) oluşturmak ve metinler arasındaki ilişkileri anlamak için kullanılan bir temel sağlar.</p><p><a href="https://faiss.ai/index.html"><strong>FAISS (Facebook AI Similarity Search)</strong></a><strong>:</strong> FAISS, metin gömme vektörlerini hızlı, etkili bir şekilde indeksleme ve benzerlik araması yapma amacıyla kullanılır. PDF belgelerinden elde edilen embedding vektörler, FAISS kullanılarak bir vektör deposunda saklanır ve semantik benzerlik aramalarında hızlı erişim sağlanır. Kullanıcı sorularına uygun belge parçalarını bulma sürecini optimize etmede önemli bir rol oynar.</p><p><a href="https://python.langchain.com/docs/get_started/introduction"><strong>LangChain</strong></a><strong>:</strong> Metin işleme, dil modeli yönetimi ve sohbet zinciri oluşturma süreçlerini sağlayabilmek adına kullanılır. Langchain, OpenAI Embeddings ve FAISS gibi araçları birleştirerek, PDF belgelerinden çıkarılan metinleri işleyip gömme vektörlerine dönüştürür, bu vektörleri hızlı bir şekilde indeksler ve kullanıcıların sorularına anlamlı yanıtlar üreten bir sohbet zinciri oluşturur. Bu, belgelerle etkileşimde bulunma yeteneğini güçlendiren ve kullanıcıların sorularına anlamlı şekillerde cevap veren bir temel sağlar.</p><p><a href="https://streamlit.io/"><strong>Streamlit</strong></a><strong>:</strong> İnteraktif bir kullanıcı arayüzü oluşturmak ve sohbeti görsel olarak gösterebilmek için kullanılır. Kullanıcılar, PDF belgelerini yükleyebilir, sorular sorabilir ve sistem tarafından sağlanan metin sonuçlarını anlık olarak görüntüleyebilir. Streamlit, projenin kullanıcı dostu bir şekilde etkileşimli olmasını sağlar.</p><h4>Proje Adımları</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pl74y8cOYdkL8lTacGa0zw.png" /><figcaption>Image by Author</figcaption></figure><ol><li><strong>Belgelerin Alınması</strong></li></ol><ul><li>Kullanıcıdan PDF&#39;leri alıyoruz. Bu adım, kullanıcının istediği sayıda belgeyi yükleyebilmesini sağlar. Bu işlem PyPDF2 kütüphanesi altında gerçekleşecektir.</li><li>PyPDF2, PDF dosyalarının sayfalarını bölme, birleştirme, kırpma ve dönüştürme yeteneğine sahip bir python kütüphanesidir. Ayrıca PyPDF2, PDF’lerden metin ve meta verileri de alabilir.</li></ul><p><strong>2. PDF’lerin Parçalara Ayrılması</strong></p><ul><li>PDF’lerin işlenebilmesi için metinlerin veya dökümanın parçalara (chunk) ayrılması gerekiyor. Her bir parça, PDF’deki metni temsil eder. Metni daha küçük parçalara bölerek daha anlamlı bir vektör temsili (embedding) elde edebiliriz.</li></ul><p><strong>3. Metin Parçalarının Sayısal Vektörlere Dönüştürülmesi</strong></p><ul><li>Metin parçalarını sayısal vektörlere (embeddings) dönüştürüyoruz. Embedding, metni sayısal bir temsile çevirir ve metnin anlamını korur. Bu adımı kelimelerin birbirleriyle olan ilişkisini koruyarak gerçekleştirir. Bu işlem metinler arasında benzerlikleri daha iyi bulabilmemizi ve metinleri sayısal bir şekilde temsil edebilmemizi sağlar.</li><li>Bu adım için HuggingFace’te bulunan çeşitli modeller veya klasik teknikler kullanılabilir. Bu proje kapsamında OpenAIEmbeddings kullanılacaktır. (OpenAI ücretli bir ürün olmasına rağmen, ürünlerinin 5$ değerinde ücret ödemeden kullanılmasına izin vermektedir.)</li></ul><p><strong>4. Kelime Vektörlerinin Saklanması</strong></p><ul><li>Elde ettiğimiz vektörleri bir veritabanında saklıyoruz. Bu işlem, daha sonra kullanıcının sorduğu sorulara benzer vektörleri anlamsal arama (semantic search) sayesinde bulmamızı sağlar.</li><li>Bu adım için Pinecone veya Chroma gibi vektör veritabanları kullanılabilir. Bu proje kapsamında FAISS kullanılacaktır.</li></ul><p><strong>5. Kullanıcı Sorularının Alınması</strong></p><ul><li>Kullanıcıdan PDF belgelerine sormak istediği sorular alınır. Bu adım, kullanıcının belgeleri hakkında bilgi edinmek istediği konuları belirtmesine olanak tanır.</li></ul><p><strong>6. Kullanıcı Sorularının Vektörlere Dönüştürülmesi</strong></p><ul><li>Kullanıcının sorduğu soruları da vektörlere dönüştürmek zorundayız. Bu sayede soruları, yüklenen PDF’lerde bulunan metinlerle anlamsal yakınlık olarak karşılaştırabiliriz.</li></ul><p><strong>7. Semantik Arama ve Sonuçların Gösterilmesi</strong></p><ul><li>Kelime vektörleri arasında semantik bir arama yaparak, kullanıcının sorusuyla ilgili benzer metinler bulunur. Bu benzer metinler, dil modeli kullanılıp sıralanarak kullanıcıya sunulur.</li></ul><h4>Bağımlılıkların Yüklenmesi</h4><p>Proje kapsamında bazı bağımlılıkları kullanabilmek için önceden yüklemek gerekiyor. Bu bağımlılıklar ve amaçları şu şekildedir:</p><ul><li>streamlit: Grafiksel kullanıcı arayüzü oluşturabilmek</li><li>PyPDF2: PDF dosyalarını okuyabilmek</li><li>langchain: Dil modeliyle etkileşime girebilmek</li><li>dotenv: OpenAI API anahtarını gizli bir şekilde kullanabilmek</li><li>FAISS: Vektör deposu olarak kullanabilmek</li><li>openai: OpenAI dil modeline erişim</li><li>huggingface_hub: Dil modeli olarak OpenAI alternatifleri kullanabilmek</li></ul><p>Bu bağımlılıkları pip kullanarak şu şekilde yükleyebilirsiniz;</p><pre>pip install streamlit pypdf2 langchain python-dotenv faiss-cpu openai huggingface_hub</pre><h4>Proje</h4><p>Projeye, gereken kütüphaneleri yüklemekle başlıyoruz.</p><pre>import streamlit as st<br>from dotenv import load_dotenv<br>from PyPDF2 import PdfReader<br>from langchain.text_splitter import CharacterTextSplitter<br>from langchain.embeddings import OpenAIEmbeddings, HuggingFaceInstructEmbeddings<br>from langchain.vectorstores import FAISS<br>from langchain.chat_models import ChatOpenAI<br>from langchain.memory import ConversationBufferMemory<br>from langchain.chains import ConversationalRetrievalChain<br>from htmlTemplates import css, bot_template, user_template<br>from langchain.llms import HuggingFaceHub</pre><p>get_pdf_textfonksiyonu, kullanıcının yüklediği PDF belgelerinden metinleri çıkarabilmek için kullanılır. Parametre olarak pdf_docs adında bir liste alır. Bu liste yüklenen PDF belgelerini içerir. Her bir PDF belgesini açar, her sayfadaki metni çıkarır ve bu metinleri birleştirerek tek bir metin haline getirir. Oluşturulan bu tek metni geri döndürür.</p><pre>def get_pdf_text(pdf_docs):<br>    text = &quot;&quot;<br>    for pdf in pdf_docs:<br>        pdf_reader = PdfReader(pdf)<br>        for page in pdf_reader.pages:<br>            text += page.extract_text()<br>    return text</pre><p>get_text_chunksfonksiyonu, bir metni daha küçük parçalara bölmek için kullanılır. Parametre olarak yukarıdaki fonksiyonda tek bir metin haline getirilen PDF metinlerini alır. Metni CharacterTextSplitter sınıfı sayesinde belirli bir boyutta küçük parçalara ayırır. Bu parçaların her birisine chunk denir.</p><pre>def get_text_chunks(text):<br>    text_splitter = CharacterTextSplitter(<br>        separator=&quot;\n&quot;,<br>        chunk_size=1000,<br>        chunk_overlap=200,<br>        length_function=len<br>    )<br>    chunks = text_splitter.split_text(text)<br>    return chunks</pre><p>get_vectorstorefonksiyonu, metin parçalarını embeddinglere dönüştürüp bir bilgi tabanı oluşturmak için kullanılır. Embedding işlemi için OpenAIEmbeddings kullanılır ve bu vektörleri içeren bir FAISS nesnesi oluşturulur. Embedding işlemi için HuggingFace üzerinden <a href="https://huggingface.co/hkunlp/instructor-xl">instructor-xl</a> gibi ücretsiz modeller de kullanılabilir.</p><pre>def get_vectorstore(text_chunks):<br>    embeddings = OpenAIEmbeddings()<br>    #for free embedding model;<br>    #embeddings = HuggingFaceInstructEmbeddings(model_name=&quot;hkunlp/instructor-xl&quot;)<br>    vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embeddings)<br>    return vectorstore</pre><p>get_conversation_chainfonksiyonu, sohbet zincirini oluşturmak için kullanılır. Parametre olarak vectorstore adında bir vektör kaynağı alır ve bu kaynak embedding vektörlerini içerir. Dil modeli olarak ChatOpenAI kullanılır ve bu dil modeli ile birlikte bir konuşma zinciri oluşturulur. Ayrıca, geçmiş sohbetleri saklamak için bir bellek (ConversationBufferMemory) oluşturulur.</p><p>Embedding için farklı alternatifler olduğu gibi, sohbet zinciri yaratırken de farklı dil modelleri alternatifleri vardır. OpenAI yerine, Google’ın <a href="https://huggingface.co/google/flan-t5-xxl">flan-t5</a> modeli gibi modeller kullanılabilir.</p><pre>def get_conversation_chain(vectorstore):<br>    llm = ChatOpenAI()<br>    # llm = HuggingFaceHub(repo_id=&quot;google/flan-t5-xxl&quot;, model_kwargs={&quot;temperature&quot;:0.5, &quot;max_length&quot;:512})<br><br>    memory = ConversationBufferMemory(memory_key=&#39;chat_history&#39;, return_messages=True)<br>    conversation_chain = ConversationalRetrievalChain.from_llm(<br>        llm=llm,<br>        retriever=vectorstore.as_retriever(),<br>        memory=memory<br>    )<br>    return conversation_chain</pre><p>handle_userinputfonksiyonu, kullanıcının sorduğu soruya yanıt vermek için kullanılır. Parametre olarak user_question adında bir metin alır, bu metin kullanıcının sorduğu soruyu içerir. Konuşma zinciri nesnesi üzerinden kullanıcının sorusuna yanıt alınır. Alınan yanıtlar, kullanıcı ve bot mesajlarını içeren bir hafızaya eklenir. Sonuçlar, Streamlit tarafından oluşturulan arayüz üzerinde kullanıcıya gösterilir.</p><pre>def handle_userinput(user_question):<br>    response = st.session_state.conversation({&#39;question&#39;: user_question})<br>    st.session_state.chat_history = response[&#39;chat_history&#39;]<br><br>    for i, message in enumerate(st.session_state.chat_history):<br>        if i % 2 == 0:<br>            st.write(user_template.replace(<br>                &quot;{{MSG}}&quot;, message.content), unsafe_allow_html=True)<br>        else:<br>            st.write(bot_template.replace(<br>                &quot;{{MSG}}&quot;, message.content), unsafe_allow_html=True)</pre><p>Fonksiyonlardan sonra arayüzü oluşturmaya, kontrolleri ve işlemleri gerçekleştirmeye başlayabiliriz.</p><p>Aşağıdaki adımlara geçmeden önce, OpenAI API anahtarını ana dosyada tutmak yerine .env isimli bir klasör açarak orada saklamanızı öneririm. Bu sayede anahtarı herkese açık bir şekilde paylaşmaktan kurtulabiliriz.<br>.env dosyası aşağıdaki gibi olacaktır:</p><pre>OPENAI_API_KEY=&lt;YOUR_OPENAI_API_KEY&gt;<br>HUGGINGFACEHUB_API_TOKEN=&lt;YOUR_HUGGINGFACE_API_TOKEN&gt;</pre><p>.env dosyasını oluşturup API anahtarlarınızı girdikten sonra ana dosyadan devam ediyoruz.</p><p>load_dotenv() ile API anahtarlarımıza erişiyoruz. Daha sonra sayfa başlığı ve simgesini ayarlayarak, oturumun durumunu kontrol ederek devam ediyoruz. Oturum durumu, Streamlit’in sayfayı yenileme isteğini kontrol etmemizi sağlar.</p><pre>load_dotenv()<br>st.set_page_config(page_title=&quot;İçine atma&quot;)<br>st.write(css, unsafe_allow_html=True)<br><br>if &quot;conversation&quot; not in st.session_state:<br>    st.session_state.conversation = None<br>if &quot;chat_history&quot; not in st.session_state:<br>    st.session_state.chat_history = None<br><br>st.header(&quot;PDF&#39;lerinizle Konuşun&quot;)</pre><p>Kullanıcının sorularını girebileceği bir metin girişi alanı oluşturuyoruz. Kullanıcı bir soru girişinde bulunduğunda, bu soru handle_userinput fonksiyonuna iletiliyor.</p><pre>user_question = st.text_input(&quot;Sorunuz: &quot;)<br>if user_question:<br>    handle_userinput(user_question)</pre><p>Bu bölümde, kullanıcının yüklediği PDF belgelerini işlemek ve sohbet zinciri oluşturmak için gerekli adımlar yer alıyor. Kullanıcı belgeleri yükledikten sonra “Isle” düğmesine tıklarsa, PDF’lerden metinler çıkarılır, metinler parçalara ayrılır, kelime vektörleri (embeddings) oluşturulur ve son olarak bir sohbet zinciri başlatılır.</p><pre>with st.sidebar:<br>    st.subheader(&quot;Dökümanlarınız&quot;)<br>    pdf_docs = st.file_uploader(<br>        &quot;PDF&#39;lerinizi yükleyin ve &#39;İşle&#39;ye basınız&quot;, accept_multiple_files=True)<br>    if st.button(&quot;İşle&quot;):<br>        with st.spinner(&quot;İşleniyor&quot;):<br>            raw_text = get_pdf_text(pdf_docs)<br>            text_chunks = get_text_chunks(raw_text)<br>            vectorstore = get_vectorstore(text_chunks)<br>            st.session_state.conversation = get_conversation_chain(<br>                vectorstore)</pre><p>Dosyayı çalıştırmak için aşağıdaki kodun kullanılması yeterli olacaktır.</p><pre>streamlit run app.py</pre><p>PDF’ler ile bilgi çıkarımı Streamlit arayüzü ile birlikte hazır. Tüm projeyi <a href="https://github.com/rolmez/langchain-PDFlerinizle-konusun">Github</a> reposunda bulabilirsiniz.</p><p>Okuduğunuz için teşekkür ediyorum. Soru ve görüşleriniz için aşağıdaki linklerden ulaşabilirsiniz:</p><p>LinkedIn: <a href="https://www.linkedin.com/in/ramazanolmez/">https://www.linkedin.com/in/ramazanolmez/</a><br>Mail: ramazanolmeez@gmail.com</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=26ec73b33672" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Metin Sınıflandırma: Başlangıçtan BERT’e]]></title>
            <link>https://medium.com/@ramazanolmeez/metin-s%C4%B1n%C4%B1fland%C4%B1rma-ba%C5%9Flang%C4%B1%C3%A7tan-berte-7ac6620ca543?source=rss-b005bac7906e------2</link>
            <guid isPermaLink="false">https://medium.com/p/7ac6620ca543</guid>
            <category><![CDATA[bert]]></category>
            <category><![CDATA[text-classification]]></category>
            <category><![CDATA[metin-sınıflandırma]]></category>
            <category><![CDATA[lstm]]></category>
            <category><![CDATA[deep-learning]]></category>
            <dc:creator><![CDATA[Ramazan Olmez]]></dc:creator>
            <pubDate>Thu, 18 Jan 2024 11:13:26 GMT</pubDate>
            <atom:updated>2024-01-19T07:31:15.783Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>Bu yazı genelinde metin sınıflandırmanın ne demek olduğundan, metin ön işleme yöntemlerinden ve kelime gösterim tekniklerinden kısa bir şekilde bahsedip Feed Forward Network, Conv1D, LSTM ve BERT kullanarak modeller geliştiriyorum. Yazının tamamını okumak istemiyorsanız, içerikler kısmından ilgilendiğiniz bölüme atlayabilirsiniz. Keyifli okumalar</blockquote><p>· <a href="#3774">1. Metin Sınıflandırma Nedir</a><br>· <a href="#2533">2. Metin Ön İşleme Yöntemleri</a><br>· <a href="#e38f">3. Kelime Gösterim Teknikleri</a><br>· <a href="#2a2d">4. Model Geliştirme Aşaması</a><br> ∘ <a href="#a7ac">Gerekli Kütüphanelerin Yüklenmesi</a><br> ∘ <a href="#4669">Veri Setinin Yüklenmesi</a><br> ∘ <a href="#929f">Veri Setinin Hazırlanması</a><br> ∘ <a href="#e16c">FEED FORWARD NETWORK</a><br> ∘ <a href="#01f0">Convolutional Layer (Conv1D)</a><br> ∘ <a href="#c329">LSTM</a><br> ∘ <a href="#698f">BERT</a><br>· <a href="#3956">5. Sonuç</a></p><h3>1. Metin Sınıflandırma Nedir</h3><p>Metin sınıflandırma, doğal dil işleme için klasik bir konudur. Metinleri kategorize etme veya etiketlerini içeriğine göre sınıflara ayırma işlemidir. Doğal dil işlemenin önemli alanlarından birisidir. Çünkü günün sonunda mailimize gelen bir e-postanın spam olup olmadığını incelemeden, filtrelenmiş bir şekilde görmek isteriz.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*sooYKevubJBDP2RY.png" /></figure><p>Bilgi çıkarımı, duygu analizi, tavsiye sistemleri, bilgi yönetimi, döküman özetleme, haber sınıflandırma, email sınıflandırma ve spam filtreleme gibi konularda birçok önemli uygulamaya sahiptir. Sağlık, sosyal bilimler, işletme, pazarlama ve hukuk gibi birçok sektörde sıklıkla kullanılır. Bu nedenle, birçok araştırmacı için bir cazibe kaynağı haline gelmiştir.</p><h3>2. Metin Ön İşleme Yöntemleri</h3><p>Metin sınıflandırma tekniklerine geçmeden önce metin verileri ile çalışmanın zorluklarının birkaçından bahsetmek istiyorum.</p><ul><li><strong>Karmaşık ve anlamsal zorluk:</strong> Metin verileri, sayısal verilere göre karmaşık ve anlamsal olarak daha zengindir. Kelimelerin farklı bağlamlarda farklı anlamları olabilir, bu da modelin doğru bir şekilde anlam çıkarmasını zorlaştırabilir.</li><li><strong>Gürültü ve tutarsızlık:</strong> Veri setinde birçok yazım hatası (özellikle sosyal medya verilerinde), yanlış bilgiler ve argo ifadeler gibi gürültüler bulunabilir. Bunların temizlenmesi gerektiği durumlarda iş yükü artar.</li><li><strong>Dengesiz veri dağılımı:</strong> Eğitim verilerindeki sınıflar arasında dengesizlik olabilir. Bu da modelin yanlı davranmsına veya iyi öğrenememesine yol açar.</li></ul><p>Bu zorlukların farkında olmak ve bunları azaltmak için önlemler almak, daha doğru ve güvenilir modeller geliştirmeye yardımcı olur. Metin verileri ile çalışmanın zorluklarını azaltan bazı teknikler:</p><ul><li>Tokenleştirme (Tokenization)</li><li>Önemli bir anlam içermeyen kelimelerin kaldırılması (Remove Stop Words)</li><li>Büyük harflerin dönüştürülmesi (Capitalization)</li><li>Argo ve kısaltmaların veri setinden kaldırılması</li><li>Noktalama işaretleri ve özel karakterler gibi gürültülerin kaldırılması</li><li>Yazım hatalarını düzeltme (Spelling Correction)</li><li>Kök çıkarma (Stemming)</li><li>Kelimenin son ekinin çıkarılması (Lemmatization)</li></ul><p>Bu tekniklerin hepsi uygulanmak zorunda değildir. Veri setinin durumuna ve ihtiyaca göre metin ön işleme adımı gerçekleştirilir.</p><h3>3. Kelime Gösterim Teknikleri</h3><p>Ön işleme adımından sonra çözülmesi gereken bir başka sorun metinlerin gösterimidir. Bilgisayarlar metin içindeki kelimeleri anlamak ve işlemek için sayısal bir temsil kullanırlar. Bu temsil, kelimelerin özelliklerini ve birbirleriyle ilişkilerini içeren bir matematiksel formül veya vektör olabilir. Bu temsile <strong>“Word Representation”</strong> denir. Bazı veri temsil yöntemleri:</p><ul><li>One-hot-encoding</li><li>N-Gram</li><li>Bag-of-Words (BoW)</li><li>TF-IDF</li><li>Word2Vec - GloVe - FastText</li><li>Embedding Layer</li></ul><p>Metin sınıflandırma için kullanılabilecek birçok farklı makine öğrenmesi temelli teknik vardır. Naive Bayes, SVM, KNN, Karar Ağaçları bu tekniklerden bazılarına örnektir. Yapılan araştırmalar bu algoritmaların çok iyi sonuçlar verdiğini göstermiş olsa da bu yazıda sinir ağları tabanlı yöntemler ile model geliştireceğim.</p><p>Sinir ağlarındaki en önemli özelliklerden biri, giriş verileri ne kadar kirli veya gürültülü olursa olsun, sinir ağının ağırlıkları doğru sınıf tahmin edilene kadar geri yayılım ile tekrar tekrar ayarlamasıdır.</p><h3>4. Model Geliştirme Aşaması</h3><p>Model eğitiminde, HuggingFace kütüphanesinde bulunan 10 farklı kategoriye sahip Türkçe “<a href="https://huggingface.co/datasets/interpress_news_category_tr_lite">interpress_news_category_tr_lite</a>” veri setini kullanacağım.</p><h4>Gerekli Kütüphanelerin Yüklenmesi</h4><pre>import os<br>import sys<br>import csv<br>import warnings<br>import re<br>import string<br>import random<br>import numpy as np<br>import pandas as pd<br>import matplotlib.pyplot as plt<br><br># Train Test Split and Metrics from sklearn<br>from sklearn.model_selection import train_test_split<br>from sklearn import metrics<br><br># Tensorflow<br>import tensorflow as tf<br>from tensorflow import keras<br>from tensorflow.keras import layers<br>from tensorflow.keras.layers.experimental.preprocessing import TextVectorization<br><br># HuggingFace<br>from datasets import load_dataset<br>        <br>pd.set_option(&quot;max_colwidth&quot;, 400)</pre><p><em>Veri setini yüklerken çalışma ortamınızda </em><strong><em>“field larger than field limit (131072)”</em></strong><em> hatasını alırsanız aşağıdaki bloğu da ekleyin.</em></p><pre>csv.field_size_limit(sys.maxsize)<br>warnings.filterwarnings(&#39;ignore&#39;)</pre><h4>Veri Setinin Yüklenmesi</h4><pre>train_dataset = load_dataset(&quot;interpress_news_category_tr_lite&quot;, split=&quot;train&quot;)<br>test_dataset = load_dataset(&quot;interpress_news_category_tr_lite&quot;, split=&quot;test&quot;)<br><br>df_train = train_dataset.to_pandas()<br>df_test = test_dataset.to_pandas()<br>data = pd.concat([df_train, df_test], ignore_index=True)<br><br>data.drop_duplicates(subset=&#39;content&#39;, keep=&#39;first&#39;, inplace=True, ignore_index=True)</pre><p>Veri kümesi HuggingFace ortamına train ve test olarak bölünüp 2 parça şekilde yüklenmiş. Ben bu bölme işlemini kendim yapmak istediğim için veri setini tek bir parça haline getiriyorum. Ayrıca birden fazla kez geçen metinlerin kaldırılma işlemini de bu aşamada gerçekleştiriyorum. Bir de veri setindeki her bir kategoride kaç örnek olduğuna bakalım.</p><pre>unique_counts = data[&#39;category&#39;].value_counts().reset_index()<br>unique_counts.columns = [&#39;category&#39;, &#39;count&#39;]<br><br>plt.figure(figsize=(8, 8))<br>plt.pie(unique_counts[&#39;count&#39;], labels=unique_counts[&#39;category&#39;], autopct=&#39;%1.1f%%&#39;, startangle=90, colors=plt.cm.Set3.colors)<br><br>plt.title(&#39;Kategori Dağılımı&#39;)<br><br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*ThBfTVWhFJWEzOliTebFJA.png" /><figcaption>By Author</figcaption></figure><p>Grafikte görüldüğü gibi veri setinin yaklaşık %50&#39;si 2 kategoriden meydana geliyor. Veri setini bu şekilde kullanabilirdik. Ancak <a href="https://tr.wikipedia.org/wiki/A%C5%9F%C4%B1r%C4%B1_%C3%B6%C4%9Frenme">aşırı öğrenmeyi</a> engellemek için kategorilerin birbirlerine yakın sayıda olmasını istedim. Bu sorunun <a href="https://towardsdatascience.com/data-augmentation-library-for-text-9661736b13ff">data augmentation</a> gibi çeşitli çözümleri olsa da, çok az sayıda olan kategorileri silmeyi tercih ettim.</p><pre>delete_categories = [2, 3, 4, 5, 7, 9]<br>data = data[~data[&#39;category&#39;].isin(delete_categories)]<br>data[&#39;category&#39;].replace({0: 0, 1: 1, 6: 2, 8: 3}, inplace=True)</pre><p>2, 3, 4, 5, 7, 9 numaraları kategorileri silerek model geliştirmeye 4 kategori ile devam ediyorum. Kafa karışıklığı yaratmaması için kalan kategorileri 0, 3 arasında numaralandırdım. Hazırlanan veri setinde kategoriler şu anlama geliyor:</p><ul><li>0 -&gt; Kültür-Sanat</li><li>1 -&gt; Ekonomi</li><li>2 -&gt; Teknoloji</li><li>3 -&gt; Sağlık</li></ul><p>Az sayıda örneğe sahip olan kategoriler silindikten sonra kalan 4 kategoriden birer örnek:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/983/1*q4DSWziy_ZilD8eMC-9kSg.png" /><figcaption>By Author</figcaption></figure><p>Küçük boyuttaki metin örnekleri genellikle daha az bilgi içerir ve bu da modelin genelleme yeteneğini sınırlayabilir. Bu tarz metinler cümlenin bağlamını anlamak için de yetersiz olabilir. Bu sebeplerden dolayı cümlelerdeki kelime sayısına göre bir filtreleme yaparak 50 den az kelimeden oluşan cümleleri veri setinden kaldırdım. Küçük boyuttaki metinler problem oluşturduğu gibi, çok büyük boyuttaki metinler de problem oluşturuyor. Bunları da veri setinden çıkartmaya karar verdim fakat bu işlemi şu aşamada değil, Embedding katmanında gerçekleştireceğim.</p><pre>min_content_size = 50<br>data = data[data[&quot;words&quot;] &gt;= min_content_size]</pre><h4>Veri Setinin Hazırlanması</h4><p>Modelde kullanacağımız sözlüğü oluşturma aşamasına geliyoruz. Fakat sözlüğü oluşturmadan önce data leakage’e uğramamak adına <a href="https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html">train-test bölme işlemini </a>gerçekleştiriyorum. Veri setinin %80&#39;lik kısmını eğitime, %20&#39;lik kısmını teste ayırdım. Bu oranları kendi modelinize göre optimize edebilirsiniz.</p><pre><br>features, targets = data[&quot;content&quot;], data[&quot;category&quot;]<br><br>train_features, test_features, \<br>train_targets, test_targets = train_test_split(<br>    features, <br>    targets, <br>    train_size=0.8, <br>    test_size=0.2, <br>    random_state=42, <br>    shuffle=True, <br>    stratify=targets<br>)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/165/1*rCGaFwfvcll1V2oawDFgQg.png" /><figcaption>Oluşturulan veri setinde 109342 adet eğitim verisi, 27336 adet test verisi vardır.</figcaption></figure><p>Büyük veri setlerini etkili bir şekilde işlemek ve eğitim sürecinde veriyi modele beslemek için uygun bir veri yapısı sağlanmalıdır. Bu gereksinimi TensorFlow veri seti oluşturarak çözüyorum. Verileri bu yapıya dönüştürmek;</p><ul><li>Çeşitli veri tiplerini kullanabilme esnekliği sağlar</li><li>Bellek kullanımı ve eğitim süresini optimize etmeye yardımcı olur</li><li>Batching, shuffling gibi işlemlerin kontrol edilmesini kolaylaştırır</li></ul><pre>train_text_ds_raw = tf.data.Dataset.from_tensor_slices(tf.cast(train_features.values, tf.string))<br>train_cat_ds_raw = tf.data.Dataset.from_tensor_slices(tf.cast(train_targets.values, tf.int64))</pre><p>TensorFlow veri seti oluşturma işleminden sonra karar verilmesi gereken bir nokta, sözlüğün boyutudur. Sözlük boyutu, eğitimde kullanılacak kelime sınırıdır. Sözlük boyutunu en sık kullanılan 50000 kelime olarak belirledim. Sözlüğe eklenmeyen kelimeler &lt;UNK&gt; olarak gözükecektir. Bu sayı, veri setine ve donanım özelliklerine göre değişebilir. En uygun değer hiper parametre seçimi ile bulunabilir. Ayrıca, max_len parametresiyle belirlediğim maksimum kelime uzunluğu da önemlidir. Bu değer, her bir metin örneğinin kaç kelime içereceğini belirler. Örneğin, max_len’i 100 olarak belirlersek, her metin örneği en fazla 100 kelime içerecektir. Bu, modelin daha küçük veya daha büyük metin örnekleriyle çalışmasını sağlar. Ancak, bu değeri seçerken de veri setinin doğasını ve işlem süresini göz önünde bulundurmalıyız.</p><pre>vocab_size = 50000<br>max_len = 500</pre><p>Sözlük boyutu (vocab_size) ve maksimum uzunluğa (max_len) karar verdikten sonra sıra ön işleme aşamasına geldi. Bu adımda <a href="https://keras.io/api/layers/preprocessing_layers/text/text_vectorization/">Keras TextVectorization</a> kullanarak metni standart hale getireceğim. Keras TetxtVectorization, uçtan uca modeller oluşturabilmemizi ve bu modellere vereceğimiz giriş verilerini dönüştürebileceğimiz bir pipeline sağlar. Bunu yapabilmek için dekoratör yardımıyla aşağıdaki ön işlem adımlarını uyguluyorum.</p><pre>@tf.keras.utils.register_keras_serializable()<br>def custom_standardization(input_string):<br>    uppercased = tf.strings.lower(input_string, encoding=&#39;utf-8&#39;)<br>    stars = tf.strings.regex_replace(uppercased, &quot;\*&quot;, &quot; &quot;)<br>    html = tf.strings.regex_replace(stars, &quot;&lt;br /&gt;&quot;, &quot;&quot;)<br>    digits = tf.strings.regex_replace(html, &quot;\w*\d\w*&quot;,&quot;&quot;)<br>    punctuations = tf.strings.regex_replace(digits, f&quot;([{string.punctuation}])&quot;, r&quot; &quot;)<br>    extra_space = tf.strings.regex_replace(punctuations, &quot; +&quot;,&quot; &quot;)<br>    <br>    # Turkce karakterlere ozgu donusumler<br>    no_I = tf.strings.regex_replace(extra_space, &quot;ı&quot;,&quot;i&quot;)<br>    no_O = tf.strings.regex_replace(no_I, &quot;ö&quot;,&quot;o&quot;)<br>    no_C = tf.strings.regex_replace(no_O, &quot;ç&quot;,&quot;c&quot;)<br>    no_S = tf.strings.regex_replace(no_C, &quot;ş&quot;,&quot;s&quot;)<br>    no_G = tf.strings.regex_replace(no_S, &quot;ğ&quot;,&quot;g&quot;)<br>    no_U = tf.strings.regex_replace(no_G, &quot;ü&quot;,&quot;u&quot;)<br>    return no_U</pre><p><em>custom_standardization()</em> fonksiyonu, modeli veriler ile beslemeden önce önemli bir rol oynar. Tutarlılığı sağlamak ve gürültüyü azaltmak için bir dizi temizleme adımı uygular.</p><pre>vectorize_layer = TextVectorization(<br>    standardize=custom_standardization,<br>    max_tokens=vocab_size - 1,<br>    output_mode=&quot;int&quot;,<br>    output_sequence_length=max_len,<br>)<br><br>vectorize_layer.adapt(train_text_ds_raw)</pre><p><em>TextVectorization()</em> katmanı ise, metni modelin anlayabileceği sayısal gösterimlere dönüştürmekten sorumludur. İki temel görevi yerine getirir:</p><ul><li>Metni düzenlemek için oluşturulmuş olan <em>custom_standardization</em> fonksiyonunu kullanarak metni standart hale getirir.</li><li>Metni tokenlere böler ve her tokene eşsiz bir integer değer atar.</li></ul><p>Kelime katmanı oluşturulduktan sonra <em>adapt()</em> fonksiyonu ile öğrenilmelidir. Burada TextVectorization uygularken sadece eğitim veri setine uyguladığımı belirtmek istiyorum. Veri sızıntılarından (data leakage) kaçınmak için hem eğitim hem test verisine uygulamamalıyız.</p><pre>vocab = vectorize_layer.get_vocabulary()<br>vocab</pre><p>En sık geçen 50000 kelimeden oluşan vocabulary’nin bir kısmı bu şekildedir.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/104/1*HIkF9tmQsEWPfG03RCBcbg.png" /></figure><p>Oluşturulan TextVectorization katmanı bir keras modeline aşağıdaki şekilde entegre edilir.</p><pre>vectorizer_model = tf.keras.models.Sequential()<br>vectorizer_model.add(tf.keras.Input(shape=(1,), dtype=tf.string))<br>vectorizer_model.add(vectorize_layer)</pre><p>Eğitim veri seti, hazırlanan metin verileri ve ilgili sınıf etiketleri ile birleştirilir.</p><pre>def prepare_lm_inputs_labels(text):<br>    text = tf.expand_dims(text, -1)<br>    return tf.squeeze(vectorize_layer(text))<br><br>train_text_ds = train_text_ds_raw.map(<br>    prepare_lm_inputs_labels,<br>    num_parallel_calls=tf.data.experimental.AUTOTUNE<br>)<br><br>train_ds = tf.data.Dataset.zip((<br>    train_text_ds,<br>    train_cat_ds_raw<br>))<br><br>train_size = train_ds.cardinality().numpy()</pre><p>Aynı işlemler test veri seti için de yapılmalıdır.</p><pre>test_text_ds_raw = tf.data.Dataset.from_tensor_slices(<br>    tf.cast(test_features.values, tf.string)<br>)<br><br>test_cat_ds_raw = tf.data.Dataset.from_tensor_slices(<br>    tf.cast(test_targets.values, tf.int64)<br>)<br><br><br>test_text_ds = test_text_ds_raw.map(<br>    prepare_lm_inputs_labels,<br>    num_parallel_calls=tf.data.experimental.AUTOTUNE<br>)<br><br>test_ds = tf.data.Dataset.zip((<br>    test_text_ds,<br>    test_cat_ds_raw<br>))<br><br>test_size = test_ds.cardinality().numpy()</pre><p>Artık eğitim ve test veri kümelerini yapılandırabilir ve optimize edebiliriz. Eğitim veri seti karıştırılarak, belirli bir boyuta <a href="https://medium.com/analytics-vidhya/when-and-why-are-batches-used-in-machine-learning-acda4eb00763">batch</a>’lenir, önbelleğe alınır ve performans artırımı için önceden yüklenir.</p><pre>batch_size = 64<br>AUTOTUNE = tf.data.experimental.AUTOTUNE<br><br>train_ds = train_ds.shuffle(buffer_size=train_size)<br>train_ds = train_ds.batch(batch_size=batch_size,drop_remainder=True)<br>train_ds = train_ds.cache()<br>train_ds = train_ds.prefetch(AUTOTUNE)<br><br>test_ds = test_ds.shuffle(buffer_size=train_size)<br>test_ds = test_ds.batch(batch_size=batch_size,drop_remainder=True)<br>test_ds = test_ds.cache()<br>test_ds = test_ds.prefetch(AUTOTUNE)</pre><pre>desired_time_steps = 64<br>desired_feature_dim = 500<br><br>def reshape_data(x, y):<br>    x_reshaped = tf.reshape(x, (desired_time_steps, desired_feature_dim))<br>    return x_reshaped, y<br><br>train_ds = train_ds.map(reshape_data)<br>test_ds = test_ds.map(reshape_data)</pre><p>Veri setinin giriş boyutları, reshape_data fonksiyonu ile belirli bir zaman adımı ve özellik boyutu için yeniden şekillendirilir.</p><h4>FEED FORWARD NETWORK</h4><p>İleri beslemeli ağ eğitimine başlamadan önce <a href="https://keras.io/api/layers/core_layers/embedding/">Keras Embedding</a> katmanından biraz bahsetmek istiyorum. Bu katman, metin temsilini gerçekleştirmek için kullanılır. Embedding katmanı rastgele ağırlıklarla başlatılır. Farklı amaçlarla kullanımları mümkündür.</p><ul><li>Kaydedilip daha sonra başka bir modelde kullanılabilecek bir kelime yerleştirmeyi öğrenmek için tek başına kullanılabilir.</li><li>Gömmenin modelin kendisi ile birlikte öğrenildiği derin öğrenme modelinin bir parçası olarak kullanılabilir.</li><li>Bir tür transfer öğrenimi olan, önceden eğitilmiş bir kelime yerleştirme modelini yüklemek için kullanılabilir.</li></ul><p>Embedding Layer kullanabilmek için 3 argüman belirmeliyiz:</p><ul><li>input_dim: Bu, metin verilerindeki kelime dağarcığının boyutudur. Örneğin, verileriniz 0–10 arasındaki değerlere kodlanmış tamsayı ise kelime dağarcığının boyutu 11 kelime olacaktır.</li><li>output_dim: Bu, kelimelerin yerleştirileceği vektör uzayının boyutudur. Her kelime için bu katmandan çıkan çıktı vektörlerinin boyutunu tanımlar. Örneğin 50, 100 ya da daha büyük olabilir.</li><li>input_length: Giriş dizilerinin uzunluğudur. Örneğin, giriş belgelerinizin tümü 1000 kelimeden oluşuyorsa bu 1000 olacaktır.</li></ul><p>Ayrıca Embedding Layer 2 boyutlu bir vektör üreteceği için, doğrudan Dense katmanına bağlamak istiyorsak Flatten katmanını kullanarak çıktıyı tek boyutlu vektöre dönüştürmemiz gerekiyor.</p><p>Modeli donanım ve veri seti göz önüne alarak inşa etmeliyiz. Ben parametreleri küçük tutmaya özen gösterdim. Veri seti 4 kategoriye sahip olduğu için SparseCategorical kullandım. Aktivasyon ve optimizer gibi hiper parametreleri sık kullanılanlardan seçtim. Donanım ve veri setinize göre hiper parametreleri deneyerek en iyi sonuca erişebilirsiniz.</p><pre>embed_dim = 4  # Embedding size<br>feed_forward_dim = 8  # Hidden layer size in FFN<br><br>def create_model_FFN():<br>    inputs_tokens = layers.Input(shape=(max_len,), dtype=tf.int32)<br>    <br>    embedding_layer = layers.Embedding(<br>        input_dim=vocab_size,<br>        output_dim=embed_dim,<br>        input_length=max_len<br>    )<br>    <br>    x = embedding_layer(inputs_tokens)<br>    x = layers.Flatten()(x)<br>    <br>    dense_layer = layers.Dense(feed_forward_dim, activation=&#39;relu&#39;)<br>    x = dense_layer(x)<br>    x = layers.Dropout(0.5)(x)<br>    <br>    outputs = layers.Dense(4)(x)<br><br>    model = keras.Model(inputs=inputs_tokens, outputs=outputs, name=&#39;model_FFN&#39;)<br>    loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)<br>    metric_fn = tf.keras.metrics.SparseCategoricalAccuracy()<br>    <br>    model.compile(optimizer=&quot;adam&quot;, loss=loss_fn, metrics=metric_fn)<br>    return model<br><br>model_FFN = create_model_FFN()<br>model_FFN.summary()</pre><p>1 Dropout ve 2 Dense layer kullanarak oluşturulan model aşağıdaki gibidir:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/530/1*qR5afiRa7tMUAW9B5tNzTQ.png" /></figure><pre>history = model_FFN.fit(train_ds, verbose=2, epochs=25)</pre><p>25 epochtan sonra eğitim veri seti üzerinde 0.8921 başarı ortaya çıktı.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/889/1*EBRwxS8y2o4JvucKxFbglg.png" /></figure><pre>plt.plot(history.history[&#39;sparse_categorical_accuracy&#39;])<br>plt.title(&#39;Feed Forward Network Accuracy&#39;)<br>plt.ylabel(&#39;accuracy&#39;)<br>plt.xlabel(&#39;epoch&#39;)<br>plt.legend([&#39;train&#39;], loc=&#39;upper left&#39;)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/616/1*moH9JSeJTpR3RoYkxubZ8Q.png" /></figure><p>Model, test veri setinde ise 0.8883&#39;lük bir başarı yakaladı.</p><pre>loss, accuracy = model_FFN.evaluate(test_ds)<br>print(&quot;Test Dataset Accuracy: &quot;, accuracy)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/441/1*F6VbC2Gm2EH_NkIqjjgqhA.png" /></figure><p>Fakat modelin başarısını bu değerlerle ölçmek bir hata olur. Modelin başarısını daha iyi yorumlayabilmek için sklearn metricleri altında bulunan classification report’u kullanmak daha faydalıdır.</p><pre>preds = model_FFN.predict(test_ds)<br>preds = preds.argmax(axis=1)<br>actuals = test_ds.unbatch().map(lambda x,y: y)<br>actuals = list(actuals.as_numpy_iterator())<br><br>print(metrics.classification_report(actuals, preds, digits=4))</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/553/1*jgh5UQk7prOa0p41asXq0w.png" /></figure><h4>Convolutional Layer (Conv1D)</h4><p>Evrişimsel sinir ağı (CNN), hiyerarşik belge sınıflandırması için yaygın olarak kullanılan bir derin öğrenme mimarisidir. Başlangıçta görüntü işlemek için oluşturulmuş olmasına rağmen, CNN’ler aynı zamanda metin sınıflandırması için de etkili bir şekilde kullanılmaktadır.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6JKyF-8OrbqKJJLN2kVFfA.png" /><figcaption><a href="https://machine-learning-company.nl/en/technical/convolutional-neural-network-text-classification-with-risk-assessment-eng/">Source</a></figcaption></figure><p>Evrişimsel ağları kullanırken bilinmesi gereken bazı parametreler şunlardır:</p><ul><li>filters: Çıktı uzayının boyutudur. Her bir filtre, öğrenilecek özellikleri belirler. Daha fazla filtre genellikle daha fazla özellik veya deseni öğrenme kapasitesi sağlar.</li><li>kernel_size: Filtrenin bir adımda (stride) ne kadar veriyi kapsayacağını belirler. Örneğin, 3 verildiğinde her seferinde üç veriden bir grup alınır.</li><li>strides: Filtrelerin giriş verisi üzerinde kaydırıldığı mesafe miktarını belirtir. Her adımda bir filtre belirli bir adım mesafesinde kayar ve öğreneceği özellikleri çıkarır.</li><li>padding: Giriş verisi etrafına eklenen ek öğelerdir. Evrişim işlemi sırasında girişin boyutunu korumak veya çıkış boyutunu kontrol etmek için kullanılır. “valid” paddingde kenar dolgusu eklenmez ve giriş boyutu küçülür. “same” paddingde ise kenar dolgusu eklenerek çıkış boyutunun giriş boyutuna eşit olması sağlanır.</li><li>activation: Her bir sinir hücresinin çıkışını belirler.</li></ul><pre>embed_dim = 4<br>feed_forward_dim = 8<br><br>def create_model_Conv1D():<br>    inputs_tokens = layers.Input(shape=(max_len,), dtype=tf.int32)<br>    <br>    embedding_layer = layers.Embedding(<br>        input_dim=vocab_size,<br>        output_dim=embed_dim,<br>        input_length=max_len<br>    )<br>    <br>    x = embedding_layer(inputs_tokens)<br>    x = layers.Conv1D(<br>        filters=32, kernel_size=7, <br>        padding=&#39;same&#39;, activation=&#39;relu&#39;)(x)<br>    x = layers.Conv1D(<br>        filters=16, kernel_size=5, <br>        padding=&#39;same&#39;, activation=&#39;relu&#39;)(x)    <br>    x = layers.MaxPooling1D(pool_size=2)(x)<br>    x = layers.Dropout(0.5)(x)<br>    x = layers.Flatten()(x)<br>    x = layers.Dense(feed_forward_dim, activation=&#39;sigmoid&#39;)(x)<br>    x = layers.Dropout(0.5)(x)<br><br>    outputs = layers.Dense(4)(x)<br>    <br>    model = keras.Model(inputs=inputs_tokens, outputs=outputs, name=&#39;model_Conv1D&#39;)<br>    loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)<br>    metric_fn = tf.keras.metrics.SparseCategoricalAccuracy()<br>    <br>    model.compile(optimizer=&quot;adam&quot;, loss=loss_fn, metrics=metric_fn)<br>    return model<br><br>model_Conv1D = create_model_Conv1D()<br>model_Conv1D.summary()</pre><p>Tek boyutlu 2 tane evrişimsel sinir ağı kullanılarak oluşturulan model aşağıdaki gibidir:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/573/1*HQz3rnxx2pGSRpbliXotsw.png" /><figcaption>By author</figcaption></figure><pre>history = model_Conv1D.fit(train_ds, verbose=1, epochs=15)</pre><p>15 epochtan sonra eğitim veri seti üzerinde %91.2&#39;lik bir başarı ortaya çıktı. Model katman sayısı arttırılıp, daha fazla epoch boyunca eğitilseydi muhtemelen daha yüksek bir başarı sağlanırdı.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/988/1*KFjCHIRPMyTaMJAsYG_IqQ.png" /><figcaption>By Author</figcaption></figure><pre>plt.plot(history.history[&#39;sparse_categorical_accuracy&#39;])<br>plt.title(&#39;Conv1D Accuracy&#39;)<br>plt.ylabel(&#39;accuracy&#39;)<br>plt.xlabel(&#39;epoch&#39;)<br>plt.legend([&#39;train&#39;], loc=&#39;upper left&#39;)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/651/1*t86vPgL0aV_cVM3k-BdcFg.png" /><figcaption>By Author</figcaption></figure><p>Model, test veri setinde ise %90.6&#39;lık bir başarı yakaladı.</p><pre>loss, accuracy = model_Conv1D.evaluate(test_ds)<br>print(&quot;Test Accuracy: &quot;, accuracy)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/317/1*RaY1E3dYDdqOeqCpYYECAQ.png" /></figure><pre>preds = model_Conv1D.predict(test_ds)<br>preds = preds.argmax(axis=1)<br>actuals = test_ds.unbatch().map(lambda x, y:y)<br>actuals = list(actuals.as_numpy_iterator())<br><br>print(metrics.classification_report(actuals, preds, digits=4))</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*bIFjZQGEiltW3ft9xuoOow.png" /></figure><h4>LSTM</h4><p>Temel RNN’ye kıyasla daha etkili bir şekilde uzun vadeli bağımlılığı koruyarak <a href="https://en.wikipedia.org/wiki/Vanishing_gradient_problem">gradyan patlaması</a> gibi sorunları gideren özel bir RNN türüdür. Model kuruluma geçmeden önce LSTM hakkında ufak bir bilgi vermek istiyorum.</p><ul><li>units: LSTM hücrelerinin sayısını belirten bir parametredir. Daha fazla hücre genellikle modelin daha karmaşık örüntüleri öğrenmesine yardımcı olabilir, ancak aynı zamanda daha fazla hesaplama gücü gerektirir.</li><li>return_sequences: Eğer return_sequences=True olarak ayarlanırsa, her zaman adımındaki çıkışlar bir dizi olarak döner. Bu dizi, bir sonraki LSTM veya dense katmana giriş olarak kullanılabilir. Eğer return_sequences=False olarak ayarlanırsa, sadece en son zaman adımının çıkışını alırız.</li><li>return_state: Eğer return_state=True olarak ayarlanırsa, fonksiyonun çıkışı, normal çıkış tensörünün yanı sıra LSTM hücrelerinin son durumlarını da içerir. Bu durumlar genellikle bir sonraki zaman adımına başlamak için başlangıç durumu olarak kullanılabilir.</li></ul><pre>embed_dim = 4<br>feed_forward_dim = 8<br><br>def create_model_LSTM():<br>    inputs_tokens = layers.Input(shape=(max_len,), dtype=tf.int32)<br>    <br>    embedding_layer = layers.Embedding(<br>        input_dim=vocab_size,<br>        output_dim=embed_dim,<br>        input_length=max_len<br>    )<br>    <br>    x = embedding_layer(inputs_tokens)<br>    x = layers.LSTM(64, return_sequences=True)(x)<br>    x = layers.Dropout(0.2)(x)<br>    x = layers.Dense(feed_forward_dim, activation=&#39;relu&#39;)(x)<br>    x = layers.GlobalMaxPool1D()(x)<br><br>    outputs = layers.Dense(4)(x)<br>    <br>    model = keras.Model(inputs=inputs_tokens, outputs=outputs, name=&#39;model_LSTM&#39;)<br>    loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)<br>    metric_fn = tf.keras.metrics.SparseCategoricalAccuracy()<br>    <br>    model.compile(optimizer=&quot;adam&quot;, loss=loss_fn, metrics=metric_fn)<br>    return model<br><br>model_LSTM = create_model_LSTM()<br>model_LSTM.summary()</pre><p>1 tane 64 unitli LSTM katmanı kullanarak oluşturulan mimari aşağıdaki gibidir:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/569/1*w4tvNvi7S21pFy8CXtbvmw.png" /><figcaption>By Author</figcaption></figure><pre>history = model_LSTM.fit(train_ds, verbose=1, epochs=5)</pre><p>Modeli 5 epoch ile eğitmemize rağmen eğitim setinde Conv1D’den daha iyi başarı gösterdiği gözükmektedir. %96.96&#39;lık bir başarı gösterdi.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/993/1*W_Tz9sOYVI_JMpiFdsVm8g.png" /><figcaption>By Author</figcaption></figure><pre>plt.plot(history.history[&#39;sparse_categorical_accuracy&#39;])<br>plt.title(&#39;model_LSTM Accuracy&#39;)<br>plt.ylabel(&#39;accuracy&#39;)<br>plt.xlabel(&#39;epoch&#39;)<br>plt.legend([&#39;train&#39;], loc=&#39;upper left&#39;)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/674/1*xSj6cTWMGEOFMztIGngnFQ.png" /><figcaption>By Author</figcaption></figure><p>Model, test veri setinde ise %90.2&#39;lik başarı gösterdi.</p><pre>loss, accuracy = model_LSTM.evaluate(test_ds)<br>print(&quot;Test Accuracy: &quot;, accuracy)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/307/1*Si6ZHq-7XMaGSi3ZHab_YA.png" /></figure><pre>preds = model_LSTM.predict(test_ds)<br>preds = preds.argmax(axis=1)<br>actuals = test_ds.unbatch().map(lambda x,y: y)<br>actuals = list(actuals.as_numpy_iterator())<br><br>print(metrics.classification_report(actuals, preds, digits=4))</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/505/1*iGlrI95z7ZEnfrlh-UN3XA.png" /></figure><p>Modelin eğitim veri setinde gösterdiği başarıyı test veri setinde gösteremediğini görüyoruz. Bunun çeşitli sebepleri olabilir. Model mimarisi yanlış olabilir, daha hafif kurulabilirdi. Veri seti dengesiz veya az olabilir. Bu sorunların önüne veri setini düzenleyerek, model mimarisini tekrar gözden geçirerek, regularization ve çapraz doğrulama gibi teknikler kullanarak geçilebilir. Ayrıca LSTM yerine Bidirectional LSTM kullanılması model performansını yükseltecektir.</p><h4>BERT</h4><p>BERT (Bidirectional Encoder Representations from Transformers), Google tarafından geliştirilen ve doğal dil işleme çalışmalarında çığır açan bir dil modelidir. Bu model, önceki dil modellerinden farklı olarak, metin içindeki bağlamı anlamak için metni iki yönde (ileri ve geri) işleyen bir biçimde eğitilmiştir.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*EkbIgx84L28HfiA0.png" /><figcaption><a href="https://towardsdatascience.com/bert-explained-state-of-the-art-language-model-for-nlp-f8b21a9b6270">Source</a></figcaption></figure><p>Model eğitim aşamasında <a href="https://simpletransformers.ai/">simpletransformers</a> kütüphanesini ve <a href="https://huggingface.co/dbmdz/bert-base-turkish-uncased">bert-base-turkish-uncased</a> modelini kullanacağım.</p><p>Model eğitimine başlamadan önce gereken kütüphaneleri yüklüyoruz. Model eğitimi sırasında hata vermemesi için TensorFlow sürümünün 2.14 ve üzeri olmasına dikkat etmemiz gerekiyor, daha düşük sürümlerde hata veriyor (Siz bu yazıyı okurken güncellemeler gelmiş, sürümler değişmiş olabilir). Yükleme işlemlerinden sonra simpletransformers kütüphanesinden ClassificationModel ve ClassificationArgs sınıflarını çağırıyoruz.</p><pre>!pip install simpletransformers<br>!pip install tensorflow==2.14<br><br>import tensorflow as tf<br>from simpletransformers.classification import ClassificationModel, ClassificationArgs</pre><p>ClassificationArgs sınıfından bir örnek oluşturup, model eğiitminde kullanılacak çeşitli parametreleri ayarlıyoruz.</p><pre>model_args = ClassificationArgs()<br><br>model_args.num_train_epochs = 5<br>model_args.max_seq_length=500<br>model_args.reprocess_input_data= True<br>model_args.overwrite_output_dir= True<br>model_args.train_batch_size= 64<br>model_args.fp16=False<br>model_args.output_dir= &quot;bert_model&quot;<br>model_args.learning_rate = 1e-4<br>model_args.no_save= True<br>model_args.save_eval_checkpoints=False<br>model_args.save_model_every_epoch=False<br>model_args.save_optimizer_and_scheduler=False</pre><p>Türkçe BERT modeli<br>num_labels parametresi veri setindeki kategori sayısı yani çıkış sınıflarının sayısına eşit olmalı.</p><pre>model_bert = ClassificationModel(&#39;bert&#39;, <br>                                 &#39;dbmdz/bert-base-turkish-uncased&#39;, <br>                                 num_labels=4,<br>                                 args=model_args)</pre><p>Diğer modellerde TextVectorization katmanında gerçekleştirdiğimiz veri ön işleme adımıını BERT’te modele veremiyoruz. Bu yüzden veri ön işleme adıımını bu aşamada ayrı bir şekilde yapmamız gerekiyor.</p><pre>def custom_standardization(input_string):<br>    uppercased = tf.strings.lower(input_string, encoding=&#39;utf-8&#39;)<br>    stars = tf.strings.regex_replace(uppercased, &quot;\*&quot;, &quot; &quot;)<br>    repeats = tf.strings.regex_replace(stars, &quot;devamını oku&quot;, &quot;&quot;)<br>    html = tf.strings.regex_replace(repeats, &quot;&lt;br /&gt;&quot;, &quot;&quot;)<br>    digits = tf.strings.regex_replace(html, &quot;\w*\d\w*&quot;,&quot;&quot;)<br>    punctuations = tf.strings.regex_replace(digits, f&quot;([{string.punctuation}])&quot;, r&quot; &quot;)<br>    extra_space = tf.strings.regex_replace(punctuations, &quot; +&quot;,&quot; &quot;)<br><br>    no_I = tf.strings.regex_replace(no_extra_space, &quot;ı&quot;,&quot;i&quot;)<br>    no_O = tf.strings.regex_replace(no_I, &quot;ö&quot;,&quot;o&quot;)<br>    no_C = tf.strings.regex_replace(no_O, &quot;ç&quot;,&quot;c&quot;)<br>    no_S = tf.strings.regex_replace(no_C, &quot;ş&quot;,&quot;s&quot;)<br>    no_G = tf.strings.regex_replace(no_S, &quot;ğ&quot;,&quot;g&quot;)<br>    no_U = tf.strings.regex_replace(no_G, &quot;ü&quot;,&quot;u&quot;)<br>    return no_U.numpy().decode(&quot;utf-8&quot;)<br><br>train_txt = train_features.apply(custom_standardization)<br>test_txt = test_features.apply(custom_standardization)<br><br>train = pd.concat([train_txt, train_targets], axis=1)<br>test = pd.concat([test_txt, test_targets], axis=1)</pre><p>Veriler ön işleme adımından geçtikten sonra eğitim için hazır hale geldiler.</p><pre>model_bert.train_model(train)</pre><p>Tamamlanan eğitimin ardından modelin başarısını ölçmek için metriklere bakma vakti geldi.</p><pre>result, model_outputs, wrong_predictions = model_bert.eval_model(test)<br>result</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/519/1*-ipRPf0Ms6hk_S_40cj5Dg.png" /><figcaption>By Author</figcaption></figure><p>mcc (Matthews Correlation Coefficient), sınıflandırma problemlerinde performansı değerlendirmek için kullanılan bir istatistiksel ölçüdür. Doğruluk (accuracy), hassasiyet (precision) ve duyarlılık (recall) gibi metriklerin bir kombinasyonunu temsil eder.</p><p>eval_loss ise validation setinin hatasını temsil eder. Ancak bu modelde de olduğu gibi validation set kullanılmamışsa, hesaplamasını eğitim seti üzerinden gerçekleştirir.</p><pre>from sklearn.metrics import  classification_report, accuracy_score<br><br>accuracy_score(actuals, predictions)<br>predictions = model_outputs.argmax(axis=1)<br>actuals = test_targets.values<br>accuracy_score(actuals, predictions)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/172/1*1_9CQ97-MbHWdA0qJ6J0Uw.png" /><figcaption>By Author</figcaption></figure><pre><br>print(classification_report(actuals, predictions, digits=3))</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/498/1*eRgh3XPafoC6Kn39UyYXFA.png" /><figcaption>By Author</figcaption></figure><h3>5. Sonuç</h3><p>Feed Forward Neural, Conv1D, LSTM ve BERT modelleriyle gerçekleştirilen metin sınıflandırma çalışmamı anlatmaya çalıştım. Her bir modelin farklı hiper parametrelerle eğitildiği durumlar incelendiğinde, dikkat çekici sonuçların elde edildiğini düşünüyorum. Feed Forward Network modeli, basit ve hızlı eğitim süresiyle öne çıkarken, Conv1D modelinin text verileriyle de iyi çalışabileceğini deneyimledim. LSTM modeli, özellikle metinler arasındaki uzun vadeli bağlantıları yakalama konusunda başarılı olurken, BERT modeli genel olarak metin anlamını daha iyi kavradı.</p><p>Her modelin kendine özgü avantajları ve dezavantajları olduğunu göz önüne alarak, doğru model seçimi probleme bağlı olarak değişebilir. Eğitim süresi, model karmaşıklığı ve kullanılabilir veri miktarı gibi faktörler, hangi modelin en uygun olduğunu belirlemekte etkili olabilir. Ayrıca, hiper parametre ayarlamalarının her modelin performansını önemli ölçüde etkilediğini gözlemledim. Bu nedenle, spesifik bir görevde en iyi performansı elde etmek için detaylı bir hiper parametre optimizasyonu gereklidir. Son olarak geliştirilen modellerin sınıflandırma raporlarını paylaşmak istiyorum:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tg1gWJekraMhwSY4GD1yvg.png" /></figure><blockquote>BERT’te, eğitim süresinin ve Colab RAM kullanımının uygun olması için toplam veri setinin %10&#39;luk kısmı kullanılmıştır.</blockquote><p>Ayrıntılı notebooka <a href="https://github.com/rolmez/text-classification/blob/main/TextClassification.ipynb">buradan</a> ulaşabilirsiniz.</p><p>Okuduğunuz için teşekkür ediyorum. Soru ve görüşleriniz için;<br>Linkedin: <a href="https://www.linkedin.com/in/ramazanolmez/">https://www.linkedin.com/in/ramazanolmez/</a><br>Mail: ramazanolmeez@gmail.com<br>Github: <a href="https://github.com/rolmez">https://github.com/rolmez</a></p><h4>Kaynaklar:</h4><ol><li><a href="https://www.youtube.com/c/muratkarakayaakademi">https://www.youtube.com/c/muratkarakayaakademi</a></li><li><a href="https://colab.research.google.com/drive/1eQydhzxK03z4_20_A9dunOq04trRYuZG?usp=sharing">https://colab.research.google.com/drive/1eQydhzxK03z4_20_A9dunOq04trRYuZG?usp=sharing</a></li><li><a href="http://charuaggarwal.net/text-class.pdf">Aggarwal, Charu C. Zhai, C. A SURVEY OF TEXT CLASSIFICATION ALGORITHMS</a></li><li><a href="https://www.researchgate.net/publication/343557744_Text_Classification_with_Deep_Neural_Networks">Amajd, M. Kaimuldenov, Z. Voronkov, I. Text Classification with Deep Neural Networks</a></li><li><a href="https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/">https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/</a></li><li><a href="https://www.researchgate.net/publication/332463886_Text_Classification_Algorithms_A_Survey">Kowsari, K., Meimand, K., Heidarysafa, M., Mendu, S. Text Classification Algorithms: A Survey</a></li><li><a href="https://arxiv.org/pdf/1009.4964">Kamruzzaman, S. M. Text Classification using Artificial Intelligence</a></li><li><a href="https://www.mdpi.com/2078-2489/13/2/83">Gasparetto, A., Marcuzzo, M., Zangari, A., &amp; Albarelli, A. (2022). A Survey on Text Classification Algorithms: From Text to Predictions</a></li><li><a href="https://dergipark.org.tr/en/pub/jscai/issue/78595/1311380">Ağduk, S., Aydemir, Emrah., Polat, Ayfer. Classification of News Texts from Different Languages with Machine Learning Algorithms</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7ac6620ca543" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Büyük Dil Modellerinde Halüsinasyonlar]]></title>
            <link>https://medium.com/@ramazanolmeez/b%C3%BCy%C3%BCk-dil-modellerinde-hal%C3%BCsinasyonlar-ee83c3008d40?source=rss-b005bac7906e------2</link>
            <guid isPermaLink="false">https://medium.com/p/ee83c3008d40</guid>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[halüsinasyon]]></category>
            <category><![CDATA[hallucinations]]></category>
            <category><![CDATA[büyük-dil-modelleri]]></category>
            <category><![CDATA[large-language-models]]></category>
            <dc:creator><![CDATA[Ramazan Olmez]]></dc:creator>
            <pubDate>Mon, 08 Jan 2024 08:53:54 GMT</pubDate>
            <atom:updated>2024-01-08T09:30:09.210Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*l5hIOGHv2KZ8a8r8" /><figcaption>Photo by <a href="https://unsplash.com/@rocknrollmonkey?utm_source=medium&amp;utm_medium=referral">Rock&#39;n Roll Monkey</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h4>İçerik Tablosu</h4><ol><li><a href="#e686">Giriş</a></li><li><a href="#3e70">Büyük Dil Modellerinde Halüsinasyon Nedir</a></li><li><a href="#7753">Halüsinasyon Çeşitleri</a></li><li><a href="#7f4f">Halüsinasyonların Nedenleri</a></li><li><a href="#3ae6">Halüsinasyon Örnekleri</a></li><li><a href="#268a">Halüsinasyonlar Nasıl Azaltılır / Yapılan Çalışmalar</a></li><li><a href="#3ae3">Sonuç</a></li></ol><h3>1. Giriş</h3><p>Son zamanlarda hızla gelişen bir teknoloji olan yapay zekanın son gelişmelerinden biri de Büyük Dil Modelleri’dir (LLMs). Bu modeller, doğal dilleri çevirebilen, çeşitli türde yaratıcı içerikler oluşturabilen, sorulara bilgilendirici bir şekilde cevap verebilen yapay zeka ürünleridir. Dil modellerinin büyük bir potansiyeli vardır. Bununla birlikte, halüsinasyon üretebilme gibi bir ihtimale de sahiptirler.</p><p>Bu yazıda, büyük dil modellerinde halüsinasyonun ne olduğunu, türlerini, nedenlerini, kaçınma yollarını ve son araştırmalar hakkında örnekleri ele alacağım.</p><h3>2. Büyük Dil Modellerinde Halüsinasyon Nedir</h3><p>PaLM, GPT ve LLaMA gibi büyük dil modelleri, çeşitli uygulamalar için akıcı ve tutarlı metinler üretebilen güçlü doğal dil işleme araçlarıdır. Büyük dil modellerinin önemli kusurlarından birisi, güvenilirliklerini etkileyen <strong>halüsinasyon</strong> üretme eğilimleridir.</p><p>LLM’lerdeki halüsinasyonlar, promptlarla alakasız, uydurma veya tutarsız içerik üretilmesi anlamına gelir. Geniş ve çeşitli veri kümelerine maruz kalmalarına rağmen, bu modeller çıktıları doğrularla ilişkilendirmek için tasarlanmamıştır. Örneğin, büyük bir dil modeli olarak bilinen ChatGPT’nin ana amacı, soruya anlamlı yanıtlar sağlamak için olasılıksal dağılım uygulamaktır. Model, maruz kaldığı bilgileri tutarlı bir şekilde birleştirmeye çalışır. Amacına ulaşabilmek için zaman zaman doğru bilginin ötesine geçebilir. Örneğin, bir dil modeline “<em>Türkiye’nin başkenti</em>” sorulduğunda, eğitildiği veri setinde bulunan hatalı bilgiden dolayı “<em>İstanbul</em>” yanıtını verebilir. Öngörülemezliği nedeniyle, LLM halüsinasyonları çeşitli sektörlerde yapay zeka uygulamalarını sekteye uğratabilir. Bu durum özellikle hukuk, sağlık ve finans gibi gerçeklere dayalı sektörlerde olumsuz sonuçlara yol açabilir.</p><p>LLM’leri etkili bir şekilde kullanmak için bu halüsinasyonları anlamak önemlidir. Sınırların farkına varmamızı sağlar ve yapay zeka teknolojilerinin hem potansiyelini hem de zorluklarını anlamamızda önemli rol oynar.</p><blockquote>Vectara tarafından yapılan bir çalışmada dil modellerinde halüsinasyon oranları şu şekilde bulunmuştur:</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/618/1*5bPL906-qnDn60cEe3UvXg.png" /><figcaption>Source: <a href="https://github.com/vectara/hallucination-leaderboard">https://github.com/vectara/hallucination-leaderboard</a></figcaption></figure><h3>3. Halüsinasyon Çeşitleri</h3><p>LLM halüsinasyonları, her biri kendine özgü özelliklere ve sonuçlara sahip belirli türlere ayrılabilir. Bu ayrım, kullanıcıların farklı halüsinasyon senaryoları tanımlamasına ve ele almasına yardımcı olur.</p><h4>3.1. Factuality Hallucinations:</h4><p>Bu durum, modelin yanlış içerik üretmesidir. Örneğin, bir model yüzölçümü en büyük ülkenin Çin olduğunu (Doğru cevap Rusya’dır) iddia edebilir ki bu olgusal bir hatadır.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/451/1*QtQsFN0yX19xssCMNALEFg.png" /><figcaption>Image By the Author (*Bard doğru cevabı biliyor, promptumu örnek olması için bu yönde verdim)</figcaption></figure><p>Gerçeklik halüsinasyonunu da (Factuality Hallucination) kendi içerisinde 2&#39;ye ayırabiliriz.</p><ul><li><strong>Factual Inconsistency:</strong> Bu halüsinasyon çeşidi, modelin eğitim aldığı veri setinde bulunan çelişkili veya tutarsız bilgileri nedeniyle gerçeklikle uyuşmayan metinler üretmesidir. LLM, Yuri Gagarin’in Ay’a inen ilk kişi olduğunu söyleyebilir (doğru cevap Neil Armstrong’dur).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/855/1*2II7j2VYDMStWf0rk0FujQ.png" /><figcaption>Image By the Author</figcaption></figure><ul><li><strong>Factual Fabrication:</strong> Modelin eğitim aldığı veri setinde bulunmayan tamamen uydurma bilgiler üretmesi de bir başka halüsinasyon çeşididir. Örneğin, bir büyük dil modeline “Shakespeare’in son oyununun adı neydi?” diye sorulduğunda, model, aslında var olmayan bir oyun için uydurma bir isim veya özet verebilir.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/863/1*ZvlKsjOKTGzPE4O9bT9Ztw.png" /><figcaption>Image By the Author</figcaption></figure><h4>3.2. Faithfulness Hallucinations:</h4><p>Bunlar, modelin sadakatsiz içerik ürettiği veya sağlanan kaynağın içerikle tutarsız olduğu durumlardır. Örneğin, bir makalede BioNTech’in Covid-19 aşısını onayladığı belirtiliyorsa, bir sadakat halüsinasyonu, FDA’nın bunu reddettiğini (intrinsic hallucination) veya Çin’in bir COVID-19 aşısını test etmeye başladığını (extrinsic hallucination) iddia eden bir metin içerecektir.</p><p>Bu halüsinasyonlar üç türe ayrılabilir:</p><ul><li><strong>Instruction Inconsistency</strong>: Model, kullanıcı tarafından verilen özel talimatları göz ardı eder. Modelden bir metni Türkçe’ye çevirmesini istediğimizde, cevabı İngilizce olarak vermesi buna bir örnektir.</li><li><strong>Context Inconsistency</strong>: Model çıktısı, sağlanan promptta mevcut olmayan veya onunla çelişen bilgiler içerir. Kullanıcının Türkiye ile ilgili bir sorusunda, modelin bunu Almanya olarak iddia etmesi bu duruma bir örnektir.</li><li><strong>Logical Inconsistency</strong>: Modelin çıktısı doğru başlamasına rağmen mantıksal bir hata içerir. Örneğin, adım adım matematik çözümünde bir aritmetik işlemi yanlış gerçekleştirir.</li></ul><h3>4. Halüsinasyonların Nedenleri</h3><p>Dil modellerinin halüsinasyon görmesinin nedenleri, karmaşık ve çeşitlidir. Bu nedenler arasında eğitim veri setindeki hatalar veya tutarsızlıklar, modelin yapısı, kullanılan algoritmalar gibi unsurlar yer alabilir. LLM’lerin halüsinasyon görmesi bir sorundur ve nedenleri anlaşılmalıdır. Bu sorunun anlaşılması, modellerin güvenilirliğini ve kullanılabilirliğini artırmaya yardımcı olacaktır. Başlıca halüsinasyon nedenleri:</p><ul><li><strong>Eğitim Verisi:</strong> Büyük dil modelleri, geniş ve çeşitli eğitim verileri ile eğitilen kapsamlı bir öğrenme sürecinden geçer. Bu veriler, çeşitli kaynaklardan toplanmıştır, bu da doğrulamayı son derece zorlaştırır. Çünkü verilerin adil, tarafsız ve gerçeklere dayalı olup olmadığını belirlemek oldukça uzun bir süreçtir. Dil modeli, gerçeği kurgudan ayırt edemez ve bazı eğitim verileri yanlı veya öznel görüşler içerir. Bu da modelin gerçeğe ulaşma ihtimalini zorlaştırır. Model sadece eğitim sırasında öğrenilen kalıpları kullanarak olası çıktıları bir araya getirir.</li><li><strong>Amaca uygun olmayan model kullanımı:</strong> LLM’ler, belirli görevler için açıkça eğitilmediklerinde rastgele halüsinasyonlara eğilimlidirler. GPT gibi büyük dil modelleri, genel doğal dil işleme görevleri için eğitilmiştir. Ancak, özel alanlardaki (örneğin tıp, hukuk ve finans gibi) konulara odaklanmadıkları için bu modellerin doğru çıkarımlar yapma konusunda yardıma ihtiyaçları olabilir. Bu modeller, belirli promptlara dayalı olarak görünüşte tutarlı bir anlatı oluşturabilir, ancak halüsinasyonlara eğilim gösterebilirler. Aşağıdaki resimde belirli görevler için eğitilmiş bazı dil modelleri görülmektedir.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6z7TgWMal8ug4Xno3nFvwQ.png" /><figcaption>Dil Modellerinin Örnek Mimari Yapıları (Source: <a href="https://medium.com/mlearning-ai/3-llm-architectures-f527ed781ba9">https://medium.com/mlearning-ai/3-llm-architectures-f527ed781ba9</a>)</figcaption></figure><ul><li><strong>Prompt Mühendisliği:</strong> Promtlar, modellere belirli görevleri yerine getirmesi için talimat verme araçlarıdır. Dil modellerini kullanmak için kullanıcılar promt olarak metin girerler. Bu işlem kodlamaya benzer, ancak programlama dillerinin aksine, basit yazım dili kullanılır. Modellerden istenilen çıktılar konusunda net olmak önemlidir. Model daha sonra promtlara uygun bir yanıt oluşturur. Ancak, promptlar yeterli olmadığında modeller tutarlı davranmayabilir. Prompt, istenilen konu akışından yoksunsa, LLM yanlış bir yanıt veya kullanıcının aramadığı tamamen farklı bir yanıt üretebilir.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/607/1*mwaUgYITwco9rZZWaXQ4lQ.png" /><figcaption>Image By the Author</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/608/1*OvN-1-DdmDozYkFdErfbcQ.png" /><figcaption>Image By the Author</figcaption></figure><ul><li><strong>Model mimarisi:</strong> Halüsinasyonlar model mimarisindeki kusurlardan veya optimal olmayan eğitim hedeflerinden de kaynaklanabilir. Örneğin, bir model yanlış mimariyle kurgulanmış olabilir veya hatalı kod çözme (decoding) stratejileri yürütülmüş olabilir. Veya bazı durumlarda, LLM&#39;ler daha uzun çıktılar gibi belirli sonuçlar için optimize edilir, bu da ayrıntılı ve alakasız yanıtlara yol açabilir.</li><li><strong>Stokastik yöntemler:</strong> LLM&#39;ler metin üretirken, çıktıya rastgelelik katabilecek stokastik stratejileri kullanır. Örneğin, model kurgulanırken yüksek bir “sıcaklık” (temperature) değeriyle eğitilmiş olabilir. Bunun modelde yaratıcılık gibi pozitif tarafları olsa da, halüsinasyon üretebilme riskini artırabilir. Bu stokastik yöntemler yüzünden model çıktıları bazen beklenmedik veya anlamsız yanıtlar oluşturur.</li></ul><h3>5. Halüsinasyon Örnekleri</h3><p>Halüsinasyon konusunda son zamanlarda bazı feci sonuçlar görüldü. Bu tür olaylar yapay zeka teknolojilerine olan güveni önemli ölçüde azaltabileceği gibi ciddi mesleki ve yasal sonuçlara da yol açabilir. Halüsinasyonlardan kaynaklanan yanlış bilgiler, karar alma süreçlerini etkileyebilir. <br>Halüsinasyonlardandan doğan bazı kötü örnekler:</p><ol><li>New York Times yaptığı bir çalışmada, ChatGPT’nin kendileri hakkında yanlış bilgiler verdiğini keşfetti. Dil modeli, var olmayan bir makaleye atıfta bulunmuştu. Gazeteciler başka halüsinasyon örneklerine de rastladılar. Yapay zeka tarafından oluşturulan sohbet robotlarına güvenmenin riskli olabileceğini vurguladılar. (<a href="https://www.nytimes.com/2023/05/01/business/ai-chatbots-hallucination.html">Source</a>)</li><li>İki avukat, davalarında ChatGPT sonuçlarını araştırmadan kullanarak büyük bir hata yaptılar. Bu avukatlar, davalarına benzer emsaller bulmak için ChatGPT’yi kullandılar. Fakat GPT’nin sadece dil modeli olduğunu, doğru bilgi verme zorunluluğu bulunmadığını atlayıp buldukları sonuçları araştırmadan mahkemeye sundular. Alıntıladıkları davalardan altısı sahte çıktı. Bu, durum mahkemenin yaptırımlarına yol açtı. (<a href="https://www.forbes.com/sites/mollybohannon/2023/06/08/lawyer-used-chatgpt-in-court-and-cited-fake-cases-a-judge-is-considering-sanctions/?sh=6f2a2fed7c7f">Source</a><a href="https://www.forbes.com/sites/mollybohannon/2023/06/08/lawyer-used-chatgpt-in-court-and-cited-fake-cases-a-judge-is-considering-sanctions/?sh=6f2a2fed7c7f)">)</a></li><li>Yakın zamanlı bir raporda ChatGPT, ABD’li bir hukuk profesörünün cinsel suçlu olarak suçlandığını iddia etti. Bu iddiada var olmayan bir Washington News raporunu kaynak olarak gösterdi. Böyle suçlamaların bıraktığı iz düşünülünce, olayın ciddiyeti daha net anlaşılıyor. (<a href="https://www.firstpost.com/world/chatgpt-makes-up-a-sexual-harassment-scandal-names-real-professor-as-accused-12418552.html">Source</a>)</li></ol><h3>6. Halüsinasyonlar Nasıl Azaltılır / Yapılan Çalışmalar</h3><p>LLM’lerde halüsinasyonları azaltmak için geri bildirim mekanizmalarından, yapılandırılmış girdi/çıktı mekanizmalarına kadar önerilen birçok teknik vardır. “A Comprehensive Survey of Hallucination Mitigation Techniques in Large Language Models” makalesinde yazarlar, 2 ana grupta 32 yeni halüsinasyon azaltma tekniğini değerlendirdiler. Bunlardan kısaca bahsetmek istiyorum:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VpADEwpaY1Q18rCk_MzOPw.png" /><figcaption>Source: A Comprehensive Survey of Hallucination Mitigation Techniques in Large Language Models</figcaption></figure><h4>6.1. Prompt Engineer:</h4><p>Dil modellerinde en iyi çıktıyı elde etmek için çeşitli promptları deneme/yanılma sürecidir. Bu süreç beklenen çıktıyı iyileştirebilir ve halüsinasyonu önemli derecede azaltabilir. Araştırmacılar bu süreci 3 farklı gruba ayırıyor.</p><h4>6.1.1. Retrieval Augmented Generation (RAG):</h4><p>Retrieval Augmented Generation (RAG) yöntemi, modelin eğitildiği veri seti haricinde güvenilir bir bilgi tabanına başvurur. Bu sayede modeli güncel bilgiler ile besleyebilir, model üzerinde daha fazla denetime sahip olunabilir. Dil modellerinin güçlü taraflarını, yeniden eğitmeye gerek duymadan belirli alanlarda genişletir. Yeniden eğitime gerek duymamasından dolayı uygun maliyetli bir yaklaşımdır. Araştırmacılar bu yaklaşımı da kendi içerisinde 4 gruba ayırarak (çıktı üretiminden önce, çıktı ürecim sırasında, çıktı üretimi sonrasında, uçtan uca), detaylı bir şekilde incelemişler.</p><ul><li><strong>Before Generation:</strong> Bu yaklaşımdaki yöntemler, yapay zeka metninin oluşturulmasından önce gerçekleşir. “<em>LLM-Augmenter”</em> ve “<em>FreshPrompt”</em> bu yaklaşıma örnek iki çalışmadır.</li><li><strong>During Generation:</strong> Bu yaklaşımdaki yöntemler, model her cümleyi oluştururken denetim mekanizmasında gerçekleşir. Bu denetim mekanizması, cümle-cümle şeklinde meydana gelir. Bu yönteme örnek olarak “<em>Knowledge Retrieval”, “Decompose-and Query framework (D&amp;Q)” </em>ve<em> “EVER”</em> adlı yöntemler gösterilebilir.</li><li><strong>After Generation:</strong> Bu kategori altındaki yöntemler, çıktının tamamı oluştuktan sonra RAG sistemini kullanır. “<em>RARR” </em>ve<em> “High Entropy Word Spotting and Replacement”</em> çalışmaları bu kategori altında incelenmiştir.</li><li><strong>End-to-end:</strong> Uçtan uca RAG, önceden eğitilmiş bir diziden diziye (seq2seq) transformerın, Dense Passage Retriever (DPR) aracılığıyla elde edilen Wikipedia’nın yoğun bir vektör dizini ile entegre edilmesini içerir. Bu kombinasyon, modelin çıktı üretimini hem girdi sorgusu hem de DPR tarafından sağlanan gizli belgeler üzerinde koşullandırmasına olanak tanır. Bu yöntem, modellerin performansını önemli ölçüde artıran bir yaklaşımdır. Bu yaklaşım, çeşitli bilgi yoğun görevlerde gelişmiş performans sağlar ve üretim modellerinde parametrik ve parametrik olmayan belleği birleştirmenin etkinliğini gösterir.</li></ul><h4>6.1.2. Self-Refinement through Feedback and Reasoning:</h4><p>Bir LLM belirli bir prompt için bir çıktı sağladıktan sonra, çıktının uygunluğu ölçülerek veya insanlar tarafından sağlanan geri bildirim sayesinde, sonraki yanıtlarında daha iyi ve daha doğru çıktılar üretilmesi sağlanabilir. Önceki çalışmaların aksine, denetimli veri veya takviyeli öğrenme gerektirmez. Bu yaklaşımda, <em>“Prompting GPT-3 To Be Reliable”, “ChatProtect”, “Self-Reflection Methodology”, “Mind’s Mirror”, “DRESS”, “MixAlign”, “CoVe” </em>ve<em> “ConLI”</em> gibi araştırmalar bulunmaktadır.</p><p>Örneğin CoVe bir kullanıcı sorgusu verildiğinde, gerçek halüsinasyonlar gibi yanlışlıklar içerebilecek bir temel yanıt üretir. Önce sorulacak doğrulama soruları oluşturur, ardından kontrol etmek için bunları yanıtlar. Aşağıdaki 4 adımı takip eder:<br>- Bir ilk yanıt taslağı hazırlar<br>- Taslağın doğruluğunu kontrol etmek için doğrulama soruları planlar<br>- Cevapların doğru olması için bu soruları bağımsız olarak yanıtlar<br>- Doğrulanmış bir yanıt oluşturur</p><h4>6.1.3. Prompt Tuning:</h4><p>Modeli belirli görevlerde daha etkili hale getirmek için fine-tune (ince ayar) aşamasında önceden eğitilmiş bir dil modeline sağlanan talimatların ayarlanmasını içeren teknik olarak tanımlanır. Burada model sabit yönergeler kullanmaz, bunun yerine ince ayar sırasında ağırlıkları ayarlayarak bunları modelin kendisi öğrenir. <em>“UPRISE”</em> ve <em>“SynTra”</em> önerilen teknikler arasındadır.</p><h4>6.2. Developing Models:</h4><p>İkinci ana yöntem kategorisi, model geliştirilmedir. Bu yöntemin amacı, model çıktılarını ayarlamak veya mevcut modellere ince ayar yapmak yerine, halüsinasyonlarla doğal olarak başa çıkmak için özel olarak tasarlanmış yeni model mimarileri uygulamak olan aktif bir araştırma alanıdır. Bu yöntem kendi içerisinde 4 gruba ayrılabilir:</p><h4>6.2.1. Introducing New Decoding Strategy:</h4><p>Kod çözme stratejileri, özellikle bir modelin üretim aşamasını hedefleyen tekniklerin geliştirilmesini içerir. Bu teknikler dil modeline uygulandığında, cevap üretim aşamasını gerçek veya bağlama özgü üretime yönlendirerek üretilen çıktılardaki halüsinasyonları önleyebilir. <em>“CAD”</em>, <em>“DoLa”</em> ve <em>“Inference-Time Intervention (ITI)”</em> bu yaklaşıma örnek yöntemlerdir.</p><h4>6.2.2. Utilization of Knowledge Graph:</h4><p>Wikidata gibi bilgi grafikleri, gerçek dünya varlıkları (örneğin insanlar, kuruluşlar veya ürünler) hakkında bilgilerin yanı sıra bunların özelliklerini ve grafikteki diğer varlıklarla bağlantılarını içeren organize veri koleksiyonlarıdır. Büyük Dil Modelleri için akıl yürütme, veri analizi ve bilgi erişimi gibi konularda güvenilir bir bilgi kaynağı oluştururlar. <em>“RHO”</em> ve <em>FLEEK</em> araştırmaları bu yöntemi kullanan projelere örnek olarak verilebilir.</p><h4>6.2.3. Introducing Faithfulness based Loss Function:</h4><p>Bu yöntemlerin amacı, modelleri eğitim sırasında temel gerçek verilerle eşleşmeye daha fazla zorlayabilen yeni ölçütler tasarlamaktır. Bu bağlamda, sadakat; modelin hatalar, eksiklikler veya çarpıtmalar eklemeden prompttan gelen verileri sadık ve düzgün bir şekilde yansıtma kapasitesi olarak tanımlanmaktadır. “<em>THAM Framework”</em> ve “<em>Loss Weighting Method”</em> bu kategoride değerlendirilebilir.</p><h4>6.2.4. Supervised Finetuning:</h4><p>SFT, etiketli verileri kullanarak LLM’leri hizalamak için iyi bilinen bir tekniktir, bu nedenle modelin belirli görevler için insan komutlarını izlemesini ve sonunda sadakatini artırmasını sağlar. Popüler yaklaşımlar arasında “<em>Knowledge Injection and Teacher-Student Approach”</em>, “<em>HAR</em>”, “<em>Fine-tuning Language Models for Factuality”</em>, “<em>BEINFO”</em>, “<em>R-Tuning</em>” ve “<em>TWEAK”</em> yer alır.</p><h3>7. Sonuç</h3><p>Halisünasyonlar, büyük dil modellerinin karşılaştığı önemli bir sorundur. Bu yazıda bu olguların anlaşılması ve azaltılması üzerine yapılan çalışmalara odaklandım. Halüsinasyonları azaltmak adına atılan her bir yaklaşım farklı noktalara dokunuyor olsa da, hepsi tek bir hedefe sahiptir; büyük dil modellerinde çıktı kalitesini iyileştirmek. Ayrıca halüsinasyon olgusunun değerlendirilmesi ve ölçülmesi zordur ve halüsinasyonların etik ve sosyal etkileri hala araştırılmaktadır.</p><p>Okuduğunuz için teşekkür ediyorum.</p><p>Görüşleriniz için:<br>LinkedIn: <a href="https://www.linkedin.com/in/ramazanolmez/">https://www.linkedin.com/in/ramazanolmez/</a><br>Mail: ramazanolmeez@gmail.com</p><h3>Kaynakça:</h3><ol><li>Tonmoy, S.M Towhidul Islam., vd. (2024). <a href="https://arxiv.org/abs/2401.01313">A Comprehensive Survey of Hallucination Mitigation Techniques in Large Language Models</a></li><li>Dahl, Matthew., vd. (2024). <a href="https://arxiv.org/abs/2401.01301">Large Legal Fictions: Profiling Legal Hallucinations in Large Language Models</a></li><li>Lei, Huang., vd. (2023). <a href="https://arxiv.org/abs/2311.05232">A Survey on Hallucination in Large Language Models: Principles, Taxonomy, Challenges, and Open Questions</a></li><li>Gallegos, Isabel O., vd. (2023)<em>. </em><a href="https://arxiv.org/abs/2309.00770">Bias and Fairness in Large Language Models: A Survey</a></li><li>Dhuliawala, Shehzaad., vd. (2023). <a href="https://arxiv.org/abs/2309.11495">Chain-of-Verification Reduces Hallucination in Large Language Models</a></li><li><a href="https://www.lakera.ai/blog/guide-to-hallucinations-in-large-language-models">https://www.lakera.ai/blog/guide-to-hallucinations-in-large-language-models</a></li><li><a href="https://kili-technology.com/large-language-models-llms/understanding-llm-hallucinations-and-how-to-mitigate-them">https://kili-technology.com/large-language-models-llms/understanding-llm-hallucinations-and-how-to-mitigate-them</a></li><li><a href="https://generativeai.pub/how-to-mitigate-hallucinations-in-large-language-models-llms-0b8559b00d04">https://generativeai.pub/how-to-mitigate-hallucinations-in-large-language-models-llms-0b8559b00d04</a></li><li><a href="https://machinelearning.apple.com/research/gender-bias-llm">https://machinelearning.apple.com/research/gender-bias-llm</a></li><li><a href="https://machinelearningmastery.com/a-gentle-introduction-to-hallucinations-in-large-language-models/">https://machinelearningmastery.com/a-gentle-introduction-to-hallucinations-in-large-language-models/</a></li><li><a href="https://medium.com/mlearning-ai/3-llm-architectures-f527ed781ba9">https://medium.com/mlearning-ai/3-llm-architectures-f527ed781ba9</a></li><li><a href="https://github.com/vectara/hallucination-leaderboard">https://github.com/vectara/hallucination-leaderboard</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ee83c3008d40" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[T5 modelini Kullanarak Geçmişten Günümüze Metin Özetleme]]></title>
            <link>https://medium.com/@ramazanolmeez/t5-modelini-kullanarak-ge%C3%A7mi%C5%9Ften-g%C3%BCn%C3%BCm%C3%BCze-metin-%C3%B6zetleme-620a8a474109?source=rss-b005bac7906e------2</link>
            <guid isPermaLink="false">https://medium.com/p/620a8a474109</guid>
            <category><![CDATA[summarization]]></category>
            <category><![CDATA[text-summarization]]></category>
            <category><![CDATA[fine-tuning]]></category>
            <category><![CDATA[metin-özetleme]]></category>
            <category><![CDATA[t5]]></category>
            <dc:creator><![CDATA[Ramazan Olmez]]></dc:creator>
            <pubDate>Fri, 05 Jan 2024 18:50:11 GMT</pubDate>
            <atom:updated>2024-01-05T18:51:48.499Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e-g6wmdryCLPrQwUTIY4Zg.jpeg" /><figcaption>Source: <a href="https://unsplash.com/">https://unsplash.com/</a></figcaption></figure><p>Bu yazının bir kısmı metin özetlemenin geçmişten günümüze tarihini anlatmakta ve bazı mimarileri (seq-to-seq, transformers, vb.) kısaca tanıtmaktadır. Buraları atlamak istiyorsanız, içindekiler bölümünden direkt model kurulum aşamasına erişebilirsiniz.</p><p>Table of Contents</p><ol><li><a href="#527c">Giriş</a></li><li><a href="#4fda">Metin Özetlemenin Kısa Tarihçesi</a></li><li><a href="#5497">Metin Özetleme Metotları</a></li><li><a href="#ae8a">Extractive Method vs Abstractive Method</a></li><li><a href="#ff86">Seq2seq, Attention, Transformers ve T5</a></li><li><a href="#b704">Google T5 Dil Modeli ile Metin Özetleme</a></li></ol><h3><strong>A. Giriş</strong></h3><p><em>Doğal dil işleme (NLP), bilgisayar bilimi, dil bilim ve yapay zekayı birleştiren bir alandır. Bu alandaki önemli uygulamalardan biri de metin özetlemedir.</em></p><blockquote><em>Metin özetleme, bir metnin veya dokümanın ana fikrini koruyarak, daha kısa bir biçimde ifade etme işlemidir. Bu karmaşık süreç, asıl metni anlamayı, önemli bilgileri seçmeyi, korumayı ve özetlemeyi içerir.</em></blockquote><p>Metin özetleme, günümüzde birçok endüstri tarafından kullanılmaktadır. Sigorta, hukuk, habercilik, eğitim ve araştırma gibi sektörlerde yaygın olarak uygulanmaktadır. Özellikle büyük belgelerle uğraşırken, bu belgelerin tamamını taramak zaman alıcı ve verimsiz bir süreç olabilir. Metin özetleme, belgelerin kısaltılmasına yardımcı olarak arama işlemlerini hızlandırabilir.</p><p>Metin özetleme, doğal dil işleme alanındaki gelişmelerden önemli ölçüde yararlanmıştır. Yapay zeka ve makine öğrenimi gibi teknolojilerin gelişimi, uygulamaların daha doğru ve etkili hale gelmesini sağlamıştır. Fakat bu günlere gelene kadar bir sürü yenilikler geçmiş, farklı yaklaşımlar üzerine çalışılmıştır. Bu nedenle, T5 ile metin özetleme modeli geliştirmeden önce, bu alandaki gelişimlere kısa bir göz atmak faydalı olabilir.</p><h3><strong>B. Metin Özetlemenin Kısa Tarihçesi</strong></h3><h4>1950 ve 1960&#39;lı Yıllar / Deneysel Yaklaşımlar:</h4><p>İlk metin özetleme çalışmaları, 1950&#39;li yıllarda başlamıştır. Bu yıllardaki çalışmalar, cümlelerin çeşitli özelliklerini hesaplayarak ve bu özellikleri kullanarak cümlelerin önemini belirlemeye odaklanmıştır. Kelime sıklığının yeterli olmadığı anlaşılınca, cümlenin belge içindeki konumunu hesaba katan yöntemler geliştirilmeye çalışılmıştır. Ancak bu dönemdeki sınırlı donanım nedeniyle istenilen sonuçlara ulaşılamamış, bu durum metin özetleme çalışmalarını bir süre için duraklatmıştır.</p><h4><strong>1970 ve 1980’li Yıllar / Rasyonalist Yaklaşımlar:</strong></h4><p>1960&#39;lı yıllarda araştırmacılar, metnin anlamını anlayarak özetlemeye odaklanmaya başlamıştır. Metindeki önemli bilgileri belirlemek için komut dosyaları, FRUMP ve SUSY gibi yaklaşımları kullandılar. Ancak, bu yaklaşımların da elle kodlanmış bilgilere ve alana özgü bilgiye ihtiyaç duyduğu görülmüştür. Yani, bu metodolojilerin kullanımıyla elde edilen sonuçlar, spesifik bilgiye dayandığı için genellikle belirli bir alanda etkili olabiliyordu. Bu durum, metin özetleme süreçlerini daha geniş kapsamlı ve genel kullanıma uygun hale getirmek adına yeni yöntem ve stratejilerin geliştirilmesini teşvik etmiştir.</p><h4>1990’lı Yıllar / Deneysel Yaklaşıma Geri Dönüş:</h4><p>1990&#39;ların ortalarında, 50&#39;li ve 60&#39;lı yıllardaki deneysel yaklaşıma dönüş yaşanmış, ancak bu sefer daha gelişmiş bir seviyede gerçekleşmiştir. Araştırmacılar, verilerden otomatik olarak elde edilen buluşsal yöntemlere değil, kendi kodladıkları prosedürlerle bilginin önemini belirlemeye yönelmişlerdir. Temel cümle analizi, konsept analizi gibi yaklaşımları benimsemişler ve çalışmaları daha öncekilerden farklı bir perspektife taşımışlardır.</p><h4>2000&#39;li Yıllar / Makine Öğrenimi Tabanlı Yaklaşımlar:</h4><p>2000&#39;li yıllarda, metin özetleme çalışmaları, yapay zeka alanındaki gelişmelerden önemli ölçüde yararlanmıştır. Bu dönemde, makine öğrenimi algoritmaları kullanılarak, daha iyi özetler oluşturulmuştur. Veri depolama ve işleme teknolojilerindeki gelişmeler, makine öğrenimli metin özetleme yöntemlerinin daha yaygın bir şekilde kullanılmasını sağlamıştır. Bu dönemde özetleme çalışmalarını iyileştirebilmek için Bayes Sınıflandırıcı, Karar Ağaçları, Saklı Markov Modelleri gibi çeşitli istatistiki modellerin hemen hemen hepsi denenmiştir.</p><h4>2015’li yıllar ve günümüz / Derin Sinir Ağları Tabanlı Yaklaşımlar:</h4><p>Geleneksel makine öğrenimi yaklaşımlarının 2000&#39;li yıllarda getirdiği iyileştirmelere rağmen, 2015 yılında derin öğrenme temelli sinirsel yaklaşımlar metin özetleme alanında önemli bir dönüm noktası oldu. Derin öğrenme tabanlı sinir ağları, karmaşık ilişkileri çıkararak verilerdeki kalıpları bulabilen doğrusal olmayan istatistiksel veri modelleme araçlarıdır. Özellikle bu dönemde, seq2seq kullanılarak yapılan metin özetlemelerinde, RNN, LSTM gibi modellerin katkısıyla büyük ilerlemeler kaydedildi. Bu modeller, metnin giriş ve çıkışını bir dizi sayısal değer olarak temsil ederek, metnin özetini oluşturmaktadır. Ayrıca, Transformer yapısının ortaya çıkmasıyla birlikte NLP görevlerinde geniş kapsamlı bir ilerleme yaşandı. Bu evrimle birlikte, BERT, GPT, PEGASUS, T5 gibi güçlü ve çok yönlü modeller geliştirildi, metin özetleme alanında yeni standartlar belirlendi.</p><h3><strong>C. Metin Özetleme Metotları</strong></h3><p>Metin özetlemenin geçmişten günümüze gelişimine genel bir bakış attık. Geçmişten günümüze gelen çalışmalar sırasında metnin özetini oluşturmak için kullanılan farklı yaklaşımlar vardır. Bu yaklaşımlar, metnin özetlenme amacına, hedef kitleye ve özetin uzunluğuna göre değişiklik gösterebilir. Başlıca yaklaşımlar şu şekildedir:</p><ol><li><em>Single document vs multi-document</em></li><li><em>Generic vs User-Focused</em></li><li><em>Indicative vs Informative</em></li><li><em>Language of Summarizer</em></li><li><em>Extracts vs Abstracts</em></li></ol><p>Bu yaklaşımların arasında özellikle <strong>extracts vs abstracts</strong> yaklaşımı, metin özetleme pratiğinde belirgin bir ayrım sağlar.</p><h3>D. Extractive Method vs Abstractive Method</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/853/1*OpVagPsnDsdUWSAQaQtSCQ.jpeg" /><figcaption>Image Source: <a href="https://aws.amazon.com/tr/blogs/media/democratize-documentation-summarization-with-hugging-face-on-amazon-sagemaker/">here</a></figcaption></figure><p>Extractive summarization (Çıkarımsal özetleme); metin içerisinden önemli cümleleri ve paragrafları çıkararak özet oluşturma işlemidir. Bir belgedeki her cümleye, belgedeki diğer tüm cümlelerle olan ilişkisine göre bir puan atanır. Puanlama, kullandığınız modele/kütüphaneye bağlı olarak farklı olabilir. En yüksek puanları alan cümleler birlikte belgenin özetini oluşturur.</p><p>Abstractive summarization (Özetleyici özetleme); orijinal metnin anlamını anlayarak yeni ve özgün bir özet oluşturma yöntemidir. Bu yöntem, metnin ana fikrini ve önemli ayrıntılarını yakalamak için metni yeniden yazar. Extractive özetlemenin aksine, daha yaratıcı bir yaklaşım benimser ve özgün bir dil kullanarak metni daha kısa bir şekilde ifade etmeye çalışır.</p><p>Her iki yöntemin de avantajları ve dezavantajları vardır. Extractive, orijinal metinde bulunan önemli bilgileri koruma eğilimindeyken, abstractive daha özgün ve esnek bir özetleme sağlar. Bu yazı bağlamında, özetleyici özetlemeye (abstractive summarization) bir örnek olarak T5 modeli ile çalışacağız.</p><h3>E. Seq2seq, Attention, Transformers ve T5</h3><p>Metin özetleme konusunda daha derin bir anlayış oluşturabilmek için sequence-to-sequence, attention, transformers ve T5 gibi büyük dil modelinden de kısaca bahsetmek istiyorum.</p><h4>Sequence-to-sequence:</h4><ul><li>Seq2seq, sinir ağı öğreniminde sıralı girdiyi kabul eden bir sinir ağıdır. Bu bir RNN olabileceği gibi bir CNN ya da başka bir mimari de olabilir.</li><li>Özellikle çeviri, özetleme, üretken soru yanıtlama ve sınıflandırma gibi doğal dil işleme görevlerinde kullanılır</li><li>Encoder-Decoder yapısını temel alır, giriş verisini anlamak için bir “encoder” ve çıkış verisini üretmek için bir “decoder” içerir.</li></ul><h4>Attention:</h4><ul><li>Attention, derin öğrenme modellerinde kullanılan ve girdinin farklı kısımlarına farklı ağırlıklar atayarak modelin çeviri veya özetleme gibi görevleri yerine getirirken en önemli bilgilere öncelik vermesini ve bunları vurgulamasını sağlayan bir mekanizmadır.</li><li>Özellikle uzun metinlerle çalışırken bilgi aktarımını kolaylaştırır.</li><li>Metin özetleme için oldukça etkili bir yöntemdir. Bu nedenle, Transformers gibi birçok mimaride kullanılır.</li></ul><h4>Transformers:</h4><ul><li>Transformer mimarisi, özellikle doğal dil işleme görevlerinde büyük başarı elde etmiş bir model yapısıdır.</li><li>Self-attention mekanizması kullanır, bu da her kelimenin diğer kelimelerle etkileşimini daha iyi modellenebilmesini sağlar.</li><li>Paralel hesaplamaları teşvik eder, bu da eğitim sürelerini kısaltır.</li></ul><p>NLP problemlerinde büyük sorunların bir tanesi modeli eğitecek veriyi elde etmektir. Neyse ki büyük dil modelleri bu iş yükünü almışlardır. Önceden eğitilmiş T5, PEGASUS gibi modeller sayesinde, gerçek veriler üzerinde modelde ince ayar (Fine-tuning) yapabiliriz. Metin özetlemede sıklıkla kullanılan önceden eğitilmiş T5 modeline de kısaca göz atalım ve model oluşturmaya başlayalım.</p><h4>T5 (Text-To-Text Transfer Transformer):</h4><p>T5 modeli, bir encoder ve bir decoder olmak üzere iki ana bileşenden oluşan çok amaçlı bir modeldir. Encoder, girdi dizisini kodlar ve decoder, kodlanmış veriyi kullanarak çıktı dizisini oluşturur. T5 modeli, encoder ve decoder için Transformer mimarisini kullanır. Transformer mimarisi, bir girdi dizisini bir çıktı dizisine dönüştürmek için dikkat mekanizmasını kullanır. T5 modeli, seq-to-seq yapısı ve Transformer mimarisi sayesinde, farklı türde yaratıcı metin formatları üretebilir. Bu formatlar arasında şiirler, kodlar, senaryolar, müzik parçaları, e-posta, mektuplar vb. yer alır.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*2L35TfIIZ3eDh_T_jSyuJA.gif" /><figcaption>Source: <a href="https://blog.research.google/2020/02/exploring-transfer-learning-with-t5.html">here</a></figcaption></figure><h3>F. Google T5 Dil Modeli ile Metin Özetleme</h3><p>Geçmişten günümüze metin özetlemede kullanılan yaklaşımlar ve tekniklere baktığımıza göre, sıra model geliştirme aşamasına geldi. Model geliştirme işlemi yüksek donanım ve zaman gerektirdiği için, <a href="https://colab.google/">Google Colab</a> veya <a href="https://www.kaggle.com/">Kaggle</a> gibi platformlar kullanmanızı tavsiye ederim.</p><p><strong>Adım 1</strong>: Gerekli yükleme işlemlerinin yapılması<br>Modeli oluşturmak için gereken kütüphaneleri yüklüyoruz. Ayrıca Hugging Face kütüphanesinden dil modellerini indirmek ve kullanabilmek için gereken kullanıcı girişini sağlamamız gerekiyor. Hugging Face’e henüz kaydolmadıysanız; <a href="https://huggingface.co/">buradan</a> kaydolun. HuggingFace Token’ininz yoksa, üye olduktan sonra <a href="https://huggingface.co/settings/tokens">buradan</a> kendi token’ınızı oluşturabilir ve kullanabilirsiniz:</p><pre>import nltk<br>import numpy as np<br><br>from datasets import load_dataset<br>from evaluate import load<br><br>import transformers<br><br>from transformers import AutoTokenizer<br>from transformers import AutoModelForSeq2SeqLM, DataCollatorForSeq2Seq, Seq2SeqTrainingArguments, Seq2SeqTrainer<br><br>from transformers import AutoModelForSeq2SeqLM<br><br>from huggingface_hub import notebook_login<br>notebook_login()<br><br>!pip install datasets evaluate transformers rouge-score nltk<br>!apt install git-lfs<br><br>print(transformers.__version__)</pre><p>Birbirlerinden farklı parametre sayılarına sahip çeşitli T5 modelleri bulunmaktadır (t5-small, t5-base, t5-large, t5-xl, t5-xxl). Bu çalışmada, fine-tune yapmak için <a href="https://huggingface.co/t5-small">t5-small</a> modelini ve <a href="https://huggingface.co/datasets/EdinburghNLP/xsum">XSum</a> veri setini kullanacağız. Değerlendirme metriği olarak ise <a href="https://huggingface.co/spaces/evaluate-metric/rouge">ROGUE</a> (Recall-Oriented Understudy for Gisting Evaluation) kullanacağız.</p><pre>model_checkpoint = &quot;t5-small&quot;<br>raw_datasets = load_dataset(&quot;xsum&quot;)<br>metric = load(&quot;rouge&quot;)</pre><p>Fine-tune işleminde kullanacağımız veri setine genel bir göz gezdirmek için ufak bir fonksiyon yazabiliriz. Aşağıdaki fonksiyon ile birlikte “train, validation ve test” olarak ayrılmış veri setinden train setine ufak bir göz atalım.</p><pre>import datasets<br>import random<br>import pandas as pd<br>from IPython.display import display, HTML<br><br>def show_random_elements(dataset, num_examples=5):<br>    assert num_examples &lt;= len(dataset), &quot;Can&#39;t pick more elements than there are in the dataset.&quot;<br>    picks = []<br>    for _ in range(num_examples):<br>        pick = random.randint(0, len(dataset)-1)<br>        while pick in picks:<br>            pick = random.randint(0, len(dataset)-1)<br>        picks.append(pick)<br>    <br>    df = pd.DataFrame(dataset[picks])<br>    for column, typ in dataset.features.items():<br>        if isinstance(typ, datasets.ClassLabel):<br>            df[column] = df[column].transform(lambda i: typ.names[i])<br>    display(HTML(df.to_html()))<br><br>show_random_elements(raw_datasets[&quot;train&quot;])</pre><p>Train veri setinden bazı örnekler:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TcyMFfFuFNInP1pu4qqsHQ.png" /><figcaption>A sample slice from the training dataset</figcaption></figure><p><strong>Adım 2:</strong> Verileri Ön İşleme<br>Modeli verilerle eğitmeden önce, verileri bir ön işleme adımından geçirmemiz gerekiyor. Bu adımda verileri modelin kabul ettiği şekle dönüştürmek gerekiyor. Bu işlemi <em>transformers</em> altında bulunan <em>AutoTokenizer</em> kullanarak gerçekleştirebiliriz.</p><pre>tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)</pre><p>Seçtiğimiz modele göre, Tokenizer’ın farklı sayılar döndürdüğünü göreceksiniz. Modelin eğitilebilmesi için bu dönüşüm gereklidir. Tokenizer’a bir cümle veya cümle listesi ileterek dönen değerlere bir bakalım:</p><pre>tokenizer([&quot;Merhaba, bu birinci cümledir.&quot;, &quot;Bu ise başka bir cümledir.&quot;])</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GT-nS0F14QdJr-VadU70HQ.png" /><figcaption>An example of tokenization</figcaption></figure><p>Yukarıda T5 modelinin çoklu görevler yapabildiğinden bahsetmiştim. Modelin geliştiricileri, hangi görev için kullanılacağı problemini ön ek kullanarak etkili bir şekilde çözmüşlerdir. Kullanıcılar olarak, hangi görevde kullanmak istiyorsak onu belirtmemiz gerekir. Özetleme işlemi için “summarize” ön ekini kullanmamız gerekiyor.</p><pre>if model_checkpoint in [&quot;t5-small&quot;, &quot;t5-base&quot;, &quot;t5-larg&quot;, &quot;t5-3b&quot;, &quot;t5-11b&quot;]:<br>    prefix = &quot;summarize: &quot;<br>else:<br>    prefix = &quot;&quot;</pre><p>Örnekleri ön işleme tabi tutacak fonksiyonu yazabiliriz. Bunları sadece <em>truncation=True</em> argümanıyla tokenizer’a veriyoruz. Bu, seçilen modelin işleyebileceğinden daha uzun bir girdinin model tarafından kabul edilen maksimum uzunluğa kadar kesilmesini sağlayacaktır.</p><pre>max_input_length = 1024<br>max_target_length = 128<br><br>def preprocess_function(examples):<br>    inputs = [prefix + doc for doc in examples[&quot;document&quot;]]<br>    model_inputs = tokenizer(inputs, max_length=max_input_length, truncation=True)<br><br>    labels = tokenizer(text_target=examples[&quot;summary&quot;], max_length=max_target_length, truncation=True)<br><br>    model_inputs[&quot;labels&quot;] = labels[&quot;input_ids&quot;]<br>    return model_inputs</pre><p>Ham veri kümesini modele uygun şekilde tokenleştiriyoruz. İşlemi verimli şekilde gerçekleştirmek için batch işlemi kullanılır.</p><pre>tokenized_datasets = raw_datasets.map(preprocess_function, batched=True)</pre><p><strong>Adım 3:</strong> Model Fine-Tuning</p><p>Artık verilerimiz hazır olduğuna göre önceden eğitilmiş modeli indirebilir ve ince ayarını yapabiliriz. Görevimiz sequence-to-sequence olduğu için AutoModelForSeq2SeqLM sınıfını kullanıyoruz.</p><pre>model = AutoModelForSeq2SeqLM.from_pretrained(model_checkpoint)</pre><p>Bir Seq2SeqTrainer’ı başlatmak için üç şey daha yapmamız gerekecek. Bunlardan en önemlisi, eğitimi özelleştirmeye yönelik tüm nitelikleri içeren bir sınıf olan Seq2SeqTrainingArguments’tir. Modelin kontrol noktalarını kaydetmek için kullanılacak bir klasör adı gerektirir ve diğer tüm argümanlar isteğe bağlıdır. (Diğer argümanların en iyi parametrelerini bulmak için birden fazla deneme yapılabilir.)</p><pre>batch_size = 16<br>model_name = model_checkpoint.split(&quot;/&quot;)[-1]<br>args = Seq2SeqTrainingArguments(<br>    f&quot;{model_name}-finetuned-xsum&quot;,<br>    evaluation_strategy = &quot;epoch&quot;,<br>    learning_rate=2e-5,<br>    per_device_train_batch_size=batch_size,<br>    per_device_eval_batch_size=batch_size,<br>    weight_decay=0.01,<br>    save_total_limit=3,<br>    num_train_epochs=1,<br>    predict_with_generate=True,<br>    fp16=True,<br>    push_to_hub=True,<br>)</pre><p>Burada değerlendirmeyi her epochun sonunda yapılacak şekilde ayarlıyoruz, öğrenme oranını değiştiriyoruz, hücrenin üst kısmında tanımlanan batch_size değerini kullanıyoruz ve ağırlık azalmasını özelleştiriyoruz. Seq2SeqTrainer modeli düzenli olarak kaydedeceğinden ve veri setimiz oldukça büyük olduğundan, ona en fazla üç kayıt yapmasını söylüyoruz. Son olarak, özetleri düzgün bir şekilde oluşturmak için predict_with_generate seçeneğini kullanıyoruz.</p><p>Son argüman her şeyi ayarlamak içindir, böylece modeli eğitim sırasında düzenli olarak Hub’a gönderebiliriz.</p><pre>data_collator = DataCollatorForSeq2Seq(tokenizer, model=model)</pre><p>Seq2SeqTrainer’ımız için tanımlamamız gereken son şey, tahminlerden metriklerin nasıl hesaplanacağıdır. Bunun için daha önce yüklediğimiz metriği kullanacak bir fonksiyon tanımlamamız ve tahminleri metinlere dönüştürmek için biraz ön işleme yapmamız gerekiyor.</p><pre>def compute_metrics(eval_pred):<br>    predictions, labels = eval_pred<br>    decoded_preds = tokenizer.batch_decode(predictions, skip_special_tokens=True)<br>    <br>    labels = np.where(labels != -100, labels, tokenizer.pad_token_id)<br>    decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)<br>    <br>    decoded_preds = [&quot;\n&quot;.join(nltk.sent_tokenize(pred.strip())) for pred in decoded_preds]<br>    decoded_labels = [&quot;\n&quot;.join(nltk.sent_tokenize(label.strip())) for label in decoded_labels]<br>    <br>    result = metric.compute(predictions=decoded_preds, references=decoded_labels, use_stemmer=True, use_aggregator=True)<br>    result = {key: value * 100 for key, value in result.items()}<br>    <br>    prediction_lens = [np.count_nonzero(pred != tokenizer.pad_token_id) for pred in predictions]<br>    result[&quot;gen_len&quot;] = np.mean(prediction_lens)<br>    <br>    return {k: round(v, 4) for k, v in result.items()}</pre><p>Daha sonra tüm bunları veri kümelerimizle birlikte Seq2SeqTrainer’a aktarmamız gerekiyor.</p><pre>trainer = Seq2SeqTrainer(<br>    model,<br>    args,<br>    train_dataset=tokenized_datasets[&quot;train&quot;],<br>    eval_dataset=tokenized_datasets[&quot;validation&quot;],<br>    data_collator=data_collator,<br>    tokenizer=tokenizer,<br>    compute_metrics=compute_metrics<br>)</pre><p>Artık sadece train yöntemini çağırarak modelimizi fine-tune edebiliriz.</p><pre>trainer.train()</pre><p>Uzuuuuuuun süren bir eğitim nihayet tamamlandı. Modelin ROGUE değerleri aşağıdaki gibidir:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*ZPC2w26QPMF2vjTkQk5Umw.png" /><figcaption>ROGUE values of the Model</figcaption></figure><p>Modelimizi kullanarak bir de örnek yapalım. İngilizce Wikipedia’dan Mustafa Kemal Atatürk ile ilgili bir pasaj aldım ve bunu özetlemesini istedim:</p><pre>Mustafa Kemal Atatürk, also known as Mustafa Kemal Pasha until 1921, <br>and Ghazi Mustafa Kemal from 1921 until the Surname Law of 1934 <br>(c. 1881 – 10 November 1938), was a Turkish field marshal, <br>revolutionary statesman, author, and <br>the founding father of the Republic of Turkey, <br>serving as its first president from 1923 until his death in 1938. <br>He undertook sweeping progressive reforms, <br>which modernized Turkey into a secular, industrializing nation. <br>Ideologically a secularist and nationalist, his policies <br>and socio-political theories became known as Kemalism. <br>Due to his military and political accomplishments, <br>Atatürk is regarded as one of the most important <br>political leaders of the 20th century.</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/378/1*_l0lih-n9oTsF8SDFK2VGg.png" /><figcaption>Summary given by the model</figcaption></figure><p>Son olarak fine-tune edilen modeli HuggingFace Hub’a yüklemek isterseniz:</p><pre>trainer.push_to_hub()<br><br>model = AutoModelForSeq2SeqLM.from_pretrained(&quot;huggingface_kullanici_ismi/model_ismi&quot;)</pre><p>Belki daha uzun bir metin, başka parametreler, daha büyük bir model kullanmalıydık ya da T5 modelinin yapısını değiştirmeliydik. Ancak karmaşık bir metni NLP modeliyle özetlemeye ne kadar çabalarsanız çabalayın, her zaman modelin özetlemeyi başaramadığı belgelerle karşılaşabiliriz. Hala ilerleme kaydedilecek çok araştırma alanı olduğunu düşünüyorum. Ayrıca, sistem donanımlarınız yeterliyse FLAN-T5 veya PEGASUS gibi daha güçlü dil modellerini de incelemenizi öneririm. Okuduğunuz için teşekkür ediyorum.</p><p><strong>Ayrıntılı notebooka </strong><a href="https://github.com/rolmez/text-summarization-finetuned-T5"><strong>bu linkten</strong></a><strong> ulaşabilirsiniz.</strong></p><p>Soru veya güncellemeleriniz için bana aşağıdaki bağlantılardan ulaşabilirsiniz:<br>LinkedIn: <a href="https://www.linkedin.com/in/ramazanolmez/"><strong>https://www.linkedin.com/in/ramazanolmez/</strong></a><strong><br></strong>Mail: <strong>ramazanolmeez@gmail.com</strong></p><p>Kaynakça:</p><p>Rothman, D., Transformers for Natural Language Processing Second Edition / Build, train, and fine-tune deep neural architectures for NLP with Python, PyTorch, TensorFlow, BERT, and GPT-3</p><p>Signh, J., NATURAL LANGUAGE PROCESSING IN THE REAL WORLD / Text Processing, Analytics, and Classification</p><p>Zechner, K., (1997) A literature survey on information extraction and text summarization. Computational Linguistics Program, Carnegie Mellon University, [online] Fall 1996. Available at: <a href="http://www.cs.cmu.edu/afs/cs.cmu.edu/Web/People/zechner/infoextr.pdf">http://www.cs.cmu.edu/afs/cs.cmu.edu/Web/People/zechner/infoextr.pdf</a>.</p><p>Zhang, H., Cai, J., Xu, J. and Wang, J., (2019a) Pretraining-Based Natural Language Generation for Text Summarization. In: Proceedings of the 23rd Conference on Computational Natural Language Learning (CoNLL). [online] Stroudsburg, PA, USA: Association for Computational Linguistics, pp.789–797. Available at: <a href="https://www.aclweb.org/anthology/K19-1074">https://www.aclweb.org/anthology/K19-1074</a>.</p><p>Saggion, Horacio., Poibeau, Thierry., Automatic Text Summarization: Past, Present, and Future</p><p>Orasan, C., Automatic Summarisation: 25 Years On</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=620a8a474109" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>