<jupyter_start><jupyter_text>Sparsity feature selector- We select the top-k features for a given dataset X (N_samples x N_feats). X is expected to be binary. X[i,j] = 1 denotes that the feature j for sample i is not missing while X[i,j] = 0 denotes a missing feature.- The resulting subset of features will have all th<jupyter_code>import cvxpy as cp
import numpy as np

# N_samples X N_features matrix with binary values denoting whether the feature exists
X = np.random.randint(2, size=(1000, 60))
#X = np.vstack((np.ones((1000,60)), np.hstack((np.zeros((1000,30)), np.ones((1000,30)))), np.random.randint(2, size=(1000,60))))

print(f'Sparsity of features:\n{100 * (1 - (X.sum(axis=0) / len(X)))}')
N_samples = X.shape[0]
N_features = X.shape[1]

k = cp.Constant(2)

# # The costs for each feature
w = cp.Constant(X)
# Variables containing the number of the coins to be returned for each denominator
# The size of this must be equal to the denominations w
x = cp.Variable((1, N_features), boolean=True)

# We want to minimize the total number of coins returned
objective = cp.Minimize(cp.sum(k - w @ x.T))



# The constraints
constraints = [
    cp.sum(x) == k,
    x>=0 # semi-positive coins
]
# Form and solve problem.
prob = cp.Problem(objective, constraints)
# Need the GLPK_MI solver because the ECOS_BB is not working correctly.
prob.solve(solver = 'GLPK_MI') # Returns the optimal value.
if prob.status == 'infeasible':
    print("Can't change %s with denominations: %s"%(CASH.__str__(), w.__str__()))
else:
    #return
    res = x.value.flatten()
    keeping = np.sum(X[:, res.astype(bool)].sum(axis=1)==k.value)
    print(f"Best result with keeping: {int(keeping)} / {N_samples} ({100 * (int(keeping)) / N_samples:.2f} %)")
    print(f"Best feature indices: {res}")
#  Keeping only the selected features
subset = X[:, res.astype(bool)]
# Dropping non-zero rows
subset = subset[np.all(subset, axis=1)]
print(f'Keeping: {subset.shape}')
def find_best_feats(X, top_k, print_=False):
    if print_:
        print(f'Sparsity of features:\n{100 * (1 - (X.sum(axis=0) / len(X)))}')
    N_samples = X.shape[0]
    N_features = X.shape[1]

    k = cp.Constant(top_k)

    # # The costs for each feature
    w = cp.Constant(X)
    # Variables containing the number of the coins to be returned for each denominator
    # The size of this must be equal to the denominations w
    x = cp.Variable((1, N_features), boolean=True)

    # We want to minimize the total number of coins returned
    objective = cp.Minimize(cp.sum(k - w @ x.T))



    # The constraints
    constraints = [
        cp.sum(x) == k,
        x>=0 # semi-positive coins
    ]
    # Form and solve problem.
    prob = cp.Problem(objective, constraints)
    # Need the GLPK_MI solver because the ECOS_BB is not working correctly.
    prob.solve(solver = 'GLPK_MI') # Returns the optimal value.
    if prob.status == 'infeasible':
        print("Can't change %s with denominations: %s"%(CASH.__str__(), w.__str__()))
        raise Error
        return []
    else:
        #return
        res = x.value.flatten()
        keeping = np.sum(X[:, res.astype(bool)].sum(axis=1)==k.value)
        if print_:
            print(f"Best result with keeping: {int(keeping)} / {N_samples} ({100 * (int(keeping)) / N_samples:.2f} %)")
            print(f"Best feature indices: {res}")
        return res
X = np.random.randint(2, size=(1000, 60))
perc = []
for k in range(1, X.shape[1]):
    res = find_best_feats(X, k)
    subset = X[:, res.astype(bool)]
    keeping = np.sum(subset.sum(axis=1)==k)
    print(f"# features {k} | Result: {int(keeping)} / {N_samples} ({100 * (int(keeping)) / N_samples:.2f} %)")
    print(f'X shape: {subset[np.all(subset, axis=1)].shape}')
    perc.append(int(keeping) / N_samples)
    #break
    
N_samples - np.count_nonzero((X @ x.T).reshape(-1,) - k)
np.dot(X, x.T).shape
np.count_nonzero((X @ np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]).reshape(1,-1).T - k))
X[:, x.value.flatten().astype(bool)]
lambda_ = 0.5

def l
cp.sum(x) * lambda_ + lambda_*loss()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15423976608187134, 'fraction_numerical': 0.025341130604288498, 'mean_word_length': 3.4961664841182913, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '28440', 'license': 'MIT', 'n_tokens_mistral': 1540, 'n_tokens_neox': 1450, 'n_words': 426, 'path': 'Select_top_non_missing_features.ipynb', 'repo_name': 'kbogas/Cascada', 'size': '4104'}