В производстве мы всегда ищем способы оптимизировать работу нашей производственной линии. Мы хотели бы увеличить пропускную способность при сохранении высокой доходности. Чтобы измерить, насколько продуктивна текущая система, мы можем использовать показатель Общая эффективность оборудования (OEE). OEE охватывает три аспекта: доступность, производительность и качество. В этом посте я хотел бы сосредоточиться на доступности и рассмотреть пример использования.

Предположим, нам дан файл журнала работы за 6 дней с определенного оборудования. Оборудование используется по 10 часов в день. Наша цель — выяснить, есть ли дни с проблемами. Проблема только в том, что статус лога написан на иностранном языке (скажем, бывает, что контрактный производитель находится в Индонезии).

import matplotlib.pyplot as plt
import pandas as pd
# suppose the data is stored in a pandas dataframe called df
df.head()

Существует множество способов анализа такого рода транзакционных данных. Здесь я сосредоточусь на конкретном методе, называемом тематическое моделирование. Основная идея состоит в том, чтобы сначала рассматривать каждую строку (или день) как мешок статуса (аналог мешка слов).

statusDF = pd.pivot_table(df, index="day", columns="dayStatus", values="durationInHours", aggfunc='sum')
statusDF.fillna(0, inplace=True)
statusDF

Затем мы можем использовать тематическое моделирование, чтобы выяснить, можно ли сгруппировать журнал за 6 дней в меньший подмножество данных. Каждому кластеру будет присвоено имя (или тема), и в идеале данные в них будут иметь общий профиль статусов. Это аналогично моделированию темы в обработке естественного языка, где есть определенные слова, тесно связанные с некоторыми темами.

Мы будем использовать простой алгоритм тематического моделирования под названием Неотрицательная матричная факторизация (NMF). Я оставлю обсуждение деталей алгоритма в другом посте.

Сложность NMF заключается в том, что нам нужно заранее определить количество скрытых тем. В этом случае мы произвольно выбираем их равными 2.

from sklearn.decomposition import NMF
model = NMF(n_components=2, init='random', random_state=1)
plt.figure(figsize=(8, 5))
W = np.around(model.fit_transform(statusDF), 1)
plt.subplot(1, 2, 1)
plt.imshow(W)
plt.title("matrix W")
plt.yticks(np.arange(len(statusDF.index.values)), statusDF.index.values)
H = np.around(model.components_, 1)
plt.subplot(1, 2, 2)
plt.xticks(np.arange(len(statusDF.columns.values)), statusDF.columns.values, rotation='90')
plt.colorbar(pad=0.1)
plt.imshow(H)
plt.title("matrix H")
plt.show()

NMF пытается разложить матрицу Bag of Status на произведения матрицы W и матрицы H. Это делается без семантического понимания того, что на самом деле означает каждый статус (т.е. нет необходимости в перевод).

Матрица Вт

Матрицу W можно интерпретировать как отображение между днями и темами. Из приведенного выше результата видно, что дни 1, 3, 4 и 6 взяты из темы 0 с разной степенью достоверности (отмечены цветом прямоугольника). Между тем, день 2 и 5 происходят из темы 1. Это показывает, что есть две группы дней. Вопрос в том, что отличает их друг от друга? Ответ лежит в матрице H.

Матрица Н

Матрица H — это отображение между темами и статусами. Например, тема 0 связана с двумя статусами: «bergerak aktif» и «uji coba berjalan». Тема 1, с другой стороны, включает «пембетулан» и «пенгецекан». На этом этапе будет полезно иметь эксперта в предметной области, который может интерпретировать статусы. Быстрый просмотр вашего любимого механизма перевода покажет, что «bergerak aktif» и «uji coba berjalan» означают активное движение, а «pembetulan» и «pengecekan» связаны с действиями по исправлению/отладке.

Оказывается, тема 1 связана с обслуживанием, а тема 0 — с высокой доступностью. Таким образом, мы можем подчеркнуть, что то, что произошло во второй и пятый день, по-видимому, вызвало необходимость технического обслуживания, которое в конечном итоге нанесло ущерб показателю OEE машины.

Мы также можем визуализировать матрицу H с помощью облака слов. Размер каждого слова соответствует значениям матрицы.

from wordcloud import WordCloud
def printWordCloud(text):
  # Create and generate a word cloud image:
  wc = WordCloud(relative_scaling=0.6, prefer_horizontal=1)
  wc.generate_from_frequencies(text)
# Display the generated image:
  plt.imshow(wc, interpolation='bilinear')
  plt.axis("off")
  plt.show()
  
# Topic 0
text0 = dict(zip(statusDF.columns.values, H[0]+1e-99)) # replace 0 value  with a small weight
printWordCloud(text0)
# Topic 1
text1 = dict(zip(statusDF.columns.values, H[1]+1e-99))
printWordCloud(text1)

Заключение

Мы показали, что тематическое моделирование можно использовать для идентификации дней (строк) с аналогичным профилем статусов (столбцов). С помощью эксперта в предметной области мы можем интерпретировать значение каждой темы и впоследствии решить, какая из них требует немедленного внимания.