12月 21, 2025
32 分で読める

ジュニアデータサイエンティスト面接質問:Python・SQL・統計・ML

interview
career-advice
job-search
entry-level
ジュニアデータサイエンティスト面接質問:Python・SQL・統計・ML
Milad Bonakdar

Milad Bonakdar

著者

Python、pandas、SQL、統計、機械学習の基礎、プロジェクト説明を中心に、ジュニアデータサイエンティスト面接の準備を進めましょう。


はじめに

ジュニアデータサイエンティストの面接では、データをきれいに整えられるか、基本的な Python と SQL を書けるか、統計をわかりやすく説明できるか、簡単な機械学習の問題を筋道立てて考えられるかがよく見られます。強い回答は短く、実務的で、自分のプロジェクトや授業、インターン経験に結び付いています。

このガイドでは、最初に確認されやすい領域を練習できます。Python の基礎、pandas によるデータ操作、SQL 的な考え方、確率と統計、モデル評価、そして経験を大きく見せすぎずに判断理由を説明する方法です。


Pythonの基礎 (5つの質問)

1. Pythonのリストとタプルの違いは何ですか?

回答:

  • リスト: 可変(変更可能)、角括弧[]で定義
  • タプル: 不変(変更不可能)、丸括弧()で定義
  • パフォーマンス: タプルの方がわずかに高速で、使用するメモリが少ない
  • ユースケース:
    • リスト: データを変更する必要がある場合
    • タプル: 固定コレクション、辞書のキー、関数の戻り値
# リスト - 可変
my_list = [1, 2, 3]
my_list[0] = 10  # 動作
my_list.append(4)  # 動作
print(my_list)  # [10, 2, 3, 4]

# タプル - 不変
my_tuple = (1, 2, 3)
# my_tuple[0] = 10  # エラー: タプルは不変
# my_tuple.append(4)  # エラー: appendメソッドがない

# タプルのアンパック
x, y, z = (1, 2, 3)
print(x, y, z)  # 1 2 3

希少度: 非常に一般的 難易度: 簡単


2. リスト内包表記について説明し、例を挙げてください。

回答: リスト内包表記は、既存のイテラブルに基づいてリストを作成するための簡潔な方法を提供します。

  • 構文: [expression for item in iterable if condition]
  • 利点: より読みやすく、ループよりも高速であることが多い
# 従来のループ
squares = []
for i in range(10):
    squares.append(i ** 2)

# リスト内包表記
squares = [i ** 2 for i in range(10)]
print(squares)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 条件付き
even_squares = [i ** 2 for i in range(10) if i % 2 == 0]
print(even_squares)  # [0, 4, 16, 36, 64]

# ネストされた内包表記
matrix = [[i * j for j in range(3)] for i in range(3)]
print(matrix)  # [[0, 0, 0], [0, 1, 2], [0, 2, 4]]

# 辞書内包表記
squares_dict = {i: i ** 2 for i in range(5)}
print(squares_dict)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

希少度: 非常に一般的 難易度: 簡単


3. ラムダ関数とは何ですか?また、いつ使用しますか?

回答: ラムダ関数は、名前のない、単一の式の関数です。

  • 構文: lambda arguments: expression
  • ユースケース: 短い関数、コールバック、ソート、フィルタリング
# 通常の関数
def square(x):
    return x ** 2

# ラムダ関数
square_lambda = lambda x: x ** 2
print(square_lambda(5))  # 25

# mapと組み合わせる
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # [1, 4, 9, 16, 25]

# filterと組み合わせる
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4]

# キーによるソート
students = [('Alice', 85), ('Bob', 92), ('Charlie', 78)]
sorted_students = sorted(students, key=lambda x: x[1], reverse=True)
print(sorted_students)  # [('Bob', 92), ('Alice', 85), ('Charlie', 78)]

希少度: 非常に一般的 難易度: 簡単


4. リストのappend()extend()の違いについて説明してください。

回答:

  • append(): リストの末尾に単一の要素を追加します
  • extend(): イテラブルから複数の要素を末尾に追加します
# append - 単一の要素を追加
list1 = [1, 2, 3]
list1.append(4)
print(list1)  # [1, 2, 3, 4]

list1.append([5, 6])
print(list1)  # [1, 2, 3, 4, [5, 6]] - リストを単一の要素として追加

# extend - 複数の要素を追加
list2 = [1, 2, 3]
list2.extend([4, 5, 6])
print(list2)  # [1, 2, 3, 4, 5, 6]

# extendの代替
list3 = [1, 2, 3]
list3 += [4, 5, 6]
print(list3)  # [1, 2, 3, 4, 5, 6]

希少度: 一般的 難易度: 簡単


5. *args**kwargsとは何ですか?

回答: これらを使用すると、関数は可変の数の引数を受け入れることができます。

  • *args: 可変の数の位置引数 (タプル)
  • **kwargs: 可変の数のキーワード引数 (辞書)
# *args - 位置引数
def sum_all(*args):
    return sum(args)

print(sum_all(1, 2, 3))  # 6
print(sum_all(1, 2, 3, 4, 5))  # 15

# **kwargs - キーワード引数
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=25, city="NYC")
# name: Alice
# age: 25
# city: NYC

# 組み合わせ
def flexible_function(*args, **kwargs):
    print("Positional:", args)
    print("Keyword:", kwargs)

flexible_function(1, 2, 3, name="Alice", age=25)
# Positional: (1, 2, 3)
# Keyword: {'name': 'Alice', 'age': 25}

希少度: 一般的 難易度: 普通


統計と確率 (5つの質問)

6. 平均、中央値、最頻値の違いは何ですか?

回答:

  • 平均: すべての値の平均 (合計 / カウント)
  • 中央値: ソートされたときの中間の値
  • 最頻値: 最も頻繁に出現する値
  • いつ使うか:
    • 平均: 正規分布データ
    • 中央値: 歪んだデータまたは外れ値が存在する場合
    • 最頻値: カテゴリカルデータ
import numpy as np
from scipy import stats

data = [1, 2, 2, 3, 4, 5, 100]

# 平均 - 外れ値の影響を受ける
mean = np.mean(data)
print(f"Mean: {mean}")  # 16.71

# 中央値 - 外れ値に強い
median = np.median(data)
print(f"Median: {median}")  # 3

# 最頻値
mode = stats.mode(data, keepdims=True)
print(f"Mode: {mode.mode[0]}")  # 2

希少度: 非常に一般的 難易度: 簡単


7. 分散と標準偏差について説明してください。

回答:

  • 分散: 平均からの二乗偏差の平均
  • 標準偏差: 分散の平方根 (データと同じ単位)
  • 目的: データの広がり/ばらつきを測定する
import numpy as np

data = [2, 4, 4, 4, 5, 5, 7, 9]

# 分散
variance = np.var(data, ddof=1)  # ddof=1はサンプル分散用
print(f"Variance: {variance}")  # 4.57

# 標準偏差
std_dev = np.std(data, ddof=1)
print(f"Std Dev: {std_dev}")  # 2.14

# 手動計算
mean = np.mean(data)
variance_manual = sum((x - mean) ** 2 for x in data) / (len(data) - 1)
print(f"Manual Variance: {variance_manual}")

希少度: 非常に一般的 難易度: 簡単


8. p値とは何ですか?また、どのように解釈しますか?

回答: p値は、帰無仮説が真であると仮定した場合に、観察されたものと同程度に極端な結果が得られる確率です。

  • 解釈:
    • p < 0.05: 帰無仮説を棄却 (統計的に有意)
    • p ≥ 0.05: 帰無仮説の棄却に失敗
  • 注意: p値は効果の大きさや重要性を測定しません
from scipy.stats import binomtest

# 例: コインが公平かどうかをテストする
# 帰無仮説: コインは公平 (p = 0.5)
# 100回のフリップで65回の表が出た

observed_heads = 65
n_flips = 100
expected_proportion = 0.5

# 二項検定
result = binomtest(observed_heads, n_flips, expected_proportion)
p_value = result.pvalue
print(f"P-value: {p_value}")  # 0.0018

if p_value < 0.05:
    print("帰無仮説を棄却 - コインは偏っている可能性が高い")
else:
    print("帰無仮説の棄却に失敗 - コインは公平に見える")

希少度: 非常に一般的 難易度: 普通


9. 中心極限定理とは何ですか?

回答: 中心極限定理は、サンプル平均のサンプリング分布は、母集団の分布に関係なく、サンプルサイズが増加するにつれて正規分布に近づくと述べています。

  • 重要なポイント:
    • 任意の分布に対して機能します (サンプルサイズが十分に大きい場合)
    • n が 30 前後という目安は便利ですが保証ではありません。歪みが強いデータや裾の重いデータでは、より多くのサンプルが必要になることがあります
    • 仮説検定と信頼区間を可能にします
import numpy as np
import matplotlib.pyplot as plt

# 非正規分布の母集団 (指数分布)
population = np.random.exponential(scale=2, size=10000)

# 多くのサンプルを取得し、それらの平均を計算する
sample_means = []
for _ in range(1000):
    sample = np.random.choice(population, size=30)
    sample_means.append(np.mean(sample))

# サンプル平均は正規分布している (CLT)
print(f"Population mean: {np.mean(population):.2f}")
print(f"Mean of sample means: {np.mean(sample_means):.2f}")
print(f"Std of sample means: {np.std(sample_means):.2f}")

希少度: 一般的 難易度: 普通


10. 相関と因果関係とは何ですか?

回答:

  • 相関: 2つの変数間の統計的関係
  • 因果関係: ある変数が別の変数の変化を直接引き起こす
  • 重要なポイント: 相関は因果関係を意味しません
  • 理由:
    • 交絡変数
    • 逆因果関係
    • 偶然
import numpy as np
import pandas as pd

# 例: アイスクリームの売上と溺死者数は相関している
# しかし、アイスクリームは溺死の原因ではない (交絡変数: 気温)

# 相関係数
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 5, 4, 5])

correlation = np.corrcoef(x, y)[0, 1]
print(f"Correlation: {correlation:.2f}")  # 0.82

# ピアソンの相関
from scipy.stats import pearsonr
corr, p_value = pearsonr(x, y)
print(f"Pearson r: {corr:.2f}, p-value: {p_value:.3f}")

希少度: 非常に一般的 難易度: 簡単


Pandasを使用したデータ操作 (5つの質問)

11. CSVファイルを読み込み、基本的な情報を表示するにはどうすればよいですか?

回答: pandasを使用してデータを読み取り、探索します。

import pandas as pd

# CSVを読み込む
df = pd.read_csv('data.csv')

# 基本情報
print(df.head())  # 最初の5行
print(df.tail())  # 最後の5行
print(df.shape)   # (行数, 列数)
print(df.info())  # データ型と非nullの数
print(df.describe())  # 統計概要

# 列名と型
print(df.columns)
print(df.dtypes)

# 欠損値の確認
print(df.isnull().sum())

# 特定の列
print(df[['column1', 'column2']].head())

希少度: 非常に一般的 難易度: 簡単


12. DataFrameの欠損値をどのように処理しますか?

回答: 欠損データを処理するための複数の戦略:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, np.nan, 8],
    'C': [9, 10, 11, 12]
})

# 欠損値の確認
print(df.isnull().sum())

# 欠損値を含む行を削除
df_dropped = df.dropna()

# 欠損値を含む列を削除
df_dropped_cols = df.dropna(axis=1)

# 特定の値で埋める
df_filled = df.fillna(0)

# 平均値で埋める
df['A'] = df['A'].fillna(df['A'].mean())

# 中央値で埋める
df['B'] = df['B'].fillna(df['B'].median())

# 前方補完 (前の値を使用)
df_ffill = df.ffill()

# 後方補完 (次の値を使用)
df_bfill = df.bfill()

# 補間
df_interpolated = df.interpolate()

希少度: 非常に一般的 難易度: 簡単


13. pandasでデータをフィルタリングおよび選択するにはどうすればよいですか?

回答: データをフィルタリングおよび選択するための複数の方法:

import pandas as pd

df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'David'],
    'age': [25, 30, 35, 28],
    'salary': [50000, 60000, 75000, 55000],
    'department': ['IT', 'HR', 'IT', 'Finance']
})

# 列を選択
print(df['name'])  # 単一の列 (Series)
print(df[['name', 'age']])  # 複数の列 (DataFrame)

# 行をフィルタリング
high_salary = df[df['salary'] > 55000]
print(high_salary)

# 複数の条件
it_high_salary = df[(df['department'] == 'IT') & (df['salary'] > 50000)]
print(it_high_salary)

# .locを使用 (ラベルベース)
print(df.loc[0:2, ['name', 'age']])

# .ilocを使用 (位置ベース)
print(df.iloc[0:2, 0:2])

# queryメソッド
result = df.query('age > 28 and salary > 55000')
print(result)

# isinメソッド
it_or_hr = df[df['department'].isin(['IT', 'HR'])]
print(it_or_hr)

希少度: 非常に一般的 難易度: 簡単


14. データをグループ化して集計するにはどうすればよいですか?

回答: 集計操作にはgroupby()を使用します:

import pandas as pd

df = pd.DataFrame({
    'department': ['IT', 'HR', 'IT', 'Finance', 'HR', 'IT'],
    'employee': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank'],
    'salary': [50000, 45000, 60000, 55000, 48000, 65000],
    'age': [25, 30, 35, 28, 32, 40]
})

# 単一の列でグループ化
dept_avg_salary = df.groupby('department')['salary'].mean()
print(dept_avg_salary)

# 複数の集計
dept_stats = df.groupby('department').agg({
    'salary': ['mean', 'min', 'max'],
    'age': 'mean'
})
print(dept_stats)

# カスタム集計
dept_custom = df.groupby('department').agg({
    'salary': lambda x: x.max() - x.min(),
    'employee': 'count'
})
print(dept_custom)

# 複数のグループ化列
result = df.groupby(['department', 'age'])['salary'].sum()
print(result)

希少度: 非常に一般的 難易度: 普通


15. DataFrameをマージまたは結合するにはどうすればよいですか?

回答: merge()join()、またはconcat()を使用します:

import pandas as pd

# サンプルDataFrame
df1 = pd.DataFrame({
    'employee_id': [1, 2, 3, 4],
    'name': ['Alice', 'Bob', 'Charlie', 'David']
})

df2 = pd.DataFrame({
    'employee_id': [1, 2, 3, 5],
    'salary': [50000, 60000, 75000, 55000]
})

# 内部結合 (一致する行のみ)
inner = pd.merge(df1, df2, on='employee_id', how='inner')
print(inner)

# 左結合 (左側のすべての行)
left = pd.merge(df1, df2, on='employee_id', how='left')
print(left)

# 右結合 (右側のすべての行)
right = pd.merge(df1, df2, on='employee_id', how='right')
print(right)

# 外部結合 (両方のすべての行)
outer = pd.merge(df1, df2, on='employee_id', how='outer')
print(outer)

# 垂直方向に連結
df3 = pd.concat([df1, df2], ignore_index=True)
print(df3)

# 水平方向に連結
df4 = pd.concat([df1, df2], axis=1)
print(df4)

希少度: 非常に一般的 難易度: 普通


機械学習の基礎 (5つの質問)

16. 教師あり学習と教師なし学習の違いは何ですか?

回答:

  • 教師あり学習:
    • ラベル付きのトレーニングデータがある (入力-出力ペア)
    • 目標: 入力から出力へのマッピングを学習する
    • 例: 分類、回帰
    • アルゴリズム: 線形回帰、決定木、SVM
  • 教師なし学習:
    • ラベル付きデータがない (入力のみ)
    • 目標: データ内のパターンまたは構造を見つける
    • 例: クラスタリング、次元削減
    • アルゴリズム: K-Means、PCA、階層型クラスタリング
from sklearn.linear_model import LinearRegression
from sklearn.cluster import KMeans
import numpy as np

# 教師あり学習 - 線形回帰
X_train = np.array([[1], [2], [3], [4], [5]])
y_train = np.array([2, 4, 6, 8, 10])

model = LinearRegression()
model.fit(X_train, y_train)
prediction = model.predict([[6]])
print(f"Supervised prediction: {prediction[0]}")  # 12

# 教師なし学習 - K-Meansクラスタリング
X = np.array([[1, 2], [1.5, 1.8], [5, 8], [8, 8], [1, 0.6], [9, 11]])

kmeans = KMeans(n_clusters=2, random_state=42)
clusters = kmeans.fit_predict(X)
print(f"Cluster assignments: {clusters}")

希少度: 非常に一般的 難易度: 簡単


17. 過学習とは何ですか?また、どのように防止しますか?

回答: 過学習は、モデルがトレーニングデータを過剰に学習し、ノイズを含み、新しいデータでパフォーマンスが低下する場合に発生します。

  • 兆候:
    • 高いトレーニング精度、低いテスト精度
    • データに対してモデルが複雑すぎる
  • 防止:
    • より多くのトレーニングデータ
    • 交差検証
    • 正則化 (L1, L2)
    • より単純なモデル
    • 早期打ち切り
    • ドロップアウト (ニューラルネットワーク)
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Ridge, Lasso
from sklearn.preprocessing import PolynomialFeatures
import numpy as np

# データの生成
X = np.random.rand(100, 1) * 10
y = 2 * X + 3 + np.random.randn(100, 1) * 2

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# 過学習の例 - 高次の多項式
poly = PolynomialFeatures(degree=15)
X_poly = poly.fit_transform(X_train)

# 過学習を防ぐための正則化
# Ridge (L2正則化)
ridge = Ridge(alpha=1.0)
ridge.fit(X_poly, y_train)

# Lasso (L1正則化)
lasso = Lasso(alpha=0.1)
lasso.fit(X_poly, y_train)

print(f"Ridge score: {ridge.score(X_poly, y_train)}")
print(f"Lasso score: {lasso.score(X_poly, y_train)}")

希少度: 非常に一般的 難易度: 普通


18. トレーニングデータとテストデータ分割について説明し、その重要性について説明してください。

回答: トレーニングデータとテストデータ分割は、モデルのパフォーマンスを評価するために、データをトレーニングセットとテストセットに分割します。

  • 目的: 過学習を防ぎ、現実世界のパフォーマンスを推定する
  • 一般的な分割: 70-30または80-20 (トレーニング-テスト)
  • 交差検証: より堅牢な評価
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris

# データのロード
iris = load_iris()
X, y = iris.data, iris.target

# トレーニングデータとテストデータ分割
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

print(f"Training set size: {len(X_train)}")
print(f"Test set size: {len(X_test)}")

# モデルのトレーニング
model = LogisticRegression(max_iter=200)
model.fit(X_train, y_train)

# 評価
train_score = model.score(X_train, y_train)
test_score = model.score(X_test, y_test)

print(f"Training accuracy: {train_score:.2f}")
print(f"Test accuracy: {test_score:.2f}")

# 交差検証 (より堅牢)
cv_scores = cross_val_score(model, X, y, cv=5)
print(f"CV scores: {cv_scores}")
print(f"Mean CV score: {cv_scores.mean():.2f}")

希少度: 非常に一般的 難易度: 簡単


19. 分類に使用する評価指標は何ですか?

回答: シナリオに応じたさまざまな指標:

  • 精度: 全体的な正しさ (バランスの取れたデータセットに適している)
  • 適合率: 予測された肯定のうち、どれだけが正しいか
  • 再現率: 実際の肯定のうち、どれだけが見つかったか
  • F1スコア: 適合率と再現率の調和平均
  • 混同行列: 予測の詳細な内訳
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer

# データのロード
data = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
    data.data, data.target, test_size=0.3, random_state=42
)

# モデルのトレーニング
model = LogisticRegression(max_iter=10000)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

# 指標
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)

print(f"Accuracy: {accuracy:.2f}")
print(f"Precision: {precision:.2f}")
print(f"Recall: {recall:.2f}")
print(f"F1-Score: {f1:.2f}")

# 混同行列
cm = confusion_matrix(y_test, y_pred)
print(f"\nConfusion Matrix:\n{cm}")

# 分類レポート
print(f"\n{classification_report(y_test, y_pred)}")

希少度: 非常に一般的 難易度: 普通


20. 分類と回帰の違いは何ですか?

回答:

  • 分類:
    • 離散的なカテゴリ/クラスを予測
    • 出力: クラスラベル
    • 例: スパム検出、画像分類
    • アルゴリズム: ロジスティック回帰、決定木、SVM
    • 指標: 精度、適合率、再現率、F1
  • 回帰:
    • 連続的な数値の値を予測
    • 出力: 数値
    • 例: 住宅価格の予測、気温予測
    • アルゴリズム: 線形回帰、ランダムフォレスト回帰
    • 指標: MSE、RMSE、MAE、R²
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np

# 回帰の例
X_reg = np.array([[1], [2], [3], [4], [5]])
y_reg = np.array([2.1, 3.9, 6.2, 7.8, 10.1])

reg_model = LinearRegression()
reg_model.fit(X_reg, y_reg)
y_pred_reg = reg_model.predict([[6]])
print(f"Regression prediction: {y_pred_reg[0]:.2f}")  # 連続値

# 分類の例
X_clf = np.array([[1], [2], [3], [4], [5]])
y_clf = np.array([0, 0, 1, 1, 1])  # バイナリクラス

clf_model = LogisticRegression()
clf_model.fit(X_clf, y_clf)
y_pred_clf = clf_model.predict([[3.5]])
print(f"Classification prediction: {y_pred_clf[0]}")  # クラスラベル (0または1)

希少度: 非常に一般的 難易度: 簡単

Newsletter subscription

実際に機能する週次のキャリアのヒント

最新の洞察をメールボックスに直接お届けします

次の面接は履歴書一つで決まる

数分でプロフェッショナルで最適化された履歴書を作成。デザインスキルは不要—証明された結果だけ。

私の履歴書を作成

この投稿を共有

面接のコールバックを2倍に

求人内容に合わせて履歴書をカスタマイズする候補者は、2.5倍多くの面接を獲得します。当社のAIを使用して、すべての応募に対して即座に自動カスタマイズできます。