рд╕реНрдкрд╛рд░реНрдХ рдПрдордПрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рдЪреБрдХреЗ рдХрдИ рд▓реЛрдЧ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдЪреАрдЬреЗрдВ рдЬреЛ "рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдлрд▓ рдирд╣реАрдВ" рд╣реИрдВред
рдпрд╛ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ред рд╕реНрдкрд╛рд░реНрдХ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреА рд╕реНрдерд┐рддрд┐ рдпрд╣ рд╣реИ рдХрд┐ рд╕реНрдкрд╛рд░реНрдХрд▓ рдмреЗрд╕ рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рд╣реИ, рдФрд░ рд╕рднреА рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреИрдХреЗрдЬ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдпрд╣ рд╣рдореЗрд╢рд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдбреЗрдЯрд╛ рд╕рд╛рдЗрдВрдЯрд┐рд╕реНрдЯ рдФрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдкрд░рд┐рдЪрд┐рдд рдЙрдкрдХрд░рдгреЛрдВ (рдЬрдкрдЯрд░, рдЬреЗрдкреЗрд▓рд┐рди) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ рд╕рдмрд╕реЗ рдЬреНрдпрд╛рджрд╛ рдЬрд░реВрд░рдд рд╣реЛрддреА рд╣реИред рд╡реЗ рдорд╛рд╡реЗрди-рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рд╕рд╛рде 500 рдореЗрдЧрд╛рдмрд╛рдЗрдЯ рдЬреЗрдПрдЖрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдпрд╛ рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рдореЗрдВ рдирд┐рд░реНрднрд░рддрд╛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕реНрдкрд╛рд░реНрдХ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЬреЗрд╡реАрдПрдо-рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрд┐рд▓реНрдб рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рд╛рде рдмреЗрд╣рддрд░ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реНрд▓реЗрд╖рдХреЛрдВ рдФрд░ рдбреЗрдЯрд╛-рд╕рд╛рдЗрдВрдЯрд┐рд╕реНрдЯреЛрдВ рдХреЗ рдмрд╣реБрдд рд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдЬреЛ рдЬреБрдкрд┐рдЯрд░ / рдЬрд╝реЗрдкреЗрд▓рд┐рди рдХреЗ рдЖрджреА рд╣реИрдВред DevOps рдФрд░ рдХреНрд▓рд╕реНрдЯрд░ рдПрдбрдорд┐рдирд┐рд╕реНрдЯреНрд░реЗрдЯрд░ рдХреЛ рдХрдВрдкреНрдпреВрдЯ рдиреЛрдбреНрд╕ рдкрд░ рдкреИрдХреЗрдЬ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рдирд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рдмреБрд░рд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИред рдЬрд┐рд╕ рдХрд┐рд╕реА рдиреЗ рдЕрдкрдиреЗ рджрдо рдкрд░ рд╕реНрдкрд╛рд░реНрдХрд▓рдПрдо рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд▓рд┐рдЦрд╛, рд╡рд╣ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╡рд░реНрдЧреЛрдВ рдФрд░ рд╡рд┐рдзрд┐рдпреЛрдВ (рдЬреЛ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдирд┐рдЬреА [рдПрдордПрд▓] рд╣реИрдВ), рд╕рдВрдЧреНрд░рд╣реАрдд рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рдЖрджрд┐ рдХреЗ рд╕рд╛рде рдХрд┐рддрдиреА рдЫрд┐рдкреА рд╣реБрдИ рдХрдард┐рдирд╛рдЗрдпрд╛рдБ рд╣реИрдВред
рдФрд░ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдм, MMLSpark рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд╕рд╛рде, рдЬреАрд╡рди рдереЛрдбрд╝рд╛ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рд╕реНрдкрд╛рд░реНрдХрдПрдордПрд▓ рдФрд░ рд╕реНрдХрд╛рд▓рд╛ рдХреЗ рд╕рд╛рде рд╕реНрдХреЗрд▓реЗрдмрд▓ рдорд╢реАрди рд╕реАрдЦрдиреЗ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рдиреЗ рдХреА рд╕реАрдорд╛ рдереЛрдбрд╝реА рдХрдо рд╣реИред
рдкрд░рд┐рдЪрдп
рдХрдИ рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдХреЗ рдХрд╛рд░рдг, рд╕рд╛рде рд╣реА рд╕реНрдкрд╛рд░реНрдХрдПрдордПрд▓ рдореЗрдВ рддреИрдпрд╛рд░ рддрд░реАрдХреЛрдВ рдФрд░ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХрд╛ рдПрдХ рд╡рд┐рд░рд▓ рд╕реЗрдЯ, рдХрдИ рдХрдВрдкрдирд┐рдпрд╛рдВ рд╕реНрдкрд╛рд░реНрдХ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд▓рд┐рдЦрддреА рд╣реИрдВред рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рдкреНрд░рд╡реАрдгрдПрдордПрд▓ , рдЬрд┐рд╕реЗ рдУрдбрдиреЛрдХрд▓рд╛рд╕реНрдирд┐рдХ рдореЗрдВ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЬреЛ, рдЧреАрдерд╣рдм рдкрд░ рдХреНрдпрд╛ рд╣реИ, рдХреЗ рддреНрд╡рд░рд┐рдд рдЖрдХрд▓рди рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдмрд╣реБрдд рдЖрд╢рд╛рдЬрдирдХ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЗрдирдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдорд╛рдзрд╛рди рдпрд╛ рддреЛ рдмрдВрдж рд╣реИрдВ рдпрд╛ рдмрд┐рд▓реНрдХреБрд▓ рдЦреБрд▓реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдореЗрдВ рдорд╛рд╡реЗрди / рдПрд╕рдмреАрдЯреА рдФрд░ рдПрдкреАрдЖрдИ рдкреНрд░рд▓реЗрдЦрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдирд╣реАрдВ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
рдЖрдЬ рд╣рдо MMLSpark рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ ред
рд╣рдо рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдЯрд╛рдЗрдЯреИрдирд┐рдХ рдХреЗ рдпрд╛рддреНрд░рд┐рдпреЛрдВ рдХреЛ рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред рд▓рдХреНрд╖реНрдп рд╕рдВрднрд╡ рдХреЗ рд░реВрдк рдореЗрдВ MMLSpark рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреА рдХрдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ, рдирд╣реАрдВ рдЫрд╡рд┐ рдкрд░ SOTA рдмрд╛рд╣рд░ рджрд╕реНрддрдХ рдХреВрд▓ рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рджрд┐рдЦрд╛рдУред рддреЛ рдЯрд╛рдЗрдЯреИрдирд┐рдХ рдХрд░реЗрдВрдЧреЗред

рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рд╣реА рд╕реНрдХрд╛рд▓рд╛ ( рдкреНрд░рд▓реЗрдЦрди ), рдкрд╛рдпрдерди рдПрдкреАрдЖрдИ ( рдкреНрд░рд▓реЗрдЦрди ) рдХреЗ рд▓рд┐рдП рдПрдХ рджреЗрд╢реА рдПрдкреАрдЖрдИ рд╣реИ, рдФрд░, GitHub рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдХреБрдЫ рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдпрд╣ рдЬрд▓реНрдж рд╣реА рдЖрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдкреАрдЖрдИ рд╣реЛрдЧрд╛ред
GitHub рдкреНрд░реЛрдЬреЗрдХреНрдЯ (PySpark + Jupyter) рдореЗрдВ рдЕрдЪреНрдЫреЗ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рд▓реЗ рд▓реИрдкрдЯреЙрдк рд╣реИрдВ , рд▓реЗрдХрд┐рди рд╣рдо рджреВрд╕рд░реЗ рд░рд╛рд╕реНрддреЗ рдкрд░ рдЬрд╛рдПрдВрдЧреЗред рдЬреИрд╕рд╛ рдХрд┐ рджрд┐рдорд┐рддреНрд░реА рдмреБрдЧрд╛рдЪреЗрдиреНрдХреЛ рдиреЗ рд▓рд┐рдЦрд╛ рд╣реИ , рдпрджрд┐ рдЖрдк рд╕реНрдкрд╛рд░реНрдХ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд╕рд┐рдд рд╣реЛрддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рдд, рдЖрдкрдХреЗ рдкрд╛рд╕ рд╕реНрдХрд╛рд▓рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рд░ рдХрд╛рд░рдг рд╣реИ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реНрдХреЗрд▓рд╛ рдЖрдкрдХреЛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХреБрд╢рд▓рддрд╛ рд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд▓рдЪреАрд▓реЗ рдврдВрдЧ рд╕реЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдорд░ рдФрд░ рдПрд╕реНрдЯреАрдореЗрдЯрд░ рдХреЛ рд╕реНрдкрд╛рд░реНрдХрдПрдордПрд▓ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рдПрдореНрдмреЗрдб рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдзреАрд░реЗ-рдзреАрд░реЗ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ UDF рдореЗрдВ / рдкрд╛рдВрдбрд╛ рдХреЛрдб (JVM рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдкрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ) рдкрд╣рд▓реЗ рд╣реА рдмрд╣реБрдд рдХреБрдЫ рд▓рд┐рдЦрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИред
рд╕реНрдерд╛рдкрдирд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд
рдкреВрд░рд╛ рд▓реИрдкрдЯреЙрдк рдпрд╣рд╛рдВ рдЙрдкрд▓рдмреНрдз рд╣реИ ред рдЯрд╛рдЗрдЯреИрдирд┐рдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рд▓реИрдкрдЯреЙрдк рдкрд░ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдЬрд╝реЗрдкреЗрд▓рд┐рди рдбреЙрдХрд░ рдЫрд╡рд┐ рдЖрдВрдЦреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдбреЙрдХрдЯрд░ рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред MMLSpark рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдорд╛рд╡реЗрди рд╕реЗрдВрдЯреНрд░рд▓ рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реНрдкрд╛рд░реНрдХ-рдкреИрдХреЗрдЬ рдореЗрдВ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдЬрд╝реЗрдкреЗрд▓рд┐рди рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд▓реИрдкрдЯреЙрдк рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдмреНрд▓реЙрдХ рдЪрд▓рд╛рдирд╛ рд╣реЛрдЧрд╛:
%spark.dep z.addRepo("bintray.com").url("http://dl.bintray.com/spark-packages/maven/") z.load("Azure:mmlspark:0.17")
рдпрд╣ рдХрд╣рдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдЙрддреНрдХреГрд╖реНрдЯ рдкрд┐рдЫрдбрд╝реА рд╕рдВрдЧрддрддрд╛ рд╣реИ: рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, XGBoost4j- рд╕реНрдкрд╛рд░реНрдХ, рдЬрд┐рд╕реЗ рд╕реНрдкрд╛рд░реНрдХ 2.3+ рдХреА рдиреНрдпреВрдирддрдо рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдпрд╣ рдЪреАрдЬрд╝ рд╕реНрдкрд╛рд░реНрдХ 2.2.1 рдореЗрдВ рдорд┐рд▓ рдЧрдИ, рдЬреЛ рдХрд┐ рдЬрд╝реЗрдкреЗрд▓рд┐рди рдбреЙрдХрд┐рди рдЫрд╡рд┐ рдФрд░ рдХрд┐рд╕реА рднреА рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдХреЗ рд╕рд╛рде рдЖрдИ рдереАред рдореИрдВрдиреЗ рдЧреМрд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ред
рдиреЛрдЯ: MMLSpark рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЕрдзрд┐рдХрд╛рдВрд╢ рднрд╛рдЧ рдПрдХ рдХреНрд▓рд╕реНрдЯрд░ рдкрд░ рдЧреНрд░рд┐рдб рдХреА рд╕реНрдерд╛рдкрдирд╛ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдкрд┐рдд рд╣реИ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП CNTK рдореМрдЬреВрдж рд╣реИ (рдЬреЛ рдкреНрд░рд▓реЗрдЦрди рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП cntk рдореЙрдбрд▓ рдХреЛ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рд┐рдП) рдФрд░ рдПрдХ рдмрдбрд╝рд╛ OpenCV рдмреНрд▓реЙрдХред рд╣рдо рдЕрдзрд┐рдХ рд╕рд╛рдВрд╕рд╛рд░рд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗ рдФрд░ рдорд╛рдорд▓реЗ рдХреЛ "рдореЙрдбрд▓" рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗ, рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рд╛рд░рдгреАрдмрджреНрдз рдбреЗрдЯрд╛ рдХреЗ рд╡рд┐рд╢рд╛рд▓ рд╕рд░рдгрд┐рдпрд╛рдБ рд╣реИрдВ рдЬреЛ .csv, рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рд╛рд░реВрдк рдореЗрдВ HDFS рдХреЗ рд░реВрдк рдореЗрдВ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдкреВрд░реНрд╡-рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдФрд░ рдПрдХ рдореЙрдбрд▓ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдпрд╣ рдбреЗрдЯрд╛ рдПрдХ рдорд╢реАрди рдХреА рдореЗрдореЛрд░реА рдореЗрдВ рдлрд┐рдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдХреНрд▓рд╕реНрдЯрд░ рдкрд░ рд╕рднреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░реЗрдВрдЧреЗред
рдкрдврд╝рдирд╛ рдФрд░ рдЦреБрдлрд┐рдпрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╕реНрдкрд╛рд░реНрдХ + рдЬрд╝реЗрдкреЗрд▓рд┐рди рдмрд┐рд▓реНрдХреБрд▓ рднреА рдЦрд░рд╛рдм рдирд╣реАрдВ рд╣реИ рдФрд░ рдИрдбреАрдП рдХреЗ рдХрд╛рд░реНрдп рдХреЗ рд╕рд╛рде рд╕рд╛рдордирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЙрдирдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЙрди рд╡рд░реНрдЧреЛрдВ рдХреЛ рдЖрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдирдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
- рд╕реНрдкрд╛рд░реНрдХ.sql.types рд╕реЗ рд╕рднреА рдХреЛ рд╕реНрдХреАрдорд╛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдФрд░ рдбреЗрдЯрд╛ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП
- рд╕рднреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП spark.sql.functions рд╕реНрддрдВрднреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
- com.microsoft.ml.spark.SummarizeData , рдЬрд┐рд╕реЗ pandas рдХрд╛ рдПрдХ рдПрдирд╛рд▓реЙрдЧ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред DataFrame.describe
import com.microsoft.ml.spark.SummarizeData import org.apache.spark.sql.functions._ import org.apache.spark.sql.types._
рд╣рдо рдЕрдкрдиреА рдлрд╝рд╛рдЗрд▓ рдкрдврд╝рддреЗ рд╣реИрдВ:
val titanicSchema = StructType( StructField("Passanger", ShortType) :: StructField("Survived", ShortType) :: StructField("PClass", ShortType) :: StructField("Name", StringType) :: StructField("Sex", StringType) :: StructField("Age", ShortType) :: StructField("SibSp", ShortType) :: StructField("Parch", ShortType) :: StructField("Ticket", StringType) :: StructField("Fare", FloatType) :: StructField("Cabin", StringType) :: StructField("Embarked", StringType) :: Nil ) val train = spark .read .schema(titanicSchema) .option("header", true) .csv("/mountV/titanic/train.csv")
рдФрд░ рдЕрдм рдбреЗрдЯрд╛ рдХреЛ рд╕реНрд╡рдпрдВ, рд╕рд╛рде рд╣реА рдЙрдирдХреЗ рдЖрдХрд╛рд░ рдХреЛ рджреЗрдЦреЗрдВ:
println(s"Train shape is: ${train.count} x ${train.columns.length}") train.limit(5).createOrReplaceTempView("trainHead")
рдиреЛрдЯ: рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрдкрдХреЛ createOrReplaceTempView рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдЬрдм рдЖрдк рд╕рд┐рд░реНрдл .show (5) рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╢реЛ рдореЗрдВ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ: рдЬрдм рдбреЗрдЯрд╛ "рдЪреМрдбрд╝рд╛" рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдкреНрд▓реЗрдЯ рдХрд╛ рдкрд╛рдард╛рддреНрдордХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ "рддреИрд░рддрд╛ рд╣реИ", рдФрд░ рдХреБрдЫ рднреА рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред
рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛ рдХрд╛ рдЖрдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ: Train shape is: 891 x 12
рдФрд░ рдЕрдм sql рд╕реЗрд▓ рдореЗрдВ рд╣рдо рдкрд╣рд▓реА 5 рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ:
%sql select * from trainHead

рдареАрдХ рд╣реИ, рдЖрдЗрдП рд╕рд╛рд░рд╛рдВрд╢ рджреЗрдЦреЗрдВ рд╣рдорд╛рд░реА рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ:
new SummarizeData() .setBasic(true) .setCounts(true) .setPercentiles(false) .setSample(true) .setErrorThreshold(0.25) .transform(train) .createOrReplaceTempView("summary")
SummarizeData рд╡рд░реНрдЧ рдХреЗ рдкрд╛рд╕ рд╕рд░рд▓ Dataset.describe рдкрд░ рдХрдИ рдлрд╛рдпрджреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЖрдкрдХреЛ рд▓рд╛рдкрддрд╛ рдФрд░ рдЕрдиреВрдареЗ рдореВрд▓реНрдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЖрдкрдХреЛ рдорд╛рддреНрд░рд╛рдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рд╕рдЯреАрдХрддрд╛ рдХреЛ рднреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрдбрд╝реЗ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдХреБрдЫ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╡рд┐рдЪрд╛рд░рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпрд╣ рдореБрдЭреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рд▓рдЧ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдкреНрд░рд╡реАрдбрд╛рдПрдордПрд▓ рдореЗрдВ рдУрдбрдиреЛрдХреНрд▓рд╛рд╕рдирд┐рдХ рдиреЗ рд╕реБрдореЗрд░рд┐рдореЗрдбрд┐рд╕рди рдПрдирд╛рд▓реЙрдЧ рдХрд╛ рдмреЗрд╣рддрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд┐рдпрд╛ рдерд╛ред Microsoft рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдЧрдпрд╛ рдФрд░ org.apache.spark.sql.functions
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рд╕рд┐рд░реНрдл рдЗрддрдирд╛ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдЖрд╕рд╛рдиреА рд╕реЗ рдПрдХ рд╣реА рд╡рд░реНрдЧ рдореЗрдВ рд▓рдкреЗрдЯрд╛ рдЧрдпрд╛ рд╣реИред Odnoklassniki рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЙрдирдХреЗ VectorStatCollector
рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдХреЛрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬрдм рдЖрдкрдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рдПрдХ рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рд╕рднреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛) рдФрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдВрдЪрд╛рд▓рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, VectorAssembler
рдиреЗ DecimalType
рдХреЛ рдкрдЪрд╛рдиреЗ рд╕реЗ рдЗрдирдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛ рд╣реИ)ред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕реНрдкрд╛рд░реНрдХ рдХреЗ рд╕рд╛рде рдореЗрд░реЗ рдЕрдиреБрднрд╡ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдзрд╛рд░рдгрд╛ рд╣реИ рдХрд┐ MMLSpark рд╕реЗ SummarizeData org.apache.spark.sql.catalyst рдореЗрдВ StackOverflow
рдЬреИрд╕реА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рджреБрд░реНрдШрдЯрдирд╛рдЧреНрд░рд╕реНрдд рд╣реЛ рд╕рдХрддреА рд╣реИ рдпрджрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рд╕реЗ рдХреЙрд▓рдо рд╣реИрдВ, рдФрд░ рдЧрдгрдирд╛ рдЧреНрд░рд╛рдл рдЙрд╕ рд╕рдордп рддрдХ рдЫреЛрдЯрд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рддрдХ рдпрд╣ рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ ( рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╕реНрдкрд╛рд░реНрдХ 2.4 рдореЗрдВ "рдЪрд░рдо" рдХреЗ рдРрд╕реЗ рдкреНрд░рд╢рдВрд╕рдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЙрдиреНрд╣реЛрдВрдиреЗ Catalyst
рдЧреНрд░рд╛рдл рдЕрдиреБрдХреВрд▓рдХ рдХрд╛ рдХрдЯреМрддреА рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЛ рдЬреЛрдбрд╝рд╛)ред рдЦреИрд░, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕реНрддрдВрднреЛрдВ рдХреЗ рд╕рд╛рде, Microsoft рд╕реЗ рд╕рдВрд╕реНрдХрд░рдг рдзреАрдорд╛ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рд▓реЗрдХрд┐рди рдпрд╣, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЕрд▓рдЧ рд╕реЗ рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред
рдбреЗрдЯрд╛ рдХреА рд╕рдлрд╛рдИ
рдЯрд╛рдЗрдЯреИрдирд┐рдХ рдореЗрдВ, рд╕рдм рдХреБрдЫ рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣ рд╣реИ - рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реНрддрдВрднреЛрдВ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдорд╛рди рдЧрд╛рдпрдм рд╣реИред рдФрд░ рдбреЗрдЯрд╛ рдореЗрдВ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреИрдВрдЯ (рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдбреЗрдЯрд╛ рдХрд╛ рдпрд╣ рд╡рд┐рд╢реЗрд╖ рд╕рдВрд╕реНрдХрд░рдг рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИ) - рд▓рд╛рдкрддрд╛ рдорд╛рдиреЛрдВ рд╕реЗ 25 рд▓рд╛рдЗрдиреЗрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЗрд╕реЗ рдареАрдХ рдХрд░реЗрдВ:
val trainFiltered = train.filter(!(isnan(col("Survived")) || isnull(col("Survived"))))
рд╕реНрдЯреНрд░рд┐рдВрдЧ рдбреЗрдЯрд╛ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ
рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛрдореБрдЭреЗ рдпрд╛рдж рд╣реИ, рдЯрд╛рдЗрдЯреИрдирд┐рдХ рдореЗрдВ Name
рдФрд░ Cabin
рдХреНрд╖реЗрддреНрд░ рд╕реЗ рдмрд╛рд╣рд░ рд▓рд╛рдИ рдЧрдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рдереАрдВред рдЖрдк рдЙрдиреНрд╣реЗрдВ рдмрд╣реБрдд рдЖрдкреВрд░реНрддрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдЦреБрдж рдХреЛ рдХреБрдЫ рд╣рдж рддрдХ рд╕реАрдорд┐рдд рдХрд░ рд▓реЗрдВрдЧреЗ, рдмрд╕ рдЗрддрдирд╛ рд╣реА рдирд╣реАрдВ рд▓рдЧрднрдЧ рдПрдХ рд╣реА рдХреЛрдб рдХреЗ рдЙрджрд╛рд╣рд░рдг рджреЗрдиреЗ рдХреЗ рд▓рд┐рдПред
рдЖрдорддреМрд░ рдкрд░ рдРрд╕реА рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрддрд╛ рд╣реИред
рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:
- рд╕рдм рдХреБрдЫ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдбреЗрдЯрд╛ рдЙрд╕реА рд╕реНрдерд╛рди рдкрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдерд╛;
- рд╕рдм рдХреБрдЫ SpakrML Transformer рдпрд╛ Spark ML Estimator Classes рдХреЗ рд░реВрдк рдореЗрдВ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддрд╛рдХрд┐ рдмрд╛рдж рдореЗрдВ рдЗрд╕реЗ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рдЗрдХрдЯреНрдард╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред
рдиреЛрдЯ: рдкрд╛рдЗрдкрд▓рд╛рдЗрди, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рд╣рдореЗрд╢рд╛ рдЯреНрд░реЗрди рдФрд░ рдкрд░реАрдХреНрд╖рдг рджреЛрдиреЛрдВ рдореЗрдВ рдПрдХ рд╣реА рдкрд░рд┐рд╡рд░реНрддрди рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╣рдореЗрдВ рдХреНрд░реЙрд╕-рд╡реИрдзреАрдХрд░рдг рдореЗрдВ "рднрд╡рд┐рд╖реНрдп рдХреЛ рджреЗрдЦрдиреЗ" рдХреА рддреНрд░реБрдЯрд┐ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреА рднреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдФрд░ рдпрд╣ рд╣рдореЗрдВ рдЕрдкрдиреА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдЪрдд рдХрд░рдиреЗ, рд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░рдиреЗ рдХреА рд╕рд░рд▓ рдХреНрд╖рдорддрд╛ рднреА рджреЗрддрд╛ рд╣реИред
рд╕реНрдкрд╛рд░реНрдХрд▓рдПрдо рдХреЗ рдкрд╛рд╕ рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП "рд▓рдЧрднрдЧ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ" рд╡рд░реНрдЧ рд╣реИ - SQLTranformer , рд▓реЗрдХрд┐рди рдПрд╕рдХреНрдпреВрдПрд▓ рдореЗрдВ рд▓рд┐рдЦрдирд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реНрдХреЗрд▓ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рд╕реЗ рднреА рдмрджрддрд░ рд╣реИ, рдЕрдЧрд░ рдХреЗрд╡рд▓ рдЖрдЗрдбрд┐рдпрд╛ рдореЗрдВ рд╕рдВрдХрд▓рди рдФрд░ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╣рд╛рдЗрд▓рд╛рдЗрдЯрд┐рдВрдЧ рдХреЗ рдЪрд░рдг рдореЗрдВ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдпрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред рдФрд░ рдпрд╣рд╛рдБ MMLSpark рд╣рдорд╛рд░реА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЖрддрд╛ рд╣реИ, рдЬрд╣рд╛рдБ рдПрдХ рд╕рд╣реА рдорд╛рдпрдиреЗ рдореЗрдВ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ UDFTransformer рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ :
import com.microsoft.ml.spark.UDFTransformer
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдкрдирд╛ рдкрд░рд┐рд╡рд░реНрддрди рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдПрдВрдЧреЗ, рдЬреЛ рд╕реАрдорд╛ рддрдХ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рдЕрдм рдпреВрдбреАрдПрдлрдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдорд░ рдмрдирд╛рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рджрд┐рдЦрд╛рдирд╛ рд╣реИред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдРрд╕реЗ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдХреЛрдИ рднреА рддрд░реНрдХ рдХреЛ рдХрд┐рд╕реА рднреА рд╕реНрддрд░ рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдореЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддрд╛ рд╣реИред
val miss = ".*miss\\..*".r val mr = ".*mr\\..*".r val mrs = ".*mrs\\..*".r val master = ".*master.*".r def convertNames(input: String): Option[String] = { Option(input).map(x => { x.toLowerCase match { case miss() => "Miss" case mr() => "Mr" case mrs() => "Mrs" case master() => "Master" case _ => "Unknown" } }) }
(рдЖрдк рддреБрд░рдВрдд рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЧрд╛рдпрдм рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХрд╛рд▓рд╛ рдХрд┐рддрдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ, рдЬреЛ, рд╡реИрд╕реЗ, рди рдХреЗрд╡рд▓ null
, рдмрд▓реНрдХрд┐ Double.NaN
рднреА рд╣реИрдВред Double.NaN
, рд▓реЗрдХрд┐рди рд╡рд╣рд╛рдБ рд╣реИрдВ рдРрд╕рд╛ рдордЬрд╛рдХ BooleanType
рдЪрд░, рдЖрджрд┐ рдореЗрдВ рдЪреВрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдПрдХ рджреБрд░реНрд▓рдн рдЪреАрдЬ)
рдЕрдм рд╣рдорд╛рд░реЗ UserDefinedFunction
рдШреЛрд╖рдгрд╛ рдХрд░реЗрдВ рдФрд░ рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рддреБрд░рдВрдд рдПрдХ Transformer
рдмрдирд╛рдПрдБ:
val nameTransformUDF = udf(convertNames _) val nameTransformer = new UDFTransformer() .setUDF(nameTransformUDF) .setInputCol("Name") .setOutputCol("NameType")
рдиреЛрдЯ: рдПрдХ рдЬрд╝реЗрдкреЗрд▓рд┐рди рд▓реИрдкрдЯреЙрдк рдореЗрдВ, рдпрд╣ рд╕рднреА рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдпрд╣ рд╕рднреА рдмрд╛рдж рдореЗрдВ рдЙрддреНрдкрд╛рджрди рдХреЛрдб рдореЗрдВ рдЖрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рд╕рднреА UDF рдЙрди рдХрдХреНрд╖рд╛рдУрдВ рдпрд╛ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдореЗрдВ рд╣реИрдВ рдЬреЛ extends Serializable
ред рд╕реНрдкрд╖реНрдЯ рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдХрднреА-рдХрднреА рднреВрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рд▓рдВрдмреЗ рд╕рдордп рдХреЗ рд▓рд┐рдП рдЦреЛрдж рд╕рдХрддреЗ рд╣реИрдВ рд╕реНрдкрд╛рд░реНрдХ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рдВрдмреЗ рд╕реНрдЯреИрдХ рдХреЗ рдирд┐рд╢рд╛рди рдХреЛ рдкрдврд╝рдиреЗ рдореЗрдВ рдХреНрдпрд╛ рдЧрд▓рдд рд╣реИред
рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрднреА рднреА Cabin
рдХреНрд╖реЗрддреНрд░ рд╣реИред рдЖрдЗрдП рдЗрд╕реЗ рдХрд░реАрдм рд╕реЗ рджреЗрдЦреЗрдВ:

рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХрдИ рд▓рд╛рдкрддрд╛ рдореВрд▓реНрдп рд╣реИрдВ, рдкрддреНрд░, рд╕рдВрдЦреНрдпрд╛, рд╡рд┐рднрд┐рдиреНрди рд╕рдВрдпреЛрдЬрди рдЖрджрд┐ рд╣реИрдВред рдЪрд▓реЛ рдХреЗрдмрд┐рдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд▓реЗрддреЗ рд╣реИрдВ (рдпрджрд┐ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ), рд╕рд╛рде рд╣реА рд╕рдВрдЦреНрдпрд╛рдПрдВ - рдЙрдирдХреЗ рдкрд╛рд╕ рд╕рдВрднрд╡рддрдГ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рддрд░реНрдХ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╕рдВрдЦреНрдпрд╛ рдЬрд╣рд╛рдЬ рдХреЗ рдПрдХ рдЫреЛрд░ рд╕реЗ рд╣реИ, рддреЛ рдзрдиреБрд╖ рдкрд░ рдХреЗрдмрд┐рдиреЛрдВ рдХреЗ рдкрд╛рд╕ рдХрдо рдореМрдХрд╛ рдерд╛ред рд╣рдо рдлрд╝рдВрдХреНрд╢рди рднреА рдмрдирд╛рдПрдВрдЧреЗ, рдФрд░ рдлрд┐рд░ рдЙрдирдХреЗ рдЖрдзрд╛рд░ рдкрд░ UDFTransformer
:
def getCabinsCount(input: String): Int = { Option(input) match { case Some(x) => x.split(" ").length case None => -1 } } val numPattern = "([az])([0-9]+)".r def getNumbersFromCabin(input: String): Int = { Option(input) match { case Some(x) => { x.split(" ")(0).toLowerCase match { case numPattern(sym, num) => Integer.parseInt(num) case _ => -1 } } case None => -2 } } val cabinsCountUDF = udf(getCabinsCount _) val numbersFromCabinUDF = udf(getNumbersFromCabin _) val cabinsCountTransformer = new UDFTransformer() .setInputCol("Cabin") .setOutputCol("CabinCount") .setUDF(cabinsCountUDF) val numbersFromCabinTransformer = new UDFTransformer() .setInputCol("Cabin") .setOutputCol("CabinNumber") .setUDF(numbersFromCabinUDF)
рдЕрдм рдЖрдЗрдП рдЙрдореНрд░ рдХреЗ рд▓рд╛рдкрддрд╛ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рдЬрд╝реЗрдкрд▓рд┐рди рдХреА рд╡рд┐рдЬрд╝реБрдЕрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдПрдБ:

рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдХреИрд╕реЗ рд▓рд╛рдкрддрд╛ рдорд╛рди рд╕рдм рдХреБрдЫ рдмрд┐рдЧрд╛рдбрд╝ рджреЗрддреЗ рд╣реИрдВред рдЙрдиреНрд╣реЗрдВ рдордзреНрдпрдо (рдпрд╛ рдордзреНрдп) рдХреЗ рд╕рд╛рде рдмрджрд▓рдирд╛ рддрд░реНрдХрд╕рдВрдЧрдд рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рдПрдордПрдордПрд▓рд╕реНрдкрд╛рд░реНрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреА рд╕рднреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ Estimator
рд▓рд┐рдЦреЗрдВрдЧреЗ, рдЬреЛ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдирдореВрдиреЗ рдкрд░ рд╕рдореВрд╣ / рдФрд╕рдд рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдЧрд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд╕рд╛рде рдмрджрд▓ рджреЗрдЧрд╛ред
рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
import org.apache.spark.sql.{Dataset, DataFrame} import org.apache.spark.ml.{Estimator, Model} import org.apache.spark.ml.param.{Param, ParamMap} import org.apache.spark.ml.util.Identifiable import org.apache.spark.ml.util.DefaultParamsWritable import com.microsoft.ml.spark.{HasInputCol, HasOutputCol} import com.microsoft.ml.spark.ConstructorWritable import com.microsoft.ml.spark.ConstructorReadable import com.microsoft.ml.spark.Wrappable
рдЖрдЗрдП ConstructorWritable
рдзреНрдпрд╛рди рджреЗрдВ, рдЬреЛ рдЬреАрд╡рди рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИред рдпрджрд┐ рд╣рдорд╛рд░рд╛ Model
рдПрдХ "рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд" рдореЙрдбрд▓ рд╣реИ рдЬреЛ fit(),
рд╡рд┐рдзрд┐ рджреЗрддрд╛ рд╣реИ, рдЬреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЗрд╕рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдФрд░ рдпрд╣ рд╕рдВрднрд╡рддрдГ 99% рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╣реИ), рддреЛ рд╣рдо рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рд╕реЗ рдХреНрд░рдордмрджреНрдзрддрд╛ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд┐рдХрд╛рд╕ рдХреЛ рдЧрддрд┐ рджреЗрддрд╛ рд╣реИ, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдбреЗрдЯрд╛рд╕рд┐рд╕реНрдЯрд┐рд╕реНрдЯ рдФрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдХреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡реЗрд╢ рд╕реАрдорд╛ рдХреЛ рднреА рдХрдо рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЖрдорддреМрд░ рдкрд░ рдкреЗрд╢реЗрд╡рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдирд╣реАрдВ рд╣реИрдВред
рд╣рдорд╛рд░реЗ Estimator
рд╡рд░реНрдЧ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣рд╛рдВ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд fit
рд╡рд┐рдзрд┐ рд╣реИ, рдмрд╛рдХреА рддрдХрдиреАрдХреА рдмрд┐рдВрджреБ рд╣реИрдВ:
class GroupImputerEstimator(override val uid: String) extends Estimator[GroupImputerModel] with HasInputCol with HasOutputCol with Wrappable with DefaultParamsWritable { def this() = this(Identifiable.randomUID("GroupImputer")) val groupCol: Param[String] = new Param[String]( this, "groupCol", "Groupping column" ) def setGroupCol(v: String): this.type = super.set(groupCol, v) def getGroupCol: String = $(groupCol) override def fit(dataset: Dataset[_]): GroupImputerModel = { val meanDF = dataset .toDF .groupBy($(groupCol)) .agg(mean(col($(inputCol))).alias("groupMean")) .select(col($(groupCol)), col("groupMean")) new GroupImputerModel( uid, meanDF, getInputCol, getOutputCol, getGroupCol ) } override def transformSchema(schema: StructType): StructType = schema .add( StructField( $(outputCol), schema.filter(x => x.name == $(inputCol))(0).dataType ) ) override def copy(extra: ParamMap): Estimator[GroupImputerModel] = { val to = new GroupImputerEstimator(this.uid) copyValues(to, extra).asInstanceOf[GroupImputerEstimator] } }
рдиреЛрдЯ: рдореИрдВрдиреЗ рдбрд┐рдлреЙрд▓реНрдЯрдХреЙрдкреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рдореИрдВрдиреЗ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛, рддреЛ рдЙрд╕рдиреЗ рдХрд╕рдо рдЦрд╛рдИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдирд╣реАрдВ рд╣реИред \ <init> (java.lang.String), рд╣рд╛рд▓рд╛рдВрдХрд┐ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдерд╛ред рдЦреИрд░, рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, copy
рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред
рдЕрдм рдЖрдкрдХреЛ Model
рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдПрдХ рд╡рд░реНрдЧ рдЬреЛ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдореЙрдбрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдФрд░ transform
рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ org.apache.spark.sql.functions
рдореЗрдВ рдирд┐рд░реНрдорд┐рдд org.apache.spark.sql.functions
рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрдирд╛рдПрдВрдЧреЗ:
class GroupImputerModel( val uid: String, val meanDF: DataFrame, val inputCol: String, val outputCol: String, val groupCol: String ) extends Model[GroupImputerModel] with ConstructorWritable[GroupImputerModel] { val ttag: TypeTag[GroupImputerModel] = typeTag[GroupImputerModel] def objectsToSave: List[Any] = List(uid, meanDF, inputCol, outputCol, groupCol) override def copy(extra: ParamMap): GroupImputerModel = new GroupImputerModel(uid, meanDF, inputCol, outputCol, groupCol) override def transform(dataset: Dataset[_]): DataFrame = { dataset .toDF .join(meanDF, Seq(groupCol), "left") .withColumn( outputCol, coalesce(col(inputCol), col("groupMean")) .cast(IntegerType)) .drop("groupMean") } override def transformSchema (schema: StructType): StructType = schema .add( StructField(outputCol, schema.filter(x => x.name == inputCol)(0).dataType) ) }
рдЕрдВрддрд┐рдо рд╡рд╕реНрддреБ рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╡рд╣ рдПрдХ Reader
, рдЬрд┐рд╕реЗ рд╣рдо MMLSpark ConstructorReadable class рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:
object GroupImputerModel extends ConstructorReadable[GroupImputerModel]
рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдирд┐рд░реНрдорд╛рдг
рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ, рдореИрдВ рд╕рд╛рдорд╛рдиреНрдп SparkML рд╡рд░реНрдЧреЛрдВ рдФрд░ MMLSpark - MultiColumnAdapter рд╕реЗ рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЪреАрдЬрд╝, рджреЛрдиреЛрдВ рдХреЛ рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЬреЛ рдЖрдкрдХреЛ рдПрдХ рд╕рд╛рде рдХрдИ рд╕реНрддрдВрднреЛрдВ рдореЗрдВ SparkML рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, StringIndexer рдФрд░ OneHotEncoder рдЗрдирдкреБрдЯ рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рдПрдХ рд╕реНрддрдВрдн рд▓реЗрддреЗ рд╣реИрдВ, рдЬреЛ рдЙрдиреНрд╣реЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реИред рджрд░реНрдж рдореЗрдВ рд╡рд┐рдЬреНрдЮрд╛рдкрди):
import org.apache.spark.ml.feature.{StringIndexer, VectorAssembler} import org.apache.spark.ml.Pipeline import com.microsoft.ml.spark.{MultiColumnAdapter, LightGBMClassifier}
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдШреЛрд╖рд┐рдд рдХрд░реЗрдВрдЧреЗ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреМрди рд╕реЗ рдХреЙрд▓рдо рд╣реИрдВ:
val catCols = Array("Sex", "Embarked", "NameType") val numCols = Array("PClass", "AgeNoMissings", "SibSp", "Parch", "CabinCount", "CabinNumber")
рдЕрдм рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдПрдирдХреЛрдбрд░ рдмрдирд╛рдПрдВ:
val stringEncoder = new MultiColumnAdapter() .setBaseStage(new StringIndexer().setHandleInvalid("keep")) .setInputCols(catCols) .setOutputCols(catCols.map(x => x + "_freqEncoded"))
рдиреЛрдЯ: рд╕реНрдкрд╛рд░реНрдХрдПрдордПрд▓ рдореЗрдВ рд╕реНрдХрд┐рдХрд┐рдЯ-рд▓рд░реНрди рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╕реНрдЯреНрд░рд┐рдВрдЧ-рдЗрдВрдбреЗрдХреНрд╕рд░ рдЖрд╡реГрддреНрддрд┐-рдПрдирдХреЛрдбрд░ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдСрд░реНрдбрд░ рд░рд┐рд▓реЗрд╢рдирд╢рд┐рдк (рдпрд╛рдиреА рд╢реНрд░реЗрдгреА 0 <рд╢реНрд░реЗрдгреА 1, рдФрд░ рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ) рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЕрдХреНрд╕рд░ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдирд┐рд░реНрдгрд╛рдпрдХ рдкреЗрдбрд╝ред
рд╣рдорд╛рд░реЗ Imputer
рдХрд░реЗрдВ:
val missingImputer = new GroupImputerEstimator() .setInputCol("Age") .setOutputCol("AgeNoMissings") .setGroupCol("Sex")
рдФрд░ VectorAssembler
, рдЪреВрдВрдХрд┐ рд╕реНрдкрд╛рд░реНрдХрдПрдордПрд▓ рдХреНрд▓рд╛рд╕рд┐рдлрд╛рдпрд░ VectorType
рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЖрд░рд╛рдорджрд╛рдпрдХ рд╣реИрдВ:
val assembler = new VectorAssembler() .setInputCols(stringEncoder.getOutputCols ++ numCols) .setOutputCol("features")
рдЕрдм рд╣рдо MMLSpark - LightGBM рдХреЗ рд╕рд╛рде рдЖрдкреВрд░реНрддрд┐ рдХрд┐рдП рдЧрдП рдЧреНрд░реЗрдбрд┐рдПрдВрдЯ рдмреВрд╕реНрдЯрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдХрд┐ XGBoost рдФрд░ CatBoost рдХреЗ рд╕рд╛рде рдЗрд╕ рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХреЗ рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ "рдмрд┐рдЧ рдереНрд░реА" рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИред рдпрд╣ рдХрдИ рдмрд╛рд░ рддреЗрдЬреА рд╕реЗ, рдмреЗрд╣рддрд░ рдФрд░ GBM рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╕реНрдерд┐рд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╕реНрдкрд╛рд░реНрдХрдПрдордПрд▓ рдХреЗ рдкрд╛рд╕ рд╣реИ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЬреЗрд╡реАрдПрдо рдкреЛрд░реНрдЯ рдЕрднреА рднреА рд╕рдХреНрд░рд┐рдп рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рд╣реИ):
val catColIndices = Array(0, 1, 2) val lgbClf = new LightGBMClassifier() .setFeaturesCol("features") .setLabelCol("Survived") .setProbabilityCol("predictedProb") .setPredictionCol("predictedLabel") .setRawPredictionCol("rawPrediction") .setIsUnbalance(true) .setCategoricalSlotIndexes(catColIndices) .setObjective("binary")
рдиреЛрдЯ: рд▓рд╛рдЗрдЯ рдЬреАрдмреАрдПрдо рд╢реНрд░реЗрдгреАрдмрджреНрдз рдЪрд░ (рд▓рдЧрднрдЧ рдХреИрдЯрдмреЙрд╕реНрдЯ рдХреА рддрд░рд╣) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдордиреЗ рдЗрд╕реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдХрд┐ рд╢реНрд░реЗрдгреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рд╣рдорд╛рд░реЗ рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рдХрд╣рд╛рдВ рд╣реИрдВ, рдФрд░ рд╡рд╣ рдЦреБрдж рдкрддрд╛ рд▓рдЧрд╛рдПрдЧрд╛ рдХрд┐ рдЙрдирдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рдПрдирдХреЛрдб рдХрд░рдирд╛ рд╣реИред
рд╕реНрдкрд╛рд░реНрдХ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрдЯ рдЬреАрдмреАрдПрдо рдлреАрдЪрд░реНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА- RadHat LightGBM рдкрд░ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдиреЛрдбреНрд╕ рдкрд░, рдмрд╣реБрдд рдирд╡реАрдирддрдо рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдХреЛрдИ рднреА рд╕рдВрд╕реНрдХрд░рдг рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рджреБрд░реНрдШрдЯрдирд╛рдЧреНрд░рд╕реНрдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдЙрд╕реЗ рдЧреНрд▓рд┐рдмреИрдХ рд╕рдВрд╕реНрдХрд░рдг рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИ ред рдпрд╣ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рддрдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдорд╛рд╡реЗрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╕рдордп, рдПрдордПрдордПрд▓рд╕реНрдкрд╛рд░реНрдХ рдорд╛рд╡реЗрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╕рдордп рд▓рд╛рдЗрдЯ рдЬреАрдмреАрдПрдо рдХреЗ рдкрд╛рд░рдореНрдкрд░рд┐рдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЦреАрдВрдЪрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рд╕реЗ рд░реЗрдбрд╣реИрдЯ рдкрд░ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
- рд▓рд╛рдЗрдЯ рдЬреАрдмреАрдПрдо рдЕрдкрдиреЗ рдХрд╛рдо рдореЗрдВ рдЕрдзрд┐рдХрд╛рд░рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХреЗ рд▓рд┐рдП рдбреНрд░рд╛рдЗрд╡рд░ рдкрд░ рдПрдХ рд╕реЙрдХреЗрдЯ рдмрдирд╛рддрд╛ рд╣реИ, рдФрд░ рдпрд╣
new java.net.ServerSocket(0)
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП рдУрдПрд╕ рдХреЗ new java.net.ServerSocket(0)
рдмрдВрджрд░рдЧрд╛рд╣реЛрдВ рд╕реЗ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдкреЛрд░реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдлрд╝рд╛рдпрд░рд╡реЙрд▓ рджреНрд╡рд╛рд░рд╛ рдЦреЛрд▓реЗ рдЧрдП рдмрдВрджрд░рдЧрд╛рд╣реЛрдВ рдХреА рд╕реАрдорд╛ рд╕реЗ рдкрдВрдЪрд╛рдВрдЧ рдХреА рд╕реАрдорд╛ рднрд┐рдиреНрди рд╣реЛрддреА рд╣реИ, рддреЛ рдмрд╣реБрдд рдХреБрдЫ рдЬрд▓рд╛ рд╕рдХрддрд╛ рд╣реИ рдЖрдк рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдкреНрд░рднрд╛рд╡ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рд▓рд╛рдЗрдЯ рдЬреАрдмреАрдПрдо рдХрднреА-рдХрднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ (рдЬрдм рдореИрдВрдиреЗ рдПрдХ рдЕрдЪреНрдЫрд╛ рдмрдВрджрд░рдЧрд╛рд╣ рдЪреБрдирд╛), рдФрд░ рдХрднреА-рдХрднреА рдирд╣реАрдВред рдФрд░ рд╡рд╣рд╛рдВ ConnectionTimeOut
рддрд░рд╣ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реЛрдВрдЧреА, рдЬреЛ рд╕рдВрдХреЗрдд рднреА рдХрд░ рд╕рдХрддреА рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд┐рдХрд▓реНрдк рдЬрдм рдЬреАрд╕реА рдЕрдзрд┐рдХрд╛рд░рд┐рдпреЛрдВ рдкрд░ рд▓рдЯрдХрд╛ рд╣реЛрддрд╛ рд╣реИ рдпрд╛ рдРрд╕рд╛ рдХреБрдЫ рд╣реЛрддрд╛ рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдореЗрд░реА рдЧрд▓рддрд┐рдпреЛрдВ рдХреЛ рджреЛрд╣рд░рд╛рдПрдВ рдирд╣реАрдВред
рдЦреИрд░, рдЕрдВрдд рдореЗрдВ, рд╣рдорд╛рд░реА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ:
val pipeline = new Pipeline() .setStages( Array( missingImputer, nameTransformer, cabinsCountTransformer, numbersFromCabinTransformer, stringEncoder, assembler, lgbClf ) )
рдЯреНрд░реЗрдирд┐рдВрдЧ
рд╣рдо рдПрдХ рдЯреНрд░реЗрди рдФрд░ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рд╣рдорд╛рд░реЗ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХреЛ рддреЛрдбрд╝ рджреЗрдВрдЧреЗ рдФрд░ рд╣рдорд╛рд░реА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗред рдпрд╣рд╛рдВ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд┐рднрд╛рдЬрди рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рд╣реИ рдФрд░ рд╣рдореЗрдВ рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдЯреНрд░реЗрди рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдкрд░рд┐рд╡рд░реНрддрди рд▓рд╛рдЧреВ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рд╕рднреА рдкрд░рд┐рд╡рд░реНрддрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЯреНрд░реЗрди рдореЗрдВ "рд╕реАрдЦрд╛" рдЬрд╛рдПрдЧрд╛:
val Array(trainDF, testDF) = trainFiltered.randomSplit(Array(0.8, 0.2)) println(s"Train rows: ${trainDF.count}\nTest rows: ${testDF.count}")
рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо MMLSpark рд╕реЗ рдПрдХ рдЕрдиреНрдп рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ - ComputeModelStatistics :
import com.microsoft.ml.spark.ComputeModelStatistics import com.microsoft.ml.spark.metrics.MetricConstants val modelEvaluator = new ComputeModelStatistics() .setLabelCol("Survived") .setScoresCol("predictedProb") .setScoredLabelsCol("predictedLabel") .setEvaluationMetric(MetricConstants.ClassificationMetrics)

рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рд╣рдордиреЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдирд╣реАрдВ рдмрджрд▓реА рд╣реИрдВред
рд╣рд╛рдЗрдкрд░рдкрд░рдореЗрдЯрд░реНрд╕ рдХрд╛ рдЪрдпрди
MMLSpark рдореЗрдВ рд╣рд╛рдЗрдкрд░рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд╢рд╛рдВрдд рдЪреАрдЬ рд╣реИ TuneHyperparameters
, рдЬреЛ рдЧреНрд░рд┐рдб рдкрд░ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЦреЛрдЬ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рдЕрднреА рддрдХ Pipeline
рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдкрд╛рд░реНрдХрдПрдордПрд▓ CrossValidator
рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ:
import org.apache.spark.ml.tuning.{ParamGridBuilder, CrossValidator} import org.apache.spark.ml.evaluation.BinaryClassificationEvaluator val paramSpace = new ParamGridBuilder() .addGrid(lgbClf.maxDepth, Array(3, 5)) .addGrid(lgbClf.learningRate, Array(0.05, 0.1)) .addGrid(lgbClf.numIterations, Array(100, 300)) .build println(s"Size of ParamsGrid: ${paramSpace.size}")
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореБрдЭреЗ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛ рдХрд┐ рдЖрдк рдЙрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдкрд░рд┐рдгрд╛рдо рдХреИрд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рди рдкрд░ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЗрд╕рд▓рд┐рдП, "рд░рд╛рдХреНрд╖рд╕реА" рдбрд┐рдЬрд╛рдЗрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ:
crossValidator .getEstimatorParamMaps .zip(bestModel.avgMetrics) .foreach(x => { println( "\n" + x._1 .toSeq .foldLeft(new StringBuilder())( (a, b) => a .append(s"\n\t${b.param.name} : ${b.value}")) .toString + s"\n\tMetric: ${x._2}" ) })
рдЬреЛ рд╣рдореЗрдВ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджреЗрддрд╛ рд╣реИ:

рд╣рдореЗрдВ рд╕реАрдЦрдиреЗ рдХреА рдЧрддрд┐ рдХрдо рдХрд░рдиреЗ рдФрд░ рдкреЗрдбрд╝реЛрдВ рдХреА рдЧрд╣рд░рд╛рдИ рдмрдврд╝рд╛рдиреЗ рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓рд╛ред рдЗрд╕ рдЖрдзрд╛рд░ рдкрд░, рдЦреЛрдЬ рд╕реНрдерд╛рди рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдирд╛ рдФрд░ рдЙрд╕рд╕реЗ рднреА рдЕрдзрд┐рдХ рдЗрд╖реНрдЯрддрдо рдкрд░рд┐рдгрд╛рдо рдЖрдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдРрд╕рд╛ рдХреЛрдИ рд▓рдХреНрд╖реНрдп рдирд╣реАрдВ рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЬрдмрдХрд┐ MMLSpark рдореЗрдВ 0.17 рд╕рдВрд╕реНрдХрд░рдг рд╣реИ рдФрд░ рдЕрднреА рднреА рдЕрд▓рдЧ рдмрдЧ рд╣реИрдВред рд▓реЗрдХрд┐рди рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рджреЗрдЦреЗ рдЧрдП рд╕рднреА рд╕реНрдкрд╛рд░реНрдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЗрдВ, MMLSpark рдХреЗ рдкрд╛рд╕ рдореЗрд░реА рд░рд╛рдп рдореЗрдВ рд╕рдмрд╕реЗ рд╡реНрдпрд╛рдкрдХ рджрд╕реНрддрд╛рд╡реЗрдЬ рдФрд░ рд╕рдмрд╕реЗ рд╕рдордЭ рдореЗрдВ рдЖрдиреЗ рд╡рд╛рд▓реА рд╕реНрдерд╛рдкрдирд╛ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИред Microsoft рдиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрднреА рддрдХ рдЗрд╕рдХрд╛ рдкреНрд░рдЪрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдбреЗрдЯрд╛рдмреНрд░рд┐рдХ рдкрд░ рдПрдХ рд░рд┐рдкреЛрд░реНрдЯ рдереА , рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдбреАрдк рд▓рд░реНрдирд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдерд╛, рдФрд░ рдРрд╕реА рдирд┐рдпрдорд┐рдд рдЪреАрдЬреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдЬреЛ рдореИрдВрдиреЗ рд▓рд┐рдЦрд╛ рдерд╛ред
рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ, рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ, рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдиреЗ рдмрд╣реБрдд рдорджрдж рдХреА, рдЬрд┐рд╕рд╕реЗ рдореБрдЭреЗ рд╕реНрдкрд╛рд░реНрдХ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рдЬрдВрдЧрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдереЛрдбрд╝рд╛ рдХрдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рдирд┐рдЬреА [рдПрдордПрд▓] рддрд░реАрдХреЛрдВ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдорд┐рд▓реА, рдФрд░ рдореЗрд░реЗ рдПрдХ рд╕рд╣рдпреЛрдЧреА рдиреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рджреБрд░реНрдШрдЯрдирд╛ рд╕реЗ рд▓рдЧрднрдЧ рдкрд╛рдпрд╛ред рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕рдХреНрд░рд┐рдп рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рд╣реИ, рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓ рд╕рдВрд░рдЪрдирд╛ рдкреВрд░рд╛ рджрд▓рд┐рдпрд╛ рдХреБрдЫ рдЧрдбрд╝рдмрдбрд╝ рд╣реИред рдЦреИрд░, рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдЙрджрд╛рд╣рд░рдг рдпрд╛ рдЕрдиреНрдп рджрд╕реНрддрд╛рд╡реЗрдЬ рдирд╣реАрдВ рд╣реИрдВ (рдирдВрдЧреЗ рд╕реНрдХреЗрд▓рдбреЙрдХ рдХреЛ рдЫреЛрдбрд╝рдХрд░), рдкрд╣рд▓реЗ рдореБрдЭреЗ рд╣рд░ рд╕рдордп рд╕реНрд░реЛрдд рдореЗрдВ рдХреНрд░реЙрд▓ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рдерд╛ред
рдЗрд╕рд▓рд┐рдП, рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрд╢рд╛ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдорд┐рдиреА-рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ (рдЗрд╕рдХреА рд╕рднреА рд╕реНрдкрд╖реНрдЯрддрд╛ рдФрд░ рд╕рд░рд▓рддрд╛ рдХреЗ рдмрд╛рд╡рдЬреВрдж) рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдФрд░ рдмрд╣реБрдд рд╕рдордп рдФрд░ рдкреНрд░рдпрд╛рд╕ рдХреЛ рдмрдЪрд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛!