python大規模データ処理テクニックの2:機械学習でよく使われる操作
1、データの前処理
ランダム化操作
機械学習でよく用いられるランダム化操作ではrandomパケットを用いて重複しない乱数生成を行い,生成した乱数をデータセットの下標として対応するデータセットを切り取ることができる.次の単純で効率的なコードは、基本的なすべてのランダム化前処理操作を実現するのに役立ちます.
データのランダムサンプリング:
データセットはトレーニングセットとテストセットに切り分けられます.
ランダム化データセットサンプルの順序:推奨:一文出力下付き: sklearnパッケージを使用した内蔵操作:マシン学習アルゴリズムのtrainメソッドはrandom_stateパラメータデータのランダム初期化を設定するための ただし、上記の方法で実現しなければ、サンプルごとに2つの値a,bを設定する方法を用いることができる.前者はランダム値、後者は下付き値である ランダム値aを並べ替え基準として各サンプルの2つの値を並べ替え(昇降順ともに可) 並べ替え後のサンプル値bでそのままの本セットのサンプルをアドレスし、順番に並べ替え順に操作すればよい
アンバランス分類抽出:希少類サンプル数を保持し、多数類のサンプルを比例してランダムに抽出する 比較的効率的なコード:
書いた拙劣なコード(推奨しない書き方):pythonの特性を運用せず、純粋にc/c++の思想でコードを書き、コード実行効率が悪い.
2、データセット変換
異なるパケット間のフォーマット変換内蔵データ構造、numpyとpandasのデータ構造の使い道の簡単な説明:(データ格納形式はまとめていない) list、dict、set、tupleなどの内蔵データ構造は最も汎用的なデータ構造であり、使い勝手がよい. numpyのデータ構造はmatlabと非常に類似しており、マトリクス演算などの算術計算に適している.機械学習パッケージscikit-learnがサポートするデータ構造でもある. dataframeの機能はデータベースと若干似ており、データの大規模な処理と分析に適している.
numpyとlist間の変換:リストをnumpyに変換: numpy変換リスト
Dataframeとnumpyの変換:dataframe回転numpy numpy転dataframe
Dataframe,seriesとlist間の変換:list変換dataframeとseries dataframeとseriesをlistに変換
ランダム化操作
機械学習でよく用いられるランダム化操作ではrandomパケットを用いて重複しない乱数生成を行い,生成した乱数をデータセットの下標として対応するデータセットを切り取ることができる.次の単純で効率的なコードは、基本的なすべてのランダム化前処理操作を実現するのに役立ちます.
import random
samp_ids = [i for i in sorted(random.sample(range(nItem), nSample)) ]
# nSample
データのランダムサンプリング:
import random
nItem = len(df)
nSample = 1000
samp_ids = [i for i in sorted(random.sample(range(nItem), nSample)) ]
# nSample
samp_idList = df.id.isin(samp_ids)
df_sample = df[samp_idList]
データセットはトレーニングセットとテストセットに切り分けられます.
import random
nRatio = 2
nTest = int(nSample / nRatio)
nTrain = nSample - nTest
samp_ix = [rowId[i] for i in sorted(random.sample(range(nSample), nTest)) ]
#
list_testSamp = df.row_id.isin(samp_ix)
list_trainSamp = list_testSamp.apply(lambda x: not x)
#
samp_test = df[list_testSamp]
samp_train = df[list_trainSamp]
ランダム化データセットサンプルの順序:
sorted(random.sample(range(nSample), nSample))
このデータセットをランダム下付き順で巡る def randomlizeSample(X_row, y_row):
nSample, nFeat = np.shape(X_row)
inx1 = DataFrame(np.random.randn(nSample), columns = ['randVal'])
inx2 = DataFrame(range(nSample), columns = ['inxVal'])
inx = pd.concat([inx1, inx2], axis = 1)
inx = inx.sort_index(by = 'randVal', ascending = False)
cnt = 0;
X = np.zeros((nSample, nFeat))
y = np.zeros((nSample))
# you should not set X and y to []
for line in inx['inxVal']:
X[cnt] = X_row[line]
y[cnt] = y_row[line]
cnt += 1
return X, y
アンバランス分類抽出:
def sampleBalance(df, lableColumn, th):
label_counts = df[lableColumn].value_counts()
#
mask = (label_counts[df[lableColumn].values] >= th).values
df = df.loc[mask]
#
label_counts = df[lableColumn].value_counts()
#
labels = label_counts.order(ascending = False).index
nLabel = len(labels)
nSampPerLabel = label_counts[labels[-1]]
balancedSamples = pd.DataFrame()
for n in range(nLabel):
df_label = df[lableColumn == labels[n]]
nItem = len(df_label)
df_label.reindex(range(nItem))
#
samp_index = [i for i in sorted(random.sample(range(nItem),
nSampPerLabel))]
samp_list = df_label[lableColumn].isin(samp_index)
df_label = df_label[samp_list]
balancedSamples = pd.concat([balancedSamples, df_label], axis = 1)
return balancedSamples, [label for lable in labels]
書いた拙劣なコード(推奨しない書き方):pythonの特性を運用せず、純粋にc/c++の思想でコードを書き、コード実行効率が悪い.
- def sampleBalance(X_row, y_row):
- rate_np = 1
- # radio of negative sample and positive sample
- nSample, nFeat = np.shape(X_row)
- nSample_pos = np.sum(y_row == 1)
- nSample_neg = np.sum(y_row == 0)
- nSample_negOnRate = np.floor(nSample_pos * rate_np)
- print(nSample, nSample_pos, nSample_neg)
- X = np.zeros((nSample_pos + nSample_negOnRate, nFeat))
- y = np.zeros((nSample_pos + nSample_negOnRate))
- # get pos sample
- id_pos = 0
- id_neg = 0
- X_neg = np.zeros((nSample_neg, nFeat))
- for i in range(nSample):
- if y_row[i] == 1:
- X[id_pos] = X_row[i]
- y[id_pos] = 1
- id_pos += 1
- else:
- X_neg[id_neg] = X_row[i]
- id_neg += 1
- inx1 = DataFrame(np.random.randn(nSample_neg), columns = ['randVal'])
- inx2 = DataFrame(range(nSample_neg), columns = ['inxVal'])
- inx = pd.concat([inx1, inx2], axis = 1)
- inx = inx.sort_index(by = 'randVal', ascending = False)
- cnt = 0
- for line in inx['inxVal']:
- if cnt >= nSample_negOnRate:
- break
- X[nSample_pos + cnt] = X_neg[line]
- y[nSample_pos + cnt] = 0
- cnt += 1
- X_rand, y_rand = randomlizeSample(X, y)
- return X_rand, y_rand
2、データセット変換
異なるパケット間のフォーマット変換
numpyとlist間の変換:
data = [[6, 7.5, 8, 0, 1], [6, 7.5, 8, 0, 1]]
arr = np.array(data)
## numpy :
data = [[6, 7.5, 8, 0, 1], [6, 7.5, 8, 0, 1]]
arr = np.array(data)
data = arr.tolist()
## :
data = [[elem for elem in line] for line in arr]
Dataframeとnumpyの変換:
X_train = df.values.astype(int) # df numpy ndarray, int
columns = ['c0', 'c1', 'c2', 'c3', 'c4']
df = pd.DataFrame(X_train, columns = columns)
Dataframe,seriesとlist間の変換:
data = [[6, 7.5, 8, 0, 1], [6, 7.5, 8, 0, 1]]
columns = ['c0', 'c1', 'c2', 'c3', 'c4']
df = pd.DataFrame(data, columns = columns)
data = [6, 7.5, 8, 0, 1]
ser = pd.series(data)
## dataframe list
df['c0'].values.tolist() # list
df.values.tolist() # dataframe list
## series list
ser.values.tolist() # series list