如何按行处理Pandas Dataframe

qv7cva1a  于 2023-04-19  发布在  其他
关注(0)|答案(1)|浏览(133)

我正在做一个ID3算法的实现。我遇到的问题是处理来自新根属性的分支
正如指纹所示

gain: 1.263221025628615 for Material
processing attribute Volume
processing branch 1 for Volume
processing branch 6 for Volume
processing branch 4 for Volume
processing branch 2 for Volume
processing branch 5 for Volume
processing branch 3 for Volume
gain: 0.6036978279454468 for Volume
attribute Venue has the max gain of 0.6036978279454468
removing Venue
new root Venue has branches [2 1]

步骤3的最后一步应该通过所选属性的唯一值过滤 Dataframe :

from numpy.core.defchararray import count
import pandas as pd
import numpy as np
import numpy as np
from math import ceil, floor, log2
from sklearn.decomposition import PCA
from numpy import linalg as LA
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB

def calculate_metrics(tp, tn, fn, p, n, fp):
    # calculate the accuracy, error rate, sensitivity, specificity, and precision for the selected classifier in reference to the corresponding test set.
    accuracy = tp + tn /(p+n)
    error_rate = fp + fn /(p + n)
    sensitivity = tp/ p
    precision = tp/ (tp+fp)
    specificity = tn/n

    display_metrics(accuracy, error_rate, sensitivity, precision, specificity)

def display_metrics(accuracy, error_rate, sensitivity, precision, specificity):
    print(f'Accuracy: {accuracy}, Error_rate:{error_rate}, Sensitivity:{sensitivity}, Precision:{precision}, specificity:{specificity}')

def mc(columnName,training_set):
    column = training_set[columnName]
    probs = column.value_counts(normalize=True)
    messageConveyed = -1*np.sum(np.log2(probs)*probs)
    # print(f'mc {messageConveyed}')
    return messageConveyed

def isUnique(s):
    a = s.to_numpy() # s.values (pandas<0.24)
    return (a[0] == a).all()

def ID3(threshold,g):
    # use the training set to predict the test set.
    # use the Assignment 2--Training set to extract rules and test the quality of the extracted rules against the Assignment 2-- Test set for ID3.
    test_set = pd.read_csv("Assignment 2--Test set for ID3.csv")
    training_set = pd.read_csv("Assignment 2--Training set for ID3.csv")

    print('***********************************')
    print('TRAINING SET')
    print(training_set)
    print('***********************************')

    print('***********************************')
    print('TEST SET')
    print(test_set)
    print('***********************************')

    print(f'test_set: {test_set}')
    print(f'training_set: {training_set}')

    # Step 1- Calculate MC (Message Conveyed) for the given data set in reference to the class attribute
    print(f'Step 1- Calculate MC (Message Conveyed) for the given data set in reference to the class attribute')
    # MC = -p1*log2(p1) - p2*log2(p2)
    # For n classes MC = -p1log2(p1) - p2*log2(p2)-...-pn*log2(pn)

    # For each column calculate the gain.
    numberOfColumns = 0
    mcDictionary = {}
    print('***********************************')
    print('For each column calculate the gain.')
    for (columnName, columnData) in training_set.iteritems():
        messageConveyed = mc(columnName,training_set)
        mcDictionary.update({columnName:round(messageConveyed)})
        numberOfColumns+=1
    print('***********************************')
    print(f'numberOfColumns {numberOfColumns}')
    print(f'mcDictionary {mcDictionary}')

    # The column with the highest gain is the root.
    print(f'The column with the highest gain is the root.')
    values = mcDictionary.values()
    max_value = max(values)
    print(f'The max value is {max_value}')
    # print(f'The max value, {max_value}, is associated with column {columnWithMaximumInformationGain}')
    val_list = list(values)
    columnWithMaximumInformationGain = list(mcDictionary.keys())[list(mcDictionary.values()).index(max_value)]
    print(f'The max value, {max_value}, is associated with column {columnWithMaximumInformationGain}')

    # select the max value from the gain array
    # this is the new root
    root =  columnWithMaximumInformationGain
    print(f'root is {root}')
    print("******************************************")
    print("**************   ROOT   ******************")
    print(f"TF is {root}**********************")
    print("******************************************")
    print(f'isUnique = {isUnique(training_set[root])}')
    if(isUnique(training_set[root])):
        return   
    
    # Step 2 - Repeat for every attribute
    print(f'Step 2 - Repeat for every attribute')
    # Loop 1
    attribute = ""
    maximum       = 0 
    for (F, columnData) in training_set.iteritems():
        print(f'processing attribute {F}')
        # Loop 2
        Total = 0
        uniques = training_set[F].unique()
        for k in uniques:
            print(f'processing branch {k} for {F}')
            # Calculate MC for column
            messageConveyed = mc(F,training_set)

            # Calculate the weight for F
            F_D    = training_set[F].count()
            TF_D   = training_set[root].count()

            weight = F_D/TF_D
            total = weight*messageConveyed
        gain = mcDictionary[root] - total
        if(gain > maximum):
            attribute = F
            maximum   = gain 
        print(f"gain: {gain} for {F}")
    
    print(f'attribute {attribute} has the max gain of {gain}')
    print(f'removing {attribute}')
    root = attribute
    print(f'new root {root} has branches {training_set[root].unique()}')
    del training_set[attribute]

    # Step 3 - Examine dataset of each leaf
    print(f'')


    

def BayesClassifier(training_set,test_set):
    # use the assignment 2-- training set for Bayes as the training set to classify the records of the assignment 2 test set for bayes
    X = test_set.values
    Y = training_set.values
    clf = GaussianNB()
    clf.fit(X, Y)



# prompt user to select either ID3 or Bayes classifier.
selection = "ID3" #= input("Please enter your selection for either ID3 or Bayes classification: ")
threshold = 0.9   #= input("Please enter a threshold: ")
g         = 0.05   #= input("Please enter a value for g: ")

if(selection == "ID3"):
    ID3(threshold,g)

if(selection == "Bayes"):
    BayesClassifier()

给定训练集

Venue,color,Model,Category,Location,weight,Veriety,Material,Volume
2,6,4,4,4,2,2,1,1
1,2,4,4,4,1,6,2,6
1,5,4,4,4,1,2,1,6
2,4,4,4,4,2,6,1,4
1,4,4,4,4,1,2,2,2
2,4,3,3,3,2,1,1,1
1,5,2,1,4,1,6,2,6
1,2,3,3,3,1,2,1,6
2,6,4,4,4,2,3,1,1
1,4,4,4,4,1,2,1,6
1,5,4,4,4,1,2,1,4

Dataframe 应通过1和2分成两个帧。

Venue, color, Model....
1
1
1
1
1
1
1
1
Venue, color, Model....
2
2
2
2
2
2
2
2
2

如何才能做到这一点?

xtupzzrd

xtupzzrd1#

这似乎做到了。

unique_values = training_set[root].unique()
    datasets = []
    for unique_value in unique_values:
        print(f'processing for file : {unique_value} ')
        df_1 = training_set[training_set[attribute] > unique_value]
        df_2 = training_set[training_set[attribute] <  unique_value]
        datasets.append(df_1)
        datasets.append(df_2)

    del training_set[attribute]

相关问题