のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

TensorFlowにdefine by run(TensorFlow Eager)がやってきた

皆さんこんにちは
お元気ですか。今回の三連休は二郎食べて満足しました。

Chainerにはじまり、PyTorchなどdefine by runで
ニューラルネットワークを計算するフレームワークがあります。
このdefine by runは非常にRNN系のニューラルネットワークを書く際に重宝しています。

そして、10月末にTensorFlowからもdefine by run用の
インターフェースが試験的に提供されました。それがTensorFlow Eagerです。

※define by runが不明な方はこちらへ
s0sem0y.hatenablog.com

TensorFlow Eager

TensorFlow Eagerは次の公式の記事で紹介されています。
ただし、この機能はPreview段階です。
通常使う場面では問題ないと思いますが、念のため何か起こっても問題ない環境で利用してください。

research.googleblog.com

一言で言うなれば、TensorFlowのdefine by run用のインターフェースです。
次の特徴があるそうです。

  1. 高速なデバッグ
  2. Pythonを利用した動的なモデル
  3. TensorFlowの処理が大体実行可能

インストール

pipに含まれるTensorFlowに含まれていないため、別途インストールが必要です。
1.4.0ではimportをできますが、内部の実装がありません。
そのため、お試しで使うには次のコマンドを実行してください。

pip install tf-nightly

Example集

公式のサンプル集は次に掲載されています。とりあえず、MNISTを使います。
github.com

MNIST サンプルのご紹介

公式MNISTを紹介します。簡単に実装を理解するならばMNISTがわかりやすい。

準備

tensorflow eagerでは最初に次のコードを実行する必要があります。
このコードの実行によりtensorflow eagerでの実行ができます。所謂おまじないのようなコードです。

  tfe.enable_eager_execution()

そして、モデル、最適関数、データセットの準備をします。
MNISTModelの内部のコードに動かすニューラルネットワークを定義します。
実装方式は次で紹介します。

  # Load the datasets
  (train_ds, test_ds) = load_data(FLAGS.data_dir)
  train_ds = train_ds.shuffle(60000).batch(FLAGS.batch_size)

  # Create the model and optimizer
  model = MNISTModel(data_format)
  optimizer = tf.train.MomentumOptimizer(FLAGS.lr, FLAGS.momentum)

モデル

モデル部分のコードです。ChainerのChainやPyTorchのModuleと殆ど似ています。
__init__側に各モジュールを定義します。
Convolutionの計算や全結合層の計算モジュールを定義し、インスタンス変数として定義します。
__init__側で定義するのは、更新するパラメータを持つモジュールです。

計算の仕方はcall関数に定義します。ここで変数に対してどう計算するかを定義します。

class MNISTModel(tfe.Network):
  def __init__(self, data_format):
    super(MNISTModel, self).__init__(name='')
    if data_format == 'channels_first':
      self._input_shape = [-1, 1, 28, 28]
    else:
      assert data_format == 'channels_last'
      self._input_shape = [-1, 28, 28, 1]
    self.conv1 = self.track_layer(
        tf.layers.Conv2D(32, 5, data_format=data_format, activation=tf.nn.relu))
    self.conv2 = self.track_layer(
        tf.layers.Conv2D(64, 5, data_format=data_format, activation=tf.nn.relu))
    self.fc1 = self.track_layer(tf.layers.Dense(1024, activation=tf.nn.relu))
    self.fc2 = self.track_layer(tf.layers.Dense(10))
    self.dropout = self.track_layer(tf.layers.Dropout(0.5))
    self.max_pool2d = self.track_layer(
        tf.layers.MaxPooling2D(
            (2, 2), (2, 2), padding='SAME', data_format=data_format))

  def call(self, inputs, training):
    x = tf.reshape(inputs, self._input_shape)
    x = self.conv1(x)
    x = self.max_pool2d(x)
    x = self.conv2(x)
    x = self.max_pool2d(x)
    x = tf.layers.flatten(x)
    x = self.fc1(x)
    if training:
      x = self.dropout(x)
    x = self.fc2(x)
    return x

メインループ

サンプルのメインとなる処理です。
次のコードでは、1poch分の学習を行い、1epoch分学習が完了したモデルを保存しています。

  with tf.device(device):
    for epoch in range(1, 11):
      with tfe.restore_variables_on_create(
          tf.train.latest_checkpoint(FLAGS.checkpoint_dir)):
        global_step = tf.train.get_or_create_global_step()
        start = time.time()
        with summary_writer.as_default():
          train_one_epoch(model, optimizer, train_ds, FLAGS.log_interval)
        end = time.time()
        print('\nTrain time for epoch #%d (global step %d): %f' % (
            epoch, global_step.numpy(), end - start))
      with test_summary_writer.as_default():
        test(model, test_ds)
      all_variables = (
          model.variables
          + optimizer.variables()
          + [global_step])
      tfe.Saver(all_variables).save(
          checkpoint_prefix, global_step=global_step)

学習

次のコードは学習するコードです。
モデル 部分で定義したmodelを使います。全体の流れは次の通りです。

  1. バッチごとのデータセットiteratorで取得する。(tfe.iterator(dataset))
  2. 誤差を計算する(model loss)
  3. 最適化関数で最小化する(optimizer.minimize)

定義したモデルはmodel()で実行できます。

def train_one_epoch(model, optimizer, dataset, log_interval=None):
  """Trains model on `dataset` using `optimizer`."""

  tf.train.get_or_create_global_step()

  def model_loss(labels, images):
    prediction = model(images, training=True)
    loss_value = loss(prediction, labels)
    tf.contrib.summary.scalar('loss', loss_value)
    tf.contrib.summary.scalar('accuracy',
                              compute_accuracy(prediction, labels))
    return loss_value

  for (batch, (images, labels)) in enumerate(tfe.Iterator(dataset)):
    with tf.contrib.summary.record_summaries_every_n_global_steps(10):
      batch_model_loss = functools.partial(model_loss, labels, images)
      optimizer.minimize(
          batch_model_loss, global_step=tf.train.get_global_step())
      if log_interval and batch % log_interval == 0:
        print('Batch #%d\tLoss: %.6f' % (batch, batch_model_loss()))

判定

判定部は次のとおりです。モデルを使って出力し、誤差を計算しているなど
学習時に見られるコードのため、目立って新しい箇所はないかと思います。

def test(model, dataset):
  """Perform an evaluation of `model` on the examples from `dataset`."""
  avg_loss = tfe.metrics.Mean('loss')
  accuracy = tfe.metrics.Accuracy('accuracy')

  for (images, labels) in tfe.Iterator(dataset):
    predictions = model(images, training=False)
    avg_loss(loss(predictions, labels))
    accuracy(tf.argmax(predictions, axis=1, output_type=tf.int64),
             tf.argmax(labels, axis=1, output_type=tf.int64))
  print('Test set: Average loss: %.4f, Accuracy: %4f%%\n' %
        (avg_loss.result(), 100 * accuracy.result()))
  with tf.contrib.summary.always_record_summaries():
    tf.contrib.summary.scalar('loss', avg_loss.result())
    tf.contrib.summary.scalar('accuracy', accuracy.result())

標準出力

MNISTのサンプルを動作させると次の出力になります。

$ python mnist.py
/Users/Tereka/anaconda3/lib/python3.6/importlib/_bootstrap.py:205: RuntimeWarning: compiletime version 3.5 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.6
  return f(*args, **kwds)
2017-11-05 23:14:38.631714: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.2 AVX AVX2 FMA
Using device /cpu:0, and data format channels_last.
Extracting /tmp/tensorflow/mnist/input_data/train-images-idx3-ubyte.gz
Extracting /tmp/tensorflow/mnist/input_data/train-labels-idx1-ubyte.gz
Extracting /tmp/tensorflow/mnist/input_data/t10k-images-idx3-ubyte.gz
Extracting /tmp/tensorflow/mnist/input_data/t10k-labels-idx1-ubyte.gz
Batch #0	Loss: 2.295565
Batch #10	Loss: 2.279653
Batch #20	Loss: 2.263355
Batch #30	Loss: 2.227737
Batch #40	Loss: 2.176997
Batch #50	Loss: 2.159155
Batch #60	Loss: 1.995388
Batch #70	Loss: 1.832986
Batch #80	Loss: 1.613709
Batch #90	Loss: 1.197411

仮にTypeErrorが発生した場合は、該当する引数を消してください。私の場合、次の箇所で発生しました。

TypeError: create_summary_file_writer() got an unexpected keyword argument 'flush_secs'

最後に

MNISTの公式サンプルをご紹介しました。
RNNを書く時に非常に使いやすくなりそうです。また、フレームワーク戦争が熾烈になりそう。

ZabbixでGPUを監視する

皆さんこんにちは
お元気ですか。私はISUCONで負けました。

前回はCPUの温度監視をしました。だが、まだ情報が足りません。

そう、GPUの監視情報です。一般的にはnvidia-smiから情報を取得できますが
これをZabbixで見たいと思います。

同じようなことを考える人は古今東西にいるもので、
Zabbix Agentの設定、テンプレートまで公開されています。それに沿って可視化しましょう。

github.com

Zabbix Agentの設定

Zabbix AgentにUserParameterを設定します。
このパラメータを設定することでZabbixAgentに新しくメトリックを追加できます。

今回のテンプレートでは、次の内容を追加します。

UserParameter=gpu.temp,nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits -i 0
UserParameter=gpu.memtotal,nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits -i 0
UserParameter=gpu.used,nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits -i 0
UserParameter=gpu.free,nvidia-smi --query-gpu=memory.free --format=csv,noheader,nounits -i 0
UserParameter=gpu.fanspeed,nvidia-smi --query-gpu=fan.speed --format=csv,noheader,nounits -i 0
UserParameter=gpu.utilisation,nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits -i 0
UserParameter=gpu.power,nvidia-smi --query-gpu=power.draw --format=csv,noheader,nounits -i 0

テンプレートの設定

さて、githubにテンプレート(nvidia_smi_template.xml)があります。
このテンプレートをZabbixに読み込ませます。

f:id:tereka:20171015014349p:plain

そして、Hostsから対象のサーバにテンプレートを適用します。

f:id:tereka:20171015014451p:plain

さて、この状態でグラフを見ます。4種類のグラフが増えています。

  1. GPU Tempareture・・・GPUの温度の確認ができる
  2. GPU Power・・・GPUの消費電力の確認ができる
  3. GPU Memory・・・GPUメモリの状態の確認ができる
  4. GPU Utilisation・・・GPUの利用率を確認できる

試しにこのグラフを表示します。一応全てのキャプチャを撮影しました。

GPU Tempareture
f:id:tereka:20171015015217p:plain

GPU Power
f:id:tereka:20171015015243p:plain

GPU Memory
f:id:tereka:20171015015233p:plain

GPU Utilisation
f:id:tereka:20171015014738p:plain

それぞれ監視ができています。この状態で、異常が起こった場合の状態を確認できます。

最後に

簡単にGPUの状態を監視できました。
とりあえず、これを眺めて楽しみます。
※様々なことを行って調べたところ私のマシントラブルはマザーボードが原因だったようです。

ZabbixでサーバマシンのCPU温度を監視する

皆さんこんにちは。
お元気ですか。旧友に最近太ったといわれて少々、落ち込んでます。
ちょっと食べる量減ったんですよね。ここ数年。

負荷がかかるとリモートPCの調子が時々悪くなると言った事象が発生し、
勝手に落ちるするといった状況なのでちょっと対策を打ちたいなぁと思っていました。

CPU温度が怪しいと思っていましたが、自分の目でsensorsを監視し続けるのは大変でした。
また、非常にエンジニア的ではなく気に入らないので別の手段(自動化など)を考えていました。
調べると、Zabbixだと収集が簡単そうにできるので、勉強がてらやってみました。

Zabbix

Zabbixとは

多数のネットワークやサーバを監視するためのソフトウェアです。
CPU, メモリなどのメトリックの収集や監視、条件による通知を行うことができます。
オープンソースでも使えるそうで、これでZabbixで温度監視ができるようです。

www.zabbix.com

Zabbixのインストール

まずは、必要な媒体をインストールします。(この方法はUbuntu/Debian用です)

wget http://repo.zabbix.com/zabbix/3.2/ubuntu/pool/main/z/zabbix-release/zabbix-release_3.2-1+xenial_all.deb
sudo dpkg -i zabbix-release_3.2-1+xenial_all.deb
sudo apt-get update
apt-get install zabbix-server-pgsql zabbix-frontend-php
sudo apt-get install zabbix-agent

普段使っているデータベースがpostgresqlなので、postgresql用の設定を行います。
まずは、Zabbix用のデータベースを作成します。

psql -U postgres
create database zabbix; 

次にZabbixを使うにあたり、必要なデータベース設定を行います。

sudo zcat /usr/share/doc/zabbix-server-pgsql/create.sql.gz | sudo psql -U postgres zabbix

そして、Zabbixのデータベースの設定を行います。
/etc/zabbix/zabbix_server.confに次の内容を記載します。
内容は設定環境に応じて、変更をしてください。

DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword=<PASSWORD>

そして、Zabbix Serverを起動します。

service zabbix-server start
update-rc.d zabbix-server enable

実はここまででZabbix動くと思えば、どうやら、Time/Zoneの設定が必要なようです。
この項目でGUI PreferenceのチェックでNGが出ました。
/etc/zabbix/apache.confのphp部分でコメントアウトになっている設定を外して、
Time/Zoneを適切に設定します。(日本であればAsia/Tokyo)

<Directory "/usr/share/zabbix">
    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all

    <IfModule mod_php5.c>
        php_value max_execution_time 300
        php_value memory_limit 128M
        php_value post_max_size 16M
        php_value upload_max_filesize 2M
        php_value max_input_time 300
        php_value always_populate_raw_post_data -1
        php_value date.timezone Asia/Tokyo
    </IfModule>
    <IfModule mod_php7.c>
        php_value max_execution_time 300
        php_value memory_limit 128M
        php_value post_max_size 16M
        php_value upload_max_filesize 2M
        php_value max_input_time 300
        php_value always_populate_raw_post_data -1
        php_value date.timezone Asia/Tokyo
    </IfModule>
</Directory>

最後にサーバに設定を反映させます。

sudo service apache2 restart

GUI設定

まずは、Zabbixの設定をGUIで行います。
http://<サーバのIP>/zabbix/setup.php

f:id:tereka:20171014233141p:plain

DBの設定を記述します。今回はpostgreSQLを選択し、設定を記載します。

f:id:tereka:20171014233124p:plain

これでダッシュボードにアクセスすることができます。
※ログインですがIDはAdmin, passwordはzabbixです。

f:id:tereka:20171015002345p:plain

試しにCPUを可視化するとこんな感じです。

f:id:tereka:20171014234017p:plain

CPUの温度監視

さて、ここからが本題です。CPUの温度を監視します。
手順は次のとおりです

  1. バイスの特定
  2. アイテムの登録
  3. グラフの作成

バイスの特定

sensorsコマンドを使ってデバイス名とコアを特定する必要があります。
sensors -u を実行しましょう。

$ sensors -u
acpitz-virtual-0
Adapter: Virtual device
temp1:
  temp1_input: 27.800
  temp1_crit: 105.000
temp2:
  temp2_input: 29.800
  temp2_crit: 105.000

coretemp-isa-0000
Adapter: ISA adapter
Physical id 0:
  temp1_input: 60.000
  temp1_max: 80.000
  temp1_crit: 100.000
  temp1_crit_alarm: 0.000
Core 0:
  temp2_input: 51.000
  temp2_max: 80.000
  temp2_crit: 100.000
  temp2_crit_alarm: 0.000
Core 1:
  temp3_input: 50.000
  temp3_max: 80.000
  temp3_crit: 100.000
  temp3_crit_alarm: 0.000
Core 2:
  temp4_input: 54.000
  temp4_max: 80.000
  temp4_crit: 100.000
  temp4_crit_alarm: 0.000
Core 3:
  temp5_input: 60.000
  temp5_max: 80.000
  temp5_crit: 100.000
  temp5_crit_alarm: 0.000

asus-isa-0000
Adapter: ISA adapter
cpu_fan:
  fan1_input: 0.000

この長い出力の中からデバイス名coretemp-isa-0000と
対応する温度temp2~temp5をどこかに記録します。Zabbixの設定で使います。

アイテムの登録

そしてZabbixのアイテムを登録しましょう。
Zabbixのアイテムには先程記録したデバイス名と対応する温度を使います。
温度計測対象分、この登録を繰り返します。

Configuration→Hosts→サーバ名を選択→Itemsで開けます。

f:id:tereka:20171015000640p:plain

グラフの作成

最後にグラフを作成します。
先程、登録したアイテムを使用してグラフを作成します。

f:id:tereka:20171015232812p:plain

f:id:tereka:20171015000617p:plain

そして暫く放置すると遂に、CPUの温度をグラフに表示できました。
これで常にアクセスし続けていれば、監視がスムーズにできます。

f:id:tereka:20171015001643p:plain

最後に

CPU監視をとても楽にできました。意外に使い心地が良いですね。
この情報に加えて、もう少し別のデータも監視したいので調べています。

CatBoostを5分程度で動かしてみた

皆さんこんにちは
お元気ですか?私は年末の師走フラグが立っています。

少し前(この界隈ではだいぶ前っぽい)にYandex社からCatBoostが発表されました。
これが発表されたことは知っていたのですが、時間が取れなくて利用してなかったソフトウェアの1つです。

CatBoost

CatBoostはYandex社が開発した勾配ブースティングをベースとした機械学習のライブラリです。
catboost.yandex

公式サイトには次の特徴が記載されています。

  1. 過学習を減らす。・・・独自のアルゴリズムによって実現した。
  2. カテゴリ特徴量の対応・・・前処理を行わなくてもカテゴリ特徴量に対応をしている。
  3. ユーザフレンドリなAPI・・・コマンドラインツールもしくは、Python,RのAPIをサポートしている。

公式ページ記載のベンチマークは他のLight GBMやxgboostよりも
よく見え、かつ新しい標準的な手法であることを主張しているのでぜひ使ってみたい所です。

※ICML2017で、少し資料があがっているようです。
https://indico.cern.ch/event/617754/contributions/2590694/attachments/1459648/2254154/catboost_for_CMS.pdf

実際に使ってみる。

インストール

まずは、インストールですが簡単にできます。
(あれ・・難しくなかった・・・)

pip install catboost

実行する

まずは、インストールできていることを確認しましょう。
試しにインストールしたライブラリをインポートしてみます。

from catboost import CatBoostRegressor

エラーが出ず、実行が完了すればインストールは成功しているはずです。

簡単な実行サンプルの紹介

CatBoostには大きく分けて2つのクラスがあります。

1つ目がCatBoostRegressorで回帰問題を解くクラス、
2つ目はCatBoostClassifierで分類問題を解くクラスになります。

解く問題によって、必要なクラスを選択することになるでしょう。

回帰問題

import numpy
from catboost import CatBoostRegressor
# 学習データ
dataset = numpy.array([[1,4,5,6],[4,5,6,7],[30,40,50,60],[20,15,85,60]])
train_labels = [1.2,3.4,9.5,24.5]
model = CatBoostRegressor(learning_rate=1, depth=6, loss_function='RMSE')
fit_model = model.fit(dataset, train_labels)

model.predict(dataset)

分類問題

from catboost import CatBoostClassifier
cat_features = [0,1,2]
train_data = [["a","b",1,4,5,6],["a","b",4,5,6,7],["c","d",30,40,50,60]]
train_labels = [1,1,-1]
test_data = [["a","b",2,4,6,8],["a","d",1,4,50,60]]
# CatBoostClassifierの初期化
model = CatBoostClassifier(iterations=2, learning_rate=1, depth=2, loss_function='Logloss')
# モデルの学習
model.fit(train_data, train_labels, cat_features)
# クラス予測
preds_class = model.predict(test_data)
# 各クラスの確率を予測
preds_proba = model.predict_proba(test_data)
# 変換していない出力数値
preds_raw = model.predict(test_data, prediction_type='RawFormulaVal')

比較的どちらもscikit-learnのインターフェースに酷似しています。
ただ、他のライブラリと異なる特徴的な部分があります。
それは、fit関数のインターフェースのcat_features変数です。

cat_featuresはカテゴリカル変数のインデックスのリストになります。
この指定をすると、カテゴリカル変数的な処理が実行されます。

見た方が良さそうなページ

最後にその他、見た方が良さそうなページを紹介します。

Usage examples

Binary Classification, Multiclassification, Regressionの簡単なサンプルや
その他実装上で利用できるコードが掲載されています。

基本的な実装はこのページを確認すれば、参考にできると思います。

tech.yandex.com

Training parameters

無数にある学習パラメータの一覧が掲載されています。
最初軽く説明しようと思ったら案外、膨大でした。
これを見ながら後に勉強しようと思います。

tech.yandex.com

最後に

今回、CatBoostを試しに動かしてみました。
実際に動かしたばかりでどの程度の精度が出るか、使いやすいかまでは至れていませんが
コンペで試運転をはじめてみようと思います。

Pandasで特徴量取得する場合に使う操作をまとめてみた

皆さんこんにちは
お元気ですか。私は元気です。

分析は基本的にPythonを使って行います。(大体Pandasですが・・・)
Pandasを利用すると色々できます。が、ふとどうするんだっけ処理が増えていきました。

自分のメモがてらカテゴリを分けて記録に残したいと思います。
最後のほうは特徴量の作り方集になっています。

Kaggleで実際に使ったことがある処理も数多く掲載しました。
思いついたら随時、追加しようと思います。

準備

本コードは事前に「import pandas as pd」を利用しています。
ファイルの操作、結合などを行うファイルを準備します。
ファイルの内容は次の通りです。

■df_example1.csv

名前 性別 年齢
太郎 21
二郎 30
三郎 21
四郎
花子 14

■df_example2.csv

名前 部活動
太郎 陸上
二郎 野球
四郎 野球
花子 華道

■df_example3.csv

名前 性別 年齢
五郎 22
六郎 21
七郎 21
八郎 3
九子 14

■df_example4.csv

趣味 授業
データ分析 地理
ゲーム 世界史
ゲーム 理科
読書 国語
Neural Network 数学

ファイル操作

読み込み

df1 = pd.read_csv("df_example1.csv")
df2 = pd.read_csv("df_example2.csv")
df3 = pd.read_csv("df_example3.csv")
df4 = pd.read_csv("df_example4.csv")
df = pd.read_csv("temp.tsv", separete="\t") # TSVファイル
df = pd.read_excel("temp.xlsx") # Excelファイル

書き込み

df1.to_csv("temp_w.csv",index=False) # IndexがTrueの場合はIndexも出力される。大体は不要

テーブル操作

1行ごとに処理をする。

for index, row in df1.iterrows():
     print (index, row)

複数列を取得する。

print (df1[["名前", "年齢"]])

#   名前  年齢
#0  太郎  21
#1  二郎  30
#2  三郎  21
#3  四郎  NAN
#4  花子  14

選択操作

テーブル条件の指定
print (df1[df1["性別"] == "男"])
#   名前 性別    年齢
#0  太郎  男  21.0
#1  二郎  男  30.0
#2  三郎  男  21.0
#3  四郎  男   NaN
複数条件の指定

&で結合すれば、複数の条件を選択できる。(|を指定すればOR)

print (df1[(df1["性別"] == "男") & (df1["年齢"] > 25)])

#    名前 性別    年齢
# 1  二郎  男  30.0

NaNを埋める。

NaNになる値を埋めたいケースがあります。

print (df1.fillna(-1))
#   名前 性別    年齢
#0  太郎  男  21.0
#1  二郎  男  30.0
#2  三郎  男  21.0
#3  四郎  男  -1.0
#4  花子  女  14.0

カラム、テーブルの統計情報を取得する。

df1["年齢"].mean() # 出力は省略
df1["年齢"].median() # 出力は省略
df1["年齢"].max() # 出力は省略
df1["年齢"].min() # 出力は省略
df1.describe()

#              年齢
#count   4.000000
#mean   21.500000
#std     6.557439
#min    14.000000
#25%          NaN
#50%          NaN
#75%          NaN
#max    30.000000
完全一致の列を発見し、除去する。

重複している列を発見します。重複しているカラムは必要がないことから
重複を調べ除去したいことがあります。
この除去には、pandasのdrop_duplicateを使います。

df.T.drop_duplicates().T

日付操作

日付から日などの情報を取得する。

特徴量を生成する際に日付から曜日などの特徴を取得したいケースがあります。
その日付から新しい特徴量を作成できます。

date = pd.date_range('2017-01-01 00:00', periods=1, freq='D')[0]
print (date) # 2017-01-01 00:00:00
print (date.dayofweek) # 6
print (date.month, date.day, date.hour, date.minute) # 1 1 0 0

2つ以上のDataFrameの結合操作

内部結合

2つ以上のテーブルを結合する。RDBのjoinと同じ操作です。

print (pd.merge(df1, df2, how="inner", on="名前"))   

#    名前 性別_x    年齢 性別_y 部活動
# 0  太郎    男  21.0    男  陸上
# 1  二郎    男  30.0    男  野球
# 2  四郎    男   NaN    男  野球
# 3  花子    女  14.0    女  華道

外部結合

print (pd.merge(df1, df2, how="outer", on="名前"))  
#   名前 性別    年齢  部活動
#0  太郎  男  21.0   陸上
#1  二郎  男  30.0   野球
#2  三郎  男  21.0  NaN
#3  四郎  男   NaN   野球
#4  花子  女  14.0   華道

2つの結合処理

Onを利用した結合をしない処理はpd.concatで可能です。

pd.concat([df3, df4], axis=0) #縦方向の結合

#   名前 性別    年齢
#0  太郎  男  21.0
#1  二郎  男  30.0
#2  三郎  男  21.0
#3  四郎  男   NaN
#4  花子  女  14.0
#0  五郎  男  22.0
#1  六郎  男  21.0
#2  七郎  男  21.0
#3  八郎  男   3.0
#4  九子  女  14.0

pd.concat([df3, df4], axis=1) #横方向の結合

#   名前 性別    年齢              趣味   授業
#0  太郎  男  21.0           データ分析   地理
#1  二郎  男  30.0             ゲーム  世界史
#2  三郎  男  21.0             ゲーム   理科
#3  四郎  男   NaN              読書   国語
#4  花子  女  14.0  Neural Network   数学

集計操作を使った特徴量作成

結合したデータを使って、Group Byを利用して集計します。
例えば、2つ以上のカラムを利用して集計する場合に使います。

2つのカラムを組み合わせて統計を取り、特徴量にする場合

2つのカラムを組み合わせて統計を取り、それを特徴量にしたい場合があります。
その場合はgroupby reset_index, mergeを使います。

merged_df = pd.merge(df1, df2, how="outer", on="名前")      
mean = merged_df.groupby(["性別"]).mean()                                               
reset_mean = mean.reset_index()                                                                   
print(merged_df.merge(reset_mean, how="left", on="性別"))   

#   名前 性別  年齢_x  部活動  年齢_y
#0  太郎  男  21.0   陸上  24.0
#1  二郎  男  30.0   野球  24.0
#2  三郎  男  21.0  NaN  24.0
#3  四郎  男   NaN   野球  24.0
#4  花子  女  14.0   華道  14.0

変数の変換を行う。

カテゴリカルな変数

ダミー変数に変換し、結果を結合する。
dummies_df = pd.get_dummies(df1["性別"))
pd.concat([df1, dummies_df], axis=1)

#   名前 性別    年齢    女    男
#0  太郎  男  21.0  0.0  1.0
#1  二郎  男  30.0  0.0  1.0
#2  三郎  男  21.0  0.0  1.0
#3  四郎  男   NaN  0.0  1.0
#4  花子  女  14.0  1.0  0.0
ラベル変数にし、結果を取得する。
from sklearn.preprocessing import LabelEncoder
df1["性別"] = LabelEncoder().fit_transform(df1["性別"])

#   名前  性別    年齢
#0  太郎   1  21.0
#1  二郎   1  30.0
#2  三郎   1  21.0
#3  四郎   1   NaN
#4  花子   0  14.0

Numpyへの変換を行う。

私は以下の2つのどちらかで変換を行います。大体np.arrayで実行しています。

df1.as_matrix()
np.array(df1)

最後に

pandas長く使っていたので纏めてみると結構多くてびっくりです。
特徴量作成にまだまだ使えるので、ぜひ使ってみてください。