代码之家  ›  专栏  ›  技术社区  ›  Avi

泛化随机森林Python的数据集源

  •  -2
  • Avi  · 技术社区  · 8 年前

    source : 我想概括一下,因此它也适用于不同类型的数据集源,例如:

    votes 其内容是:

    republican,n,y,n,y,y,y,n,n,n,y,?,y,y,y,n,y
    republican,n,y,n,y,y,y,n,n,n,n,n,y,y,y,n,?
    democrat,?,y,y,?,y,y,n,n,n,n,y,n,y,y,n,n
    

    vehicle

    sonar

    0.0200,0.0371,0.0428,0.0207,0.0954,0.0986,0.1539,0.1601,0.3109,0.2111,0.1609,0.1582,0.2238,0.0645,0.0660,0.2273,0.3100,0.2999,0.5078,0.4797,0.5783,0.5071,0.4328,0.5550,0.6711,0.6415,0.7104,0.8080,0.6791,0.3857,0.1307,0.2604,0.5121,0.7547,0.8537,0.8507,0.6692,0.6097,0.4943,0.2744,0.0510,0.2834,0.2825,0.4256,0.2641,0.1386,0.1051,0.1343,0.0383,0.0324,0.0232,0.0027,0.0065,0.0159,0.0072,0.0167,0.0180,0.0084,0.0090,0.0032,R
    

    gini_index , str_column_to_float str_column_to_int 功能?如何更改它们,使其适合上述不同类型的数据集?

    # Random Forest Algorithm on Sonar Dataset
    from random import seed
    from random import randrange
    from csv import reader
    from math import sqrt
    
    # Load a CSV file
    def load_csv(filename):
        dataset = list()
        with open(filename, 'r') as file:
            csv_reader = reader(file)
            for row in csv_reader:
                if not row:
                    continue
                dataset.append(row)
        return dataset
    
    # Convert string column to float
    def str_column_to_float(dataset, column):
        for row in dataset:
            row[column] = float(row[column].strip())
    
    # Convert string column to integer
    def str_column_to_int(dataset, column):
        class_values = [row[column] for row in dataset]
        unique = set(class_values)
        lookup = dict()
        for i, value in enumerate(unique):
            lookup[value] = i
        for row in dataset:
            row[column] = lookup[row[column]]
        return lookup
    
    # Split a dataset into k folds
    def cross_validation_split(dataset, n_folds):
        dataset_split = list()
        dataset_copy = list(dataset)
        fold_size = int(len(dataset) / n_folds)
        for i in range(n_folds):
            fold = list()
            while len(fold) < fold_size:
                index = randrange(len(dataset_copy))
                fold.append(dataset_copy.pop(index))
            dataset_split.append(fold)
        return dataset_split
    
    # Calculate accuracy percentage
    def accuracy_metric(actual, predicted):
        correct = 0
        for i in range(len(actual)):
            if actual[i] == predicted[i]:
                correct += 1
        return correct / float(len(actual)) * 100.0
    
    # Evaluate an algorithm using a cross validation split
    def evaluate_algorithm(dataset, algorithm, n_folds, *args):
        folds = cross_validation_split(dataset, n_folds)
        scores = list()
        for fold in folds:
            train_set = list(folds)
            train_set.remove(fold)
            train_set = sum(train_set, [])
            test_set = list()
            for row in fold:
                row_copy = list(row)
                test_set.append(row_copy)
                row_copy[-1] = None
            predicted = algorithm(train_set, test_set, *args)
            actual = [row[-1] for row in fold]
            accuracy = accuracy_metric(actual, predicted)
            scores.append(accuracy)
        return scores
    
    # Split a dataset based on an attribute and an attribute value
    def test_split(index, value, dataset):
        left, right = list(), list()
        for row in dataset:
            if row[index] < value:
                left.append(row)
            else:
                right.append(row)
        return left, right
    
    # Calculate the Gini index for a split dataset
    def gini_index(groups, classes):
        # count all samples at split point
        n_instances = float(sum([len(group) for group in groups]))
        # sum weighted Gini index for each group
        gini = 0.0
        for group in groups:
            size = float(len(group))
            # avoid divide by zero
            if size == 0:
                continue
            score = 0.0
            # score the group based on the score for each class
            for class_val in classes:
                p = [row[-1] for row in group].count(class_val) / size
                score += p * p
            # weight the group score by its relative size
            gini += (1.0 - score) * (size / n_instances)
        return gini
    
    # Select the best split point for a dataset
    def get_split(dataset, n_features):
        class_values = list(set(row[-1] for row in dataset))
        b_index, b_value, b_score, b_groups = 999, 999, 999, None
        features = list()
        while len(features) < n_features:
            index = randrange(len(dataset[0])-1)
            if index not in features:
                features.append(index)
        for index in features:
            for row in dataset:
                groups = test_split(index, row[index], dataset)
                gini = gini_index(groups, class_values)
                if gini < b_score:
                    b_index, b_value, b_score, b_groups = index, row[index], gini, groups
        return {'index':b_index, 'value':b_value, 'groups':b_groups}
    
    # Create a terminal node value
    def to_terminal(group):
        outcomes = [row[-1] for row in group]
        return max(set(outcomes), key=outcomes.count)
    
    # Create child splits for a node or make terminal
    def split(node, max_depth, min_size, n_features, depth):
        left, right = node['groups']
        del(node['groups'])
        # check for a no split
        if not left or not right:
            node['left'] = node['right'] = to_terminal(left + right)
            return
        # check for max depth
        if depth >= max_depth:
            node['left'], node['right'] = to_terminal(left), to_terminal(right)
            return
        # process left child
        if len(left) <= min_size:
            node['left'] = to_terminal(left)
        else:
            node['left'] = get_split(left, n_features)
            split(node['left'], max_depth, min_size, n_features, depth+1)
        # process right child
        if len(right) <= min_size:
            node['right'] = to_terminal(right)
        else:
            node['right'] = get_split(right, n_features)
            split(node['right'], max_depth, min_size, n_features, depth+1)
    
    # Build a decision tree
    def build_tree(train, max_depth, min_size, n_features):
        root = get_split(train, n_features)
        split(root, max_depth, min_size, n_features, 1)
        return root
    
    # Make a prediction with a decision tree
    def predict(node, row):
        if row[node['index']] < node['value']:
            if isinstance(node['left'], dict):
                return predict(node['left'], row)
            else:
                return node['left']
        else:
            if isinstance(node['right'], dict):
                return predict(node['right'], row)
            else:
                return node['right']
    
    # Create a random subsample from the dataset with replacement
    def subsample(dataset, ratio):
        sample = list()
        n_sample = round(len(dataset) * ratio)
        while len(sample) < n_sample:
            index = randrange(len(dataset))
            sample.append(dataset[index])
        return sample
    
    # Make a prediction with a list of bagged trees
    def bagging_predict(trees, row):
        predictions = [predict(tree, row) for tree in trees]
        return max(set(predictions), key=predictions.count)
    
    # Random Forest Algorithm
    def random_forest(train, test, max_depth, min_size, sample_size, n_trees, n_features):
        trees = list()
        for i in range(n_trees):
            sample = subsample(train, sample_size)
            tree = build_tree(sample, max_depth, min_size, n_features)
            trees.append(tree)
        predictions = [bagging_predict(trees, row) for row in test]
        return(predictions)
    
    # Test the random forest algorithm
    seed(2)
    # load and prepare data
    filename = 'sonar.all-data.csv'
    dataset = load_csv(filename)
    # convert string attributes to integers
    for i in range(0, len(dataset[0])-1):
        str_column_to_float(dataset, i)
    # convert class column to integers
    str_column_to_int(dataset, len(dataset[0])-1)
    # evaluate algorithm
    n_folds = 5
    max_depth = 10
    min_size = 1
    sample_size = 1.0
    n_features = int(sqrt(len(dataset[0])-1))
    for n_trees in [1, 5, 10]:
        scores = evaluate_algorithm(dataset, random_forest, n_folds, max_depth, min_size, sample_size, n_trees, n_features)
        print('Trees: %d' % n_trees)
        print('Scores: %s' % scores)
        print('Mean Accuracy: %.3f%%' % (sum(scores)/float(len(scores))))
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Avi    8 年前

    以下是必须更改的代码(数据源是链接):

    import pandas as pd
    file_path = 'https://archive.ics.uci.edu/ml/machine-learning-databases/voting-records/house-votes-84.data'
    dataset2 = pd.read_csv(file_path, header=None, dtype=str)
    v = dataset2.values
    
    f = pd.factorize(v.ravel())[0].reshape(v.shape)
    
    dataset1 = pd.DataFrame(f)
    df = dataset1.astype('str')
    
    dataset = df.values.tolist()
    
    推荐文章